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

TIM*_*MEX 399 javascript jquery

什么是非jQuery相当于$(document).ready()

sos*_*dra 552

这非常适合ECMA

document.addEventListener("DOMContentLoaded", function() {
  // code...
});
Run Code Online (Sandbox Code Playgroud)

window.onload不等于JQuery的$(document).ready,因为$(document).ready等待只对DOM树,同时window.onload检查,包括对外资产和图像的所有元素.

编辑:由于Jan Derk的观察,添加了IE8和更旧的等价物.您可以在此链接上阅读MDN 上此代码的来源:

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

还有其他选择"interactive".有关详细信息,请参阅MDN链接.

  • 对于那些测试 @oriadam 评论的人来说,很可能是因为当您尝试在控制台中收听它时,**DOMContentLoaded 很久以前就被触发了**。尝试将其包含在本地测试的页面中。 (9认同)
  • 如果在调用此脚本时已加载文档怎么办?什么都不会发生:( (8认同)
  • @Deerloper Nope,刚在Chrome控制台上试过 - 没有任何反应:`document.addEventListener("DOMContentLoaded",function(){console.log(123)})`现在试试吧 (8认同)
  • 浏览器中对DOMContentLoaded **的支持:http://caniuse.com/domcontentloaded (2认同)

Dou*_*ner 78

好消息$(document).ready()是它之前发射过window.onload.加载功能等待所有内容加载,包括外部资源和图像.$(document).ready但是,当DOM树完成并可以操作时会触发.如果你想准备好DOM,没有jQuery,你可以检查这个库.有人ready从jQuery中提取了部分内容.它很好很小,你可能会发现它很有用:

已完全使用Google Code

  • 是的,但我们中的一些人来这里是为了真正的答案。 (16认同)
  • 这不回答问题,也没有显示任何非jQuery代码.它是如何得到这么多的赞成票的? (14认同)
  • 好的库@Doug,我唯一不喜欢它的是,使用*浏览器嗅探*,似乎它基于jQuery 1.2.x. 较新版本的jQuery(1.3+)不再进行浏览器嗅探,我喜欢这个想法,我可能会在github上开始一些事情: - )... (6认同)
  • 非常糟糕的答案 - 忽略OP问题。我们中的一些人出于多种原因不想使用 jQuery。 (6认同)
  • DomReady代码网络!通过github上的@CMS:https://github.com/cms/domready/network (4认同)
  • @丹尼尔W。因为它简单又实用。我们大多数人来到这里寻找一种方法来确保 DOM 准备好被 javascript 代码使用。 (3认同)

Tha*_*you 40

我放在一起的小东西

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);
Run Code Online (Sandbox Code Playgroud)

如何使用它

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

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

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

domReady(init, console);
Run Code Online (Sandbox Code Playgroud)

  • 谢谢.我喜欢它向后兼容的事实.向前迈进并不意味着只留下不那么幸运的人.无法使用现代浏览器(无论出于何种原因)是不幸的...... (2认同)

CTS*_*_AE 17

现在到了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!"));
Run Code Online (Sandbox Code Playgroud)

其他读物


更新资料

这是一些使用我编写的标准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);
  }
}
Run Code Online (Sandbox Code Playgroud)

打字稿

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);
  }
}
Run Code Online (Sandbox Code Playgroud)

承诺

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);
  }
});
Run Code Online (Sandbox Code Playgroud)


Zig*_*612 13

有一个基于标准的替换,DOMContentLoaded支持超过90%以上的浏览器,但不支持IE8(所以下面的代码使用JQuery来支持浏览器):

document.addEventListener("DOMContentLoaded", function(event) { 
  //do work
});
Run Code Online (Sandbox Code Playgroud)

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 );
}
Run Code Online (Sandbox Code Playgroud)

  • 新的 jQuery 放弃了对旧浏览器的支持,现在它们只有使用“addEventListener”的“DOMContentLoaded”和“load”事件,并且首先触发会删除两个侦听器,因此不会触发两次。 (2认同)

onl*_*mas 12

根据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');
});
Run Code Online (Sandbox Code Playgroud)

我个人也会检查是否fn是一个函数的类型.

我之后回答这个问题的原因是因为我正在寻找这个答案,但在这里找不到.我认为这是最好的解决方案.


Bri*_*ell 7

在普通的JavaScript中,没有库?这是一个错误.$只是一个标识符,除非您定义它,否则它是未定义的.

jQuery定义$了它自己的"所有对象"(也称为jQuery可以使用它而不与其他库冲突).如果您不使用jQuery(或其他定义它的库),则$不会定义.

或者你在问普通JavaScript中的等价物是什么?在这种情况下,您可能想要window.onload,这不是完全等效的,但是在vanilla JavaScript中接近相同效果的最快捷,最简单的方法.

  • 对于这个答案的许多下层人士(以及下面的其他人):当问到这个问题时,它简单地说:"javascript中的$(document).ready()是什么?不是jquery.这是什么?" 这听起来像是在询问普通香草JavaScript中没有加载jQuery的含义.在我的回答中,我试图回答这个问题,并为没有jQuery或其他库的普通的JavaScript提供最接近的简单答案,以防他的意思.请注意,所有额外的上下文都是由其他人猜测问题所在,而不是原始海报. (38认同)

NVR*_*VRM 5

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

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

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

onloadeddata = (function(){ console.log("Data loaded!") })()
Run Code Online (Sandbox Code Playgroud)

当初始HTML文档已完全加载和解析时,无需等待样式表,图像和子帧完成加载,就会触发DOMContentLoaded事件。完全不同的事件加载应仅用于检测页面已满。在DOMContentLoaded更合适的地方使用负载是一个非常普遍的错误,因此请务必谨慎。

https://developer.mozilla.org/zh-CN/docs/Web/Events/DOMContentLoaded

使用的函数是IIFE,在这种情况下非常有用,因为它在准备就绪时会触发自身:

https://zh.wikipedia.org/wiki/立即调用功能_表达式

将它放在任何脚本的末尾显然更合适。

在ES6中,我们还可以将其编写为箭头函数:

onload = (() => { console.log("ES6 page fully loaded!") })()
Run Code Online (Sandbox Code Playgroud)

最好是使用DOM元素,我们可以等待触发箭头IIFE的任何变量准备就绪。

行为将相同,但对内存的影响较小。

footer = (() => { console.log("Footer loaded!") })()
Run Code Online (Sandbox Code Playgroud)
<div id="footer">
Run Code Online (Sandbox Code Playgroud)

在许多情况下,至少在我的浏览器中,文档对象也会在就绪时触发。语法非常好,但是需要进一步测试兼容性。

document=(()=>{    /*Ready*/   })()
Run Code Online (Sandbox Code Playgroud)