我有一个使用$(document).ready的脚本,但它不使用jQuery中的任何其他内容。我想通过删除jQuery依赖项来减轻它。

如何在不使用jQuery的情况下实现我自己的$(document).ready功能?我知道,使用window.onload将不同,因为window.onlead在加载所有图像、帧等后启动。


当前回答

现在你应该使用模块。将代码放入模块的默认函数中,并将该函数导入脚本元素。

客户端.js:

export default function ()
{
  alert ("test");
}

index.html:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>test</title>
  </head>
  <body>
    <script type="module">
      import main from './client.js';
      main ();
    </script>
  </body>
</html>

其他回答

以下是测试DOM就绪的最小代码片段,它适用于所有浏览器(甚至IE 8):

r(function(){
    alert('DOM Ready!');
});
function r(f){/in/.test(document.readyState)?setTimeout('r('+f+')',9):f()}

看到这个答案。

有一种基于标准的替代品DOMContentLoaded,99%以上的浏览器都支持它,但IE8:

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 );
}

我们发现了一个快速而肮脏的跨浏览器实现,它可以用最少的实现实现大多数简单情况:

window.onReady = function onReady(fn){
    document.body ? fn() : setTimeout(function(){ onReady(fn);},50);
};

如果您不必支持非常旧的浏览器,即使在外部脚本加载了异步属性时,也可以使用以下方法:

HTMLDocument.prototype.ready = new Promise(function(resolve) {
   if(document.readyState != "loading")
      resolve();
   else
      document.addEventListener("DOMContentLoaded", function() {
         resolve();
      });
});

document.ready.then(function() {
   console.log("document.ready");
});

如果您正在加载BODY底部附近的jQuery,但在编写jQuery(<func>)或jQuery(document).ready(<func>)时遇到问题,请在Github上查看jqShim。

与其重新创建自己的文档就绪函数,它只需保留这些函数,直到jQuery可用,然后按预期继续jQuery。将jQuery移动到主体底部的目的是加快页面加载速度,您仍然可以通过在模板头部内联jqShim.min.js来实现这一点。

最后我写了这段代码,将WordPress中的所有脚本都移到了页脚,而现在只有这段填充码直接位于页眉中。