javascript:如何编写$(document).ready像没有jquery的事件

时间:2021-10-01 00:03:45

in jquery $(document).ready(function) or $(function) , how could I do the same thing without jquery, and I need browser compatiable, and allow to attach more than one function.

在jquery $(document).ready(function)或$(function)中,如果没有jquery,我怎么能做同样的事情,我需要浏览器兼容,并且允许附加多个函数。

Note: dom ready!= window onload

7 个解决方案

#1


24  

This is the way jQuery wraps the functions you're looking for - the snippet does not need jQuery, and is cross-browser compatible. I've replaced all calls to jQuery.ready() with yourcallback - which you need to define.

这就是jQuery包装你正在寻找的函数的方式 - 代码片段不需要jQuery,并且是跨浏览器兼容的。我用yourcallback替换了对jQuery.ready()的所有调用 - 你需要定义它。

What goes on in here:

这里发生了什么:

  • first, the function DOMContentLoaded is defined, which will be used when the DOMContentLoaded event fires - it ensures that the callback is only called once.
  • 首先,定义函数DOMContentLoaded,它将在DOMContentLoaded事件触发时使用 - 它确保仅调用一次回调。

  • a check if the document is already loaded - if yes, fire the callback right away
  • 检查文档是否已加载 - 如果是,立即触发回调

  • otherwise sniff for features (document.addEventListener / document.attachEvent) and bind the callbacks to it (different for IE and normal browsers, plus the onload callback)
  • 否则嗅探功能(document.addEventListener / document.attachEvent)并将回调绑定到它(IE和普通浏览器不同,加上onload回调)

Lifted from jQuery 1.4.3, functions bindReady() and DOMContentLoaded:

从jQuery 1.4.3开始,函数bindReady()和DOMContentLoaded:

/*
* Copyright 2010, John Resig
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*/
// Cleanup functions for the document ready method
// attached in the bindReady handler
if ( document.addEventListener ) {
DOMContentLoaded = function() {
    document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
    //jQuery.ready();
            yourcallback();
};

} else if ( document.attachEvent ) {
DOMContentLoaded = function() {
    // Make sure body exists, at least, in case IE gets a little overzealous 
            if ( document.readyState === "complete" ) {
        document.detachEvent( "onreadystatechange", DOMContentLoaded );
        //jQuery.ready();
                    yourcallback();
    }
    };
}

// Catch cases where $(document).ready() is called after the
// browser event has already occurred.
if ( document.readyState === "complete" ) {
    // Handle it asynchronously to allow scripts the opportunity to delay ready
//return setTimeout( jQuery.ready, 1 );
    // ^^ you may want to call *your* function here, similarly for the other calls to jQuery.ready
    setTimeout( yourcallback, 1 );
}

// Mozilla, Opera and webkit nightlies currently support this event
if ( document.addEventListener ) {
    // Use the handy event callback
document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
// A fallback to window.onload, that will always work
//window.addEventListener( "load", jQuery.ready, false );
    window.addEventListener( "load", yourcallback, 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", DOMContentLoaded);

        // A fallback to window.onload, that will always work
        window.attachEvent( "onload", yourcallback );

 }

That's 51 lines of pure JavaScript code, just to register the event reliably. As far as I know, there is no easier method. Goes to show what the wrappers like jQuery are good for: they wrap the capability sniffing and ugly compatibility issues so that you can focus on something else.

这是51行纯JavaScript代码,只是为了可靠地注册事件。据我所知,没有比较简单的方法了。去展示像jQuery这样的包装器有什么用处:它们包含功能嗅探和丑陋的兼容性问题,以便您可以专注于其他事情。

#2


9  

Smallest DOMReady code, ever.

有史以来最小的DOMReady代码。

<html>
  <head>
    <script>
      var ready = function (f) {
        (/complete|loaded|interactive/.test(document.readyState)) ?
            f() :
            setTimeout(ready, 9, f);
      };
    </script>
  </head>
  <body>
    <script>
      ready(function () {
        alert('DOM Ready!');
      });
    </script>
  </body>
</html>

#3


3  

This is all you need if you're supporting IE9+ and modern (2013) versions of Chrome, FF, Safari, etc.

如果您支持IE9 +和现代(2013)版本的Chrome,FF,Safari等,这就是您所需要的。

function ready(event) {
    // your code here
    console.log('The DOM is ready.', event);
    // clean up event binding
    window.removeEventListener('DOMContentLoaded', ready);
}

// bind to the load event
window.addEventListener('DOMContentLoaded', ready);

#4


2  

Here's a method I use that seems to work reliably

这是我使用的方法似乎可靠地工作

function ready(func) {
  var span = document.createElement('span');
  var ms = 0;
  setTimeout(function() {
    try {
      document.body.appendChild(span);

      document.body.removeChild(span);

      //Still here? Then document is ready
      func();
    } catch(e) {
      //Whoops, document is not ready yet, try again...

      setTimeout(arguments.callee, ms);
    }
  }, ms);
}

Pretty simple, it just keeps trying to append an empty <span> element to document.body. If the document is not "ready" an exception will be thrown, in which case it tries again with a new setTimeout call. Once no exception is thrown, it calls the callback function.

非常简单,它只是不断尝试将空的元素附加到document.body。如果文档没有“准备就绪”,则会抛出异常,在这种情况下,它会再次尝试使用新的setTimeout调用。一旦没有抛出异常,它就会调用回调函数。

I'd be happy to hear if there are any problems with this method. It has worked well for me, but I have not done the extensive testing that would be natural to any popular Javascript framework.

我很高兴听到这个方法有什么问题。它对我来说效果很好,但我没有做过任何流行的Javascript框架自然的广泛测试。

#5


1  

I've seen lots of different ways of trying to do this. The simplest way (suggested by yahoo initially, I think) is to just call your initializer function after the close body tag, a bit obtrusive, but it's a single line.

我已经看到了许多尝试这种方法的不同方法。最简单的方法(我认为最初由yahoo建议)是在关闭body标签之后调用你的初始化函数,有点突兀,但它只是一行。

#6


0  

Edit

The DomReady event does not exist nativly in javascript. You can implement your own by following some wonderful work done by people like Dean Edwards here and here with those in place you can perform a similar event attachment process on document instead of window.

DomReady事件在javascript中不存在。您可以通过跟随Dean Edwards等人在这里和这里完成的一些精彩工作来实现自己的工作,您可以在文档而不是窗口上执行类似的事件附件处理。


Check out user83421's answer to How do I add an additional window.onload event in Javascript

查看user83421的答案如何在Javascript中添加额外的window.onload事件

To recap here as well.

在这里回顾一下。

if (window.addEventListener) // W3C standard
{
  window.addEventListener('load', myFunction, false); // NB **not** 'onload'
} 
else if (window.attachEvent) // Microsoft
{
  window.attachEvent('onload', myFunction);
}

#7


0  

I have this after the 'close body' tag and before the 'close html' tag. and it works pretty well. The load presets function assigns width,height and position values to css div tags. useful for different screen sizes.

我在'close body'标签之后和'close html'标签之前有这个。而且效果很好。加载预设功能将宽度,高度和位置值分配给css div标签。适用于不同的屏幕尺寸。

document.onreadystatechange = function () {
if  (document.readyState == "interactive") {
loadPresets();
}

}

#1


24  

This is the way jQuery wraps the functions you're looking for - the snippet does not need jQuery, and is cross-browser compatible. I've replaced all calls to jQuery.ready() with yourcallback - which you need to define.

这就是jQuery包装你正在寻找的函数的方式 - 代码片段不需要jQuery,并且是跨浏览器兼容的。我用yourcallback替换了对jQuery.ready()的所有调用 - 你需要定义它。

What goes on in here:

这里发生了什么:

  • first, the function DOMContentLoaded is defined, which will be used when the DOMContentLoaded event fires - it ensures that the callback is only called once.
  • 首先,定义函数DOMContentLoaded,它将在DOMContentLoaded事件触发时使用 - 它确保仅调用一次回调。

  • a check if the document is already loaded - if yes, fire the callback right away
  • 检查文档是否已加载 - 如果是,立即触发回调

  • otherwise sniff for features (document.addEventListener / document.attachEvent) and bind the callbacks to it (different for IE and normal browsers, plus the onload callback)
  • 否则嗅探功能(document.addEventListener / document.attachEvent)并将回调绑定到它(IE和普通浏览器不同,加上onload回调)

Lifted from jQuery 1.4.3, functions bindReady() and DOMContentLoaded:

从jQuery 1.4.3开始,函数bindReady()和DOMContentLoaded:

/*
* Copyright 2010, John Resig
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*/
// Cleanup functions for the document ready method
// attached in the bindReady handler
if ( document.addEventListener ) {
DOMContentLoaded = function() {
    document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
    //jQuery.ready();
            yourcallback();
};

} else if ( document.attachEvent ) {
DOMContentLoaded = function() {
    // Make sure body exists, at least, in case IE gets a little overzealous 
            if ( document.readyState === "complete" ) {
        document.detachEvent( "onreadystatechange", DOMContentLoaded );
        //jQuery.ready();
                    yourcallback();
    }
    };
}

// Catch cases where $(document).ready() is called after the
// browser event has already occurred.
if ( document.readyState === "complete" ) {
    // Handle it asynchronously to allow scripts the opportunity to delay ready
//return setTimeout( jQuery.ready, 1 );
    // ^^ you may want to call *your* function here, similarly for the other calls to jQuery.ready
    setTimeout( yourcallback, 1 );
}

// Mozilla, Opera and webkit nightlies currently support this event
if ( document.addEventListener ) {
    // Use the handy event callback
document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
// A fallback to window.onload, that will always work
//window.addEventListener( "load", jQuery.ready, false );
    window.addEventListener( "load", yourcallback, 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", DOMContentLoaded);

        // A fallback to window.onload, that will always work
        window.attachEvent( "onload", yourcallback );

 }

That's 51 lines of pure JavaScript code, just to register the event reliably. As far as I know, there is no easier method. Goes to show what the wrappers like jQuery are good for: they wrap the capability sniffing and ugly compatibility issues so that you can focus on something else.

这是51行纯JavaScript代码,只是为了可靠地注册事件。据我所知,没有比较简单的方法了。去展示像jQuery这样的包装器有什么用处:它们包含功能嗅探和丑陋的兼容性问题,以便您可以专注于其他事情。

#2


9  

Smallest DOMReady code, ever.

有史以来最小的DOMReady代码。

<html>
  <head>
    <script>
      var ready = function (f) {
        (/complete|loaded|interactive/.test(document.readyState)) ?
            f() :
            setTimeout(ready, 9, f);
      };
    </script>
  </head>
  <body>
    <script>
      ready(function () {
        alert('DOM Ready!');
      });
    </script>
  </body>
</html>

#3


3  

This is all you need if you're supporting IE9+ and modern (2013) versions of Chrome, FF, Safari, etc.

如果您支持IE9 +和现代(2013)版本的Chrome,FF,Safari等,这就是您所需要的。

function ready(event) {
    // your code here
    console.log('The DOM is ready.', event);
    // clean up event binding
    window.removeEventListener('DOMContentLoaded', ready);
}

// bind to the load event
window.addEventListener('DOMContentLoaded', ready);

#4


2  

Here's a method I use that seems to work reliably

这是我使用的方法似乎可靠地工作

function ready(func) {
  var span = document.createElement('span');
  var ms = 0;
  setTimeout(function() {
    try {
      document.body.appendChild(span);

      document.body.removeChild(span);

      //Still here? Then document is ready
      func();
    } catch(e) {
      //Whoops, document is not ready yet, try again...

      setTimeout(arguments.callee, ms);
    }
  }, ms);
}

Pretty simple, it just keeps trying to append an empty <span> element to document.body. If the document is not "ready" an exception will be thrown, in which case it tries again with a new setTimeout call. Once no exception is thrown, it calls the callback function.

非常简单,它只是不断尝试将空的元素附加到document.body。如果文档没有“准备就绪”,则会抛出异常,在这种情况下,它会再次尝试使用新的setTimeout调用。一旦没有抛出异常,它就会调用回调函数。

I'd be happy to hear if there are any problems with this method. It has worked well for me, but I have not done the extensive testing that would be natural to any popular Javascript framework.

我很高兴听到这个方法有什么问题。它对我来说效果很好,但我没有做过任何流行的Javascript框架自然的广泛测试。

#5


1  

I've seen lots of different ways of trying to do this. The simplest way (suggested by yahoo initially, I think) is to just call your initializer function after the close body tag, a bit obtrusive, but it's a single line.

我已经看到了许多尝试这种方法的不同方法。最简单的方法(我认为最初由yahoo建议)是在关闭body标签之后调用你的初始化函数,有点突兀,但它只是一行。

#6


0  

Edit

The DomReady event does not exist nativly in javascript. You can implement your own by following some wonderful work done by people like Dean Edwards here and here with those in place you can perform a similar event attachment process on document instead of window.

DomReady事件在javascript中不存在。您可以通过跟随Dean Edwards等人在这里和这里完成的一些精彩工作来实现自己的工作,您可以在文档而不是窗口上执行类似的事件附件处理。


Check out user83421's answer to How do I add an additional window.onload event in Javascript

查看user83421的答案如何在Javascript中添加额外的window.onload事件

To recap here as well.

在这里回顾一下。

if (window.addEventListener) // W3C standard
{
  window.addEventListener('load', myFunction, false); // NB **not** 'onload'
} 
else if (window.attachEvent) // Microsoft
{
  window.attachEvent('onload', myFunction);
}

#7


0  

I have this after the 'close body' tag and before the 'close html' tag. and it works pretty well. The load presets function assigns width,height and position values to css div tags. useful for different screen sizes.

我在'close body'标签之后和'close html'标签之前有这个。而且效果很好。加载预设功能将宽度,高度和位置值分配给css div标签。适用于不同的屏幕尺寸。

document.onreadystatechange = function () {
if  (document.readyState == "interactive") {
loadPresets();
}

}