Cet article fournit une analyse approfondie du fonctionnement de la fonction ready de jQuery. Partagez-le avec tout le monde pour votre référence, les détails sont les suivants :
jQuery est une excellente bibliothèque de scripts, la première version a été publiée par John Resig au BarCamp NYC en janvier 2006. Vous pouvez télécharger la dernière version sur http://jquery.com/ Depuis la publication de cet article, elle a été mise à jour vers la version 2.1.4 de jQuery. Ici, nous prenons jQuery1.8.3 comme exemple.
Il existe de nombreuses façons d'apprendre jQuery. Aujourd'hui, nous commençons par la fonction ready de jQuery. Le code de cet exemple provient de la bibliothèque de scripts jQuery.
Si vous avez utilisé jQuery, vous devez avoir utilisé la fonction ready, qui sert à enregistrer les fonctions pouvant être exécutées lorsque la page est prête.
La question est : quand notre page sera-t-elle prête ?
1. événement de chargement
La méthode de traitement la plus basique est l'événement onload de la page. Lorsque nous traitons cet événement, il existe de nombreuses façons, c'est-à-dire que nous pouvons l'écrire directement dans la balise de début de l'élément body via HTML, ou nous pouvons l'utiliser. méthode d'enregistrement des événements à utiliser, qui peut être divisée en méthode DOM0 et méthode DOM2. En tenant compte de la compatibilité du navigateur, écrivez-le en mode DOM2, comme indiqué ci-dessous.
if (document.addEventListener) { // A fallback to window.onload, that will always work window.addEventListener("load", jQuery.ready, false); // If IE event model is used } else { // A fallback to window.onload, that will always work window.attachEvent("onload", jQuery.ready); }
2. Événement DOMContentLoaded
Cependant, l'événement onload ne sera pas déclenché tant que tous les éléments de la page ne seront pas chargés, y compris les images sur la page, etc. S'il y a un grand nombre d'images sur la page Web, l'effet peut être imaginé. L'utilisateur peut avoir commencé à utiliser la page avant de voir les images. À ce stade, notre page n'a pas été initialisée et l'événement n'a pas été enregistré. . N'est-ce pas ? C'est trop tard !
En plus de l'événement onload bien connu, qui est similaire à l'événement onload dans le DOM, nous avons également l'événement DOMContentLoaded à prendre en compte. Les navigateurs standards prennent en charge cet événement. Cet événement sera déclenché lorsque tout le DOM sera analysé. .
De cette manière, pour les navigateurs basés sur des standards, nous pouvons également enregistrer la gestion de cet événement. De cette façon, nous pouvons détecter l’événement de fin de chargement plus tôt.
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); }
3. événement onreadystatechange
Que faire avec les navigateurs non standards ?
Si le navigateur dispose d'un événement document.onreadystatechange, lorsque l'événement est déclenché, si document.readyState=complete, on peut considérer que l'arborescence DOM a été chargée.
Cependant, cet événement n'est pas très fiable. Par exemple, lorsqu'il y a des images dans la page, il peut ne se déclencher qu'après l'événement onload. Autrement dit, il ne peut être exécuté correctement que lorsque la page ne contient aucun binaire. ressources ou très peu ou est mis en cache comme alternative.
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); // If IE event model is used } else { // 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", jQuery.ready); }
Que fait la fonction DOMContentLoaded ? Enfin, la fonction jQuery.ready doit être appelée.
DOMContentLoaded = function() { if ( document.addEventListener ) { document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); jQuery.ready(); } else if ( document.readyState === "complete" ) { // we're here because readyState === "complete" in oldIE // which is good enough for us to call the dom ready! document.detachEvent( "onreadystatechange", DOMContentLoaded ); jQuery.ready(); } }
4. Méthode de détection doScroll
MSDN a un dicton discret sur une méthode JScript. Lorsque la page DOM n'est pas chargée, une exception sera générée lorsque la méthode doScroll est appelée. Ensuite on l'utilise à l'envers S'il n'y a pas d'exception, alors la page DOM a été chargée !
Diego Perini a rapporté en 2007 un moyen de détecter si IE est chargé, en utilisant l'appel à la méthode doScroll. Des instructions détaillées peuvent être trouvées ici.
Le principe est que lorsque IE est dans un non-iframe, il ne peut juger en permanence si le DOM est chargé qu'en fonction de sa capacité à exécuter doScroll. Dans cet exemple, essayez d'exécuter doScroll toutes les 50 millisecondes. Notez que l'appel de doScroll provoquera une exception lorsque la page n'est pas chargée, donc try -catch est utilisé pour intercepter l'exception.
(function doScrollCheck() { if (!jQuery.isReady) { try { // Use the trick by Diego Perini // http://javascript.nwbox.com/IEContentLoaded/ top.doScroll("left"); } catch (e) { return setTimeout(doScrollCheck, 50); } // and execute any waiting functions jQuery.ready(); } })();
5. document.readyState 状态
如果我们注册 ready 函数的时间点太晚了,页面已经加载完成之后,我们才注册自己的 ready 函数,那就用不着上面的层层检查了,直接看看当前页面的 readyState 就可以了,如果已经是 complete ,那就可以直接执行我们准备注册的 ready 函数了。不过 ChrisS 报告了一个很特别的错误情况,我们需要延迟一下执行。
setTimeout 经常被用来做网页上的定时器,允许为它指定一个毫秒数作为间隔执行的时间。当被启动的程序需要在非常短的时间内运行,我们就会给她指定一个很小的时间数,或者需要马上执行的话,我们甚至把这个毫秒数设置为0,但事实上,setTimeout有一个最小执行时间,当指定的时间小于该时间时,浏览器会用最小允许的时间作为setTimeout的时间间隔,也就是说即使我们把setTimeout的毫秒数设置为0,被调用的程序也没有马上启动。
这个最小的时间间隔是多少呢?这和浏览器及操作系统有关。在John Resig的新书《Javascript忍者的秘密》一书中提到
Browsers all have a 10ms minimum delay on OSX and a(approximately) 15ms delay on Windows.(在苹果机上的最小时间间隔是10毫秒,在Windows系统上的最小时间间隔大约是15毫秒),另外,MDC中关于setTimeout的介绍中也提到,Firefox中定义的最小时间间隔(DOM_MIN_TIMEOUT_VALUE)是10毫秒,HTML5定义的最小时间间隔是4毫秒。既然规范都是这样写的,那看来使用setTimeout是没办法再把这个最小时间间隔缩短了。
这样,通过设置为 1, 我们可以让程序在浏览器支持的最小时间间隔之后执行了。
// Catch cases where $(document).ready() is called after the browser event has already occurred. // we once tried to use readyState "interactive" here, but it caused issues like the one // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 if (document.readyState === "complete") { // 延迟 1 毫秒之后,执行 ready 函数 setTimeout(jQuery.ready, 1); }
6. 完整的代码
在 jQuery 中完整的代码如下所示。位于 jQuery 1.8.3 源代码的 #842 行。
jQuery.ready.promise = function( obj ) { if ( !readyList ) { readyList = jQuery.Deferred(); // Catch cases where $(document).ready() is called after the browser event has already occurred. // we once tried to use readyState "interactive" here, but it caused issues like the one // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 if ( document.readyState === "complete" ) { // Handle it asynchronously to allow scripts the opportunity to delay ready setTimeout( jQuery.ready, 1 ); // Standards-based browsers support DOMContentLoaded } else 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 ); // If IE event model is used } else { // 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", jQuery.ready ); // If IE and not a frame // continually check to see if the document is ready var top = false; try { top = window.frameElement == null && document.documentElement; } catch(e) {} if ( top && top.doScroll ) { (function doScrollCheck() { if ( !jQuery.isReady ) { try { // Use the trick by Diego Perini // http://javascript.nwbox.com/IEContentLoaded/ top.doScroll("left"); } catch(e) { return setTimeout( doScrollCheck, 50 ); } // and execute any waiting functions jQuery.ready(); } })(); } } } return readyList.promise( obj ); };
那么,又是谁来调用呢?当然是需要的时候,在我们调用 ready 函数的时候,才需要注册这些判断页面是否完全加载的处理,这段代码在 1.8.3 中位于代码的 #244 行,如下所示:
ready: function( fn ) { // Add the callback jQuery.ready.promise().done( fn ); return this; }
在页面上引用 jQuery 脚本库之后,执行了 jQuery 的初始化函数,初始化函数中创建了 ready 函数。我们在通过 ready 函数注册事件处理之前,jQuery 完成了页面检测代码的注册。这样。当页面完全加载之后,我们注册的函数就被调用了。
补充:jquery ready 简写模式
Jquery ready 函数:
$(document).ready(function(){ alert(' i am ready'); } );
可简写为:
$(function(){ alert("i am in"); } );
希望本文所述对大家jQuery程序设计有所帮助。