$(document).ready equivalent without jQuery

2018-12-30 23:56发布

I have a script that uses $(document).ready, but it doesn't use anything else from jQuery. I'd like to lighten it up by removing the jQuery dependency.

How can I implement my own $(document).ready functionality without using jQuery? I know that using window.onload will not be the same, as window.onload fires after all images, frames, etc. have been loaded.

30条回答
旧人旧事旧时光
2楼-- · 2018-12-30 23:59

How about this solution?

// other onload attached earlier
window.onload=function() {
   alert('test');
};

tmpPreviousFunction=window.onload ? window.onload : null;

// our onload function
window.onload=function() {
   alert('another message');

   // execute previous one
   if (tmpPreviousFunction) tmpPreviousFunction();
};
查看更多
ら面具成の殇う
3楼-- · 2018-12-31 00:00

Here is the smallest code snippet to test DOM ready which works across all browsers (even IE 8):

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

See this answer.

查看更多
浮光初槿花落
4楼-- · 2018-12-31 00:00

I simply use:

setTimeout(function(){
    //reference/manipulate DOM here
});

And unlike document.addEventListener("DOMContentLoaded" //etc as in the very top answer, it works as far back as IE9 -- http://caniuse.com/#search=DOMContentLoaded only indicates as recently as IE11.

For instance, go to https://netrenderer.com/index.php, choose Internet Explorer 9 from the dropdown, enter https://dexygen.github.io/blog/oct-2017/jekyll/jekyll-categories/liquid-templates/2017/10/22/how-jekyll-builds-site-categories.html and click "Render", and you will see something akin to the screenshot at the bottom of this post.

See the following Javascript code I am using in the header to manipulate the style of the Jekyll "hacker" theme to my liking -- in particular you can reference the if (location.pathname !== rootPath) block to see how I am inserting the Home and Blog Home links, which are being displayed by IE9 per the NetRenderer site.

Interestingly I stumbled upon this setTimeout solution in 2009: Is checking for the readiness of the DOM overkill?, which probably could have been worded slightly better, as I meant by using various frameworks' more complicated approaches.

setTimeout(function() {//delay execution until after dom is parsed
    var containerEls = document.getElementsByClassName('container');
    var headingEl = containerEls[0].getElementsByTagName('h1')[0];
    var headerEl = document.getElementsByTagName('header')[0];
    var downloadsSectionEl = document.getElementById('downloads');
    var rootPath = "/";
    var blogRootPath = "/blog/";

    containerEls[0].style.maxWidth = '800px';
    containerEls[1].style.maxWidth = '800px';
    headingEl.style.margin = '0';
    headerEl.style.marginBottom = '7px';
    downloadsSectionEl.style.margin = '0';

    if (location.pathname !== rootPath) {
        downloadsSectionEl.appendChild(generateNavLink('Home', rootPath));
        if (location.pathname !== blogRootPath) {
            downloadsSectionEl.appendChild(document.createTextNode(' | '));
            downloadsSectionEl.appendChild(generateNavLink('Blog Home', blogRootPath));
        }
    }

    function generateNavLink(linkText, hrefPath) {
        var navLink = document.createElement('a');
        var linkTextNode = document.createTextNode(linkText);
        navLink.setAttribute('href', hrefPath);
        navLink.appendChild(linkTextNode);
        return navLink;
    }
});

dexygen.github.io on IE9

查看更多
看风景的人
5楼-- · 2018-12-31 00:00

If you don't have to support very old browsers, here is a way to do it even when your external script is loaded with async attribute:

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");
});
查看更多
ら面具成の殇う
6楼-- · 2018-12-31 00:02

Place your <script>/*JavaScript code*/</script> right before the closing </body> tag.

Admittedly, this might not suit everyone's purposes since it requires changing the HTML file rather than just doing something in the JavaScript file a la document.ready, but still...

查看更多
人气声优
7楼-- · 2018-12-31 00:02

The setTimeout/setInterval solutions presented here will only work in specific circumstances.

The problem shows up especially in older Internet Explorer versions up to 8.

The variables affecting the success of these setTimeout/setInterval solutions are:

1) dynamic or static HTML
2) cached or non cached requests
3) size of the complete HTML document
4) chunked or non chunked transfer encoding

the original (native Javascript) code solving this specific issue is here:

https://github.com/dperini/ContentLoaded
http://javascript.nwbox.com/ContentLoaded (test)

this is the code from which the jQuery team have built their implementation.

查看更多
登录 后发表回答