什么是'$(document).ready()'的非jQuery等价物?

ruyhziif  于 2023-08-04  发布在  jQuery
关注(0)|答案(9)|浏览(114)

$(document).ready()的非jQuery等效项是什么?

35g0bw71

35g0bw711#

这是完美的,从ECMA。这段代码就是你所需要的,但是如果你想挖掘更多的东西并探索其他选项,请查看这个详细的解释。

document.addEventListener("DOMContentLoaded", function() {
  // code...
});

字符串
window.onload不等于jQuery $(document).ready,因为$(document).ready只等待DOM树,而window.onload检查所有元素,包括外部资源和图像。

编辑:根据Jan Derk的观察,增加了IE8及更老版本。您可以在MDN上阅读source of this code

// alternative to DOMContentLoaded
document.onreadystatechange = function () {
    if (document.readyState == "interactive") {
        // Initialize your application or run some code.
    }
}


除了"interactive"之外还有其他选项。详情请参见the MDN docs

sqougxex

sqougxex2#

现在是2018年,这里有一个快速而简单的方法。
这将添加一个事件侦听器,但如果它已经被触发,我们将检查dom是否处于就绪状态或是否已完成。它可以在子资源(图像、样式表、框架等)加载完成之前或之后触发。

function domReady(fn) {
  // If we're early to the party
  document.addEventListener("DOMContentLoaded", fn);
  // If late; I mean on time.
  if (document.readyState === "interactive" || document.readyState === "complete" ) {
    fn();
  }
}

domReady(() => console.log("DOM is ready, come and get it!"));

字符串

附加阅读

更新

这里有一些快速实用工具帮助程序,使用我编写的标准ES6 Import & Export,其中也包括TypeScript。也许我可以让这些成为一个快速库,可以作为依赖项安装到项目中。

JavaScript

export const domReady = (callBack) => {
  if (document.readyState === "loading") {
    document.addEventListener('DOMContentLoaded', callBack);
  }
  else {
    callBack();
  }
}

export const windowReady = (callBack) => {
  if (document.readyState === 'complete') {
    callBack();
  }
  else {
    window.addEventListener('load', callBack);
  }
}

TypeScript

export const domReady = (callBack: () => void) => {
  if (document.readyState === "loading") {
    document.addEventListener('DOMContentLoaded', callBack);
  }
  else {
    callBack();
  }
}

export const windowReady = (callBack: () => void) => {
  if (document.readyState === 'complete') {
    callBack();
  }
  else {
    window.addEventListener('load', callBack);
  }
}

承诺

export const domReady = new Promise(resolve => {
  if (document.readyState === "loading") {
    document.addEventListener('DOMContentLoaded', resolve);
  }
  else {
    resolve();
  }
});

export const windowReady = new Promise(resolve => {
  if (document.readyState === 'complete') {
    resolve();
  }
  else {
    window.addEventListener('load', resolve);
  }
});

c8ib6hqw

c8ib6hqw3#

一件我拼凑起来的小东西

domready.js

(function(exports, d) {
  function domReady(fn, context) {

    function onReady(event) {
      d.removeEventListener("DOMContentLoaded", onReady);
      fn.call(context || exports, event);
    }

    function onReadyIe(event) {
      if (d.readyState === "complete") {
        d.detachEvent("onreadystatechange", onReadyIe);
        fn.call(context || exports, event);
      }
    }

    d.addEventListener && d.addEventListener("DOMContentLoaded", onReady) ||
    d.attachEvent      && d.attachEvent("onreadystatechange", onReadyIe);
  }

  exports.domReady = domReady;
})(window, document);

字符串
如何使用

<script src="domready.js"></script>
<script>
  domReady(function(event) {
    alert("dom is ready!");
  });
</script>


还可以通过传递第二个参数来更改回调运行的上下文

function init(event) {
  alert("check the console");
  this.log(event);
}

domReady(init, console);

pu82cl6c

pu82cl6c4#

有一个基于标准的替换
DOMContentLoaded被超过90%的浏览器支持,但不支持IE8(因此下面的代码由JQuery用于浏览器支持)

document.addEventListener("DOMContentLoaded", function(event) { 
  //do work
});

字符串

jQuery的原生函数比window.onload复杂得多,如下所示。

function bindReady(){
    if ( readyBound ) return;
    readyBound = true;

    // Mozilla, Opera and webkit nightlies currently support this event
    if ( document.addEventListener ) {
        // Use the handy event callback
        document.addEventListener( "DOMContentLoaded", function(){
            document.removeEventListener( "DOMContentLoaded", arguments.callee, false );
            jQuery.ready();
        }, false );

    // If IE event model is used
    } else if ( document.attachEvent ) {
        // ensure firing before onload,
        // maybe late but safe also for iframes
        document.attachEvent("onreadystatechange", function(){
            if ( document.readyState === "complete" ) {
                document.detachEvent( "onreadystatechange", arguments.callee );
                jQuery.ready();
            }
        });

        // If IE and not an iframe
        // continually check to see if the document is ready
        if ( document.documentElement.doScroll && window == window.top ) (function(){
            if ( jQuery.isReady ) return;

            try {
                // If IE is used, use the trick by Diego Perini
                // http://javascript.nwbox.com/IEContentLoaded/
                document.documentElement.doScroll("left");
            } catch( error ) {
                setTimeout( arguments.callee, 0 );
                return;
            }

            // and execute any waiting functions
            jQuery.ready();
        })();
    }

    // A fallback to window.onload, that will always work
    jQuery.event.add( window, "load", jQuery.ready );
}

ulydmbyx

ulydmbyx5#

根据http://youmightnotneedjquery.com/#ready,一个仍然可以与IE8一起工作的不错的替代品是

function ready(fn) {
  if (document.readyState != 'loading') {
    fn();
  } else if (document.addEventListener) {
    document.addEventListener('DOMContentLoaded', fn);
  } else {
    document.attachEvent('onreadystatechange', function() {
      if (document.readyState != 'loading')
        fn();
    });
  }
}

// test
window.ready(function() {
    alert('it works');
});

字符串

改进:我个人也会检查fn的类型是否是一个函数。正如@elliottregan建议的那样,在使用后删除事件侦听器。

function ready(fn) {
  if (typeof fn !== 'function') {
    throw new Error('Argument passed to ready should be a function');
  }

  if (document.readyState != 'loading') {
    fn();
  } else if (document.addEventListener) {
    document.addEventListener('DOMContentLoaded', fn, {
      once: true // A boolean value indicating that the listener should be invoked at most once after being added. If true, the listener would be automatically removed when invoked.
    });
  } else {
    document.attachEvent('onreadystatechange', function() {
      if (document.readyState != 'loading')
        fn();
    });
  }
}

// tests
try {
  window.ready(5);
} catch (ex) {
  console.log(ex.message);
}

window.ready(function() {
  alert('it works');
});


我之所以回答这个问题很晚,是因为我一直在寻找这个答案,但在这里找不到。我认为这是最好的解决办法。

9nvpjoqh

9nvpjoqh6#

  • 这并没有回答问题,也没有显示任何非jQuery代码。请看下面@ sospedra的回答。*

$(document).ready()的好处是它在window.onload之前触发。load函数会一直等待,直到加载完所有内容,包括外部资源和图像。但是,$(document).ready在DOM树完成并且可以操作时触发。如果你想在没有jQuery的情况下实现DOM,你可以签入这个库。有人从jQuery中提取了ready部分。它很好,很小,你可能会发现它很有用:
domready at Google Code

y3bcpkx1

y3bcpkx17#

在最近的浏览器中,最简单的方法是使用适当的GlobalEventHandlersonDOMContentLoadedonloadonloadeddata(...)

onDOMContentLoaded = (function(){ console.log("DOM ready!") })()

onload = (function(){ console.log("Page fully loaded!") })()

onloadeddata = (function(){ console.log("Data loaded!") })()

字符串

  • DOMContentLoaded事件在初始HTML文档已完全加载和解析时触发,无需等待样式表、图像和子帧完成加载。一个非常不同的事件加载应该只用于检测完全加载的页面。在使用load的时候使用DOMContentLoaded会更合适,这是一个非常普遍的错误,所以要小心。*

https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded
使用的函数是一个IIFE,在这种情况下非常有用,因为它在准备好时会触发自己:
https://en.wikipedia.org/wiki/Immediately-invoked_function_expression
将其放在任何脚本的末尾显然更合适。
在ES6中,我们也可以把它写成箭头函数:

onload = (() => { console.log("ES6 page fully loaded") })()


最好的方法是使用DOM元素,我们可以等待任何变量准备就绪,触发带箭头的IIFE。
行为将是相同的,但对内存的影响较小。

footer = (() => { console.log("Footer loaded!") })()
<div id="footer">

的字符串

ecfdbz9o

ecfdbz9o8#

在普通的JavaScript中,没有库?这是一个错误。$是一个简单的标识符,除非您定义它,否则它是未定义的。
jQuery将$定义为它自己的“一切对象”(也称为jQuery,因此您可以使用它而不会与其他库发生冲突)。如果您没有使用jQuery(或其他定义它的库),则不会定义$
或者你在问纯JavaScript中的等价物是什么?在这种情况下,您可能需要window.onload,它并不完全等效,但它是在vanilla JavaScript中接近相同效果的最快、最简单的方法。

h9vpoimq

h9vpoimq9#

body onLoad也可以是一个替代方案:

<html>
<head><title>Body onLoad Exmaple</title>

<script type="text/javascript">
    function window_onload() {
        //do something
    }
</script>

</head>
<body onLoad="window_onload()">

</body>
</html>

字符串

相关问题