non-jQuery .ready() alternative that executes BEFORE jQuery's .ready(), unlike DOMContentLoaded

浪尽此生 提交于 2019-12-13 16:41:48

问题


I'm making a non-jQuery-dependent plugin which, to play nicely with various existing popular jQuery features and plugins, must execute a function after the end of the DOM has been reached, but not after the execution of anything later queued using jQuery .ready().

The standard non-jQuery .ready() alternative is document.addEventListener("DOMContentLoaded",function(){});.

If a page has functions deferred using both jQuery .ready() and DOMContentLoaded:

  • all the jQuery .ready()s execute in the order they were defined
  • ...then all the DOMContentLoadeds execute, in the order they were defined:

...and both occur between the interactive and complete document readyStates:

 document.addEventListener("readystatechange", function () { alert(document.readyState); });

document.addEventListener("DOMContentLoaded", function(event) { alert(1); });
                          
$(document).ready(function(){ alert(2); });

document.addEventListener("DOMContentLoaded", function(event) { alert(3); });

$(document).ready(function(){  alert(4); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

What can I use which is like document.addEventListener("DOMContentLoaded") but is not pre-empted by any and all jQuery .ready()s like this?

To be clear about the exact timing, in my particular case, I can guarantee that this time-crucial code is queued before any .ready()s are queued, so answers which append to the same queue as .ready() will also solve my problem, not just answers which pre-empt all .ready()s. But pre-empting all .ready()s is probably preferable, since it would be applicable for a wider range of cases.


(bonus points for any clear simple explanation as to what it is about jQuery's .ready() that causes it to execute before all document.addEventListener("DOMContentLoaded") regardless of when they were defined, I can't figure it out)


回答1:


It actually has nothing to do with the .ready() call itself, it has to do with the fact that jQuery is loaded before your code example.

jQuery adds an event listener for DOMContentLoaded/load when it is loaded, so by the time your code example runs jQuery already has a listener added. So it will get fired before the listeners in your example.

The browser goes through these steps

  1. Browser loads jquery.js
  2. jQuery initializes and adds listener on DOMContentLoaded/load
  3. Your code runs that adds listener on DOMContentLoaded and adds .ready() callbacks
  4. DOMContentLoaded is triggered
  5. jQuery's listener is in the queue before the others so it gets fired first
  6. jQuery executes each .ready() callback in succession
  7. All other DOMContentLoaded listeners in the queue get fired next

Now you can have yours called first by putting your addEventListener code before your inclusion of jQuery

<script>
    document.addEventListener("DOMContentLoaded", function(event) { alert(1); });
</script>
<script src="jquery.js"></script>
<script>
    document.addEventListener("DOMContentLoaded", function(event) { alert(3); });
    $(document).ready(function(){ alert(2); });
    $(document).ready(function(){  alert(4); });
</script>

Demo

<script>
    document.addEventListener("DOMContentLoaded", function(event) { alert(1); });
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
    document.addEventListener("DOMContentLoaded", function(event) { alert(3); });
    $(document).ready(function(){ alert(2); });
    $(document).ready(function(){  alert(4); });
</script>

If you do not have control over the placement of your code, you might be out of luck. You could try using a interval timer that is executed quickly (ie every millisecond) and check if dom is ready and when it is execute your code. But there is no guarantee it will get executed first.




回答2:


place your jqueries at the end of your document file.. it will help you resolve the conflicts sometimes..:D




回答3:


If interpret Question correctly, you can use $.holdReady()

$.holdReady(true);

// do stuff

document.addEventListener("DOMContentLoaded"
, function(event) { alert(1); });

document.addEventListener("DOMContentLoaded"
, function(event) { alert(2); });

$.holdReady(false);

$(document).ready(function() {//do stuff when `$.holdReady(false)` is called});


来源:https://stackoverflow.com/questions/30534726/non-jquery-ready-alternative-that-executes-before-jquerys-ready-unlike-d

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!