javascript - पहल - मेकअप के प्रकार




JQuery के $.ready() के शुद्ध शुद्ध जावास्क्रिप्ट समतुल्य()-पृष्ठ/डोम इसके लिए तैयार होने पर फ़ंक्शन को कैसे कॉल करें (7)

इस प्रश्न का उत्तर यहां दिया गया है:

ठीक है, यह सिर्फ एक मूर्ख सवाल हो सकता है, हालांकि मुझे यकीन है कि कई अन्य लोग समय-समय पर एक ही प्रश्न पूछ रहे हैं। मैं, मैं बस इसके बारे में 100% सुनिश्चित करना चाहता हूं। JQuery के साथ हम सब अद्भुत जानते हैं

$('document').ready(function(){});

हालांकि, मान लीजिए कि मैं मानक जावास्क्रिप्ट में लिखे गए एक फ़ंक्शन को चलाने के लिए कोई लाइब्रेरी नहीं चलाऊंगा, और जैसे ही पेज इसे संभालने के लिए तैयार है, मैं एक फ़ंक्शन लॉन्च करना चाहता हूं। इस तक पहुंचने का सही तरीका क्या है?

मुझे पता है मैं कर सकता हूँ:

window.onload="myFunction()";

... या मैं body टैग का उपयोग कर सकता हूं:

<body onload="myFunction()">

... या मैं सबकुछ के बाद पेज के निचले हिस्से में भी कोशिश कर सकता हूं, लेकिन अंतिम body या html टैग जैसे:

<script type="text/javascript">
   myFunction();
</script>

एक क्रॉस-ब्राउजर (पुराना / नया) - एक या अधिक फ़ंक्शंस को jQuery की $.ready() जैसी तरीके से जारी करने की समग्र विधि क्या है?


तैयार

function ready(fn){var d=document;(d.readyState=='loading')?d.addEventListener('DOMContentLoaded',fn):fn();}

जैसे प्रयोग करें

ready(function(){
    //some code
});

स्वयं invoking कोड के लिए

(function(fn){var d=document;(d.readyState=='loading')?d.addEventListener('DOMContentLoaded',fn):fn();})(function(){

    //Some Code here
    //DOM is avaliable
    //var h1s = document.querySelector("h1");

});

समर्थन: आईई 9 +


आईई 9 में परीक्षण किया गया, और नवीनतम फ़ायरफ़ॉक्स और क्रोम और आईई 8 में भी समर्थित है।

document.onreadystatechange = function () {
  var state = document.readyState;
  if (state == 'interactive') {
      init();
  } else if (state == 'complete') {
      initOnCompleteLoad();
  }
}​;

उदाहरण: http://jsfiddle.net/electricvisions/Jacck/

अद्यतन - पुन: प्रयोज्य संस्करण

मैंने अभी निम्नलिखित विकसित किया है। यह पीछे की संगतता के बिना jQuery या डोम के लिए तैयार एक अपेक्षाकृत सरल है। इसे शायद और परिशोधन की जरूरत है। क्रोम, फ़ायरफ़ॉक्स और आईई (10/11) के नवीनतम संस्करणों में परीक्षण किया गया है और पुराने ब्राउज़र में काम करना चाहिए जैसा कि टिप्पणी की गई है। अगर मुझे कोई समस्या मिलती है तो मैं अपडेट करूंगा।

window.readyHandlers = [];
window.ready = function ready(handler) {
  window.readyHandlers.push(handler);
  handleState();
};

window.handleState = function handleState () {
  if (['interactive', 'complete'].indexOf(document.readyState) > -1) {
    while(window.readyHandlers.length > 0) {
      (window.readyHandlers.shift())();
    }
  }
};

document.onreadystatechange = window.handleState;

उपयोग:

ready(function () {
  // your code here
});

यह जेएस की एसिंक लोडिंग को संभालने के लिए लिखा गया है, लेकिन जब तक आप खनन नहीं कर रहे हैं तब तक आप इस स्क्रिप्ट को पहले सिंक करना सिंक करना चाहेंगे। मैंने इसे विकास में उपयोगी पाया है।

आधुनिक ब्राउज़र भी स्क्रिप्ट की एसिंक लोडिंग का समर्थन करते हैं जो अनुभव को आगे बढ़ाता है। एसिंक के लिए समर्थन का मतलब है कि पेज को प्रतिपादित करते समय कई स्क्रिप्ट एक साथ डाउनलोड की जा सकती हैं। बस अतुल्यकालिक रूप से लोड की गई अन्य स्क्रिप्ट्स के आधार पर या एक मिनीफायर या निर्भरता को संभालने के लिए ब्राउज़र जैसे कुछ का उपयोग करते समय देखें।


एक ढांचे की अनुपस्थिति में करने के लिए सबसे सरल बात यह है कि आपके लिए सभी क्रॉस-ब्राउज़र संगतता आपके शरीर के अंत में केवल आपके कोड पर कॉल करना है। यह एक onload हैंडलर से निष्पादित करने के लिए तेज़ है क्योंकि यह केवल डीओएम तैयार होने के लिए इंतजार कर रहा है, सभी छवियों को लोड करने के लिए नहीं। और, यह हर ब्राउज़र में काम करता है।

<html>
<head>
</head>
<body>
Your HTML here

<script>
// self executing function here
(function() {
   // your page initialization code here
   // the DOM will be available here

})();
</script>
</body>
</html>

यदि आप वास्तव में ऐसा नहीं करना चाहते हैं और आपको क्रॉस ब्राउज़र संगतता की आवश्यकता है और आप window.onload लिए इंतजार नहीं करना चाहते हैं। तो window.onload , तो आपको शायद यह देखना चाहिए कि jQuery जैसे ढांचे को यह $(document).ready() लागू करता है $(document).ready() विधि। यह ब्राउज़र की क्षमताओं के आधार पर काफी शामिल है।

आपको थोड़ा सा विचार देने के लिए jQuery क्या करता है (जहां स्क्रिप्ट टैग रखा जाता है, वहां काम करेगा)।

यदि समर्थित है, तो यह मानक की कोशिश करता है:

document.addEventListener('DOMContentLoaded', fn, false);

फॉलबैक के साथ:

window.addEventListener('load', fn, false )

या आईई के पुराने संस्करणों के लिए, यह उपयोग करता है:

document.attachEvent("onreadystatechange", fn);

फॉलबैक के साथ:

window.attachEvent("onload", fn);

और, आईई कोड पथ में कुछ कार्य-आसपास हैं जो मैं काफी अनुवर्ती नहीं हूं, लेकिन ऐसा लगता है कि इसमें फ्रेम के साथ कुछ करना है।

यहां jQuery के लिए एक पूर्ण विकल्प है .ready() सादा जावास्क्रिप्ट में लिखा गया है:

(function(funcName, baseObj) {
    // The public function name defaults to window.docReady
    // but you can pass in your own object and own function name and those will be used
    // if you want to put them in a different namespace
    funcName = funcName || "docReady";
    baseObj = baseObj || window;
    var readyList = [];
    var readyFired = false;
    var readyEventHandlersInstalled = false;

    // call this when the document is ready
    // this function protects itself against being called more than once
    function ready() {
        if (!readyFired) {
            // this must be set to true before we start calling callbacks
            readyFired = true;
            for (var i = 0; i < readyList.length; i++) {
                // if a callback here happens to add new ready handlers,
                // the docReady() function will see that it already fired
                // and will schedule the callback to run right after
                // this event loop finishes so all handlers will still execute
                // in order and no new ones will be added to the readyList
                // while we are processing the list
                readyList[i].fn.call(window, readyList[i].ctx);
            }
            // allow any closures held by these functions to free
            readyList = [];
        }
    }

    function readyStateChange() {
        if ( document.readyState === "complete" ) {
            ready();
        }
    }

    // This is the one public interface
    // docReady(fn, context);
    // the context argument is optional - if present, it will be passed
    // as an argument to the callback
    baseObj[funcName] = function(callback, context) {
        if (typeof callback !== "function") {
            throw new TypeError("callback for docReady(fn) must be a function");
        }
        // if ready has already fired, then just schedule the callback
        // to fire asynchronously, but right away
        if (readyFired) {
            setTimeout(function() {callback(context);}, 1);
            return;
        } else {
            // add the function and context to the list
            readyList.push({fn: callback, ctx: context});
        }
        // if document already ready to go, schedule the ready function to run
        if (document.readyState === "complete") {
            setTimeout(ready, 1);
        } else if (!readyEventHandlersInstalled) {
            // otherwise if we don't have event handlers installed, install them
            if (document.addEventListener) {
                // first choice is DOMContentLoaded event
                document.addEventListener("DOMContentLoaded", ready, false);
                // backup is window load event
                window.addEventListener("load", ready, false);
            } else {
                // must be IE
                document.attachEvent("onreadystatechange", readyStateChange);
                window.attachEvent("onload", ready);
            }
            readyEventHandlersInstalled = true;
        }
    }
})("docReady", window);

कोड का नवीनतम संस्करण सार्वजनिक रूप से GitHub पर https://github.com/jfriend00/docReady पर साझा किया जाता है

उपयोग:

// pass a function reference
docReady(fn);

// use an anonymous function
docReady(function() {
    // code here
});

// pass a function reference and a context
// the context will be passed to the function as the first argument
docReady(fn, context);

// use an anonymous function with a context
docReady(function(context) {
    // code here that can use the context argument that was passed to docReady
}, ctx);

इसका परीक्षण किया गया है:

IE6 and up
Firefox 3.6 and up
Chrome 14 and up
Safari 5.1 and up
Opera 11.6 and up
Multiple iOS devices
Multiple Android devices

कार्य कार्यान्वयन और परीक्षण बिस्तर: http://jsfiddle.net/jfriend00/YfD3C/

यहां बताया गया है कि यह कैसे काम करता है:

  1. एक IIFE (तुरंत फंक्शन अभिव्यक्ति का आह्वान) बनाएं ताकि हमारे पास गैर-सार्वजनिक राज्य चर हो।
  2. एक सार्वजनिक समारोह docReady(fn, context) घोषित करें docReady(fn, context)
  3. जब docReady(fn, context) कहा जाता है, तो जांच करें कि तैयार हैंडलर पहले से ही निकाल दिया गया है या नहीं। यदि ऐसा है, तो जेएस के इस थ्रेड के बाद setTimeout(fn, 1) साथ समाप्त होने के बाद बस नए जोड़े गए कॉलबैक को ठीक से setTimeout(fn, 1)
  4. यदि तैयार हैंडलर पहले से ही नहीं निकाल दिया गया है, तो बाद में कॉल करने के लिए कॉलबैक की सूची में यह नया कॉलबैक जोड़ें।
  5. जांचें कि दस्तावेज़ पहले से तैयार है या नहीं। यदि ऐसा है, तो सभी तैयार हैंडलर निष्पादित करें।
  6. अगर हमने ईवेंट श्रोताओं को अभी तक यह नहीं पता है कि दस्तावेज़ कब तैयार हो जाए, तो उन्हें अभी इंस्टॉल करें।
  7. यदि document.addEventListener मौजूद है, तो "DOMContentLoaded" और "load" ईवेंट दोनों के लिए .addEventListener() का उपयोग करके ईवेंट हैंडलर इंस्टॉल करें। "लोड" सुरक्षा के लिए एक बैकअप घटना है और इसकी आवश्यकता नहीं होनी चाहिए।
  8. यदि document.addEventListener मौजूद नहीं है, तो "onreadystatechange" और "onload" ईवेंट के लिए .attachEvent() का उपयोग कर ईवेंट हैंडलर इंस्टॉल करें।
  9. onreadystatechange घटना में, यह देखने के लिए जांचें कि क्या document.readyState === "complete" और यदि ऐसा है, तो सभी तैयार हैंडलरों को आग लगाने के लिए फ़ंक्शन को कॉल करें।
  10. अन्य सभी ईवेंट हैंडलर में, सभी तैयार हैंडलरों को आग लगाने के लिए एक फ़ंक्शन को कॉल करें।
  11. फ़ंक्शन में सभी तैयार हैंडलर को कॉल करने के लिए, यह देखने के लिए एक स्टेट वैरिएबल जांचें कि क्या हमने पहले से ही निकाल दिया है या नहीं। अगर हमारे पास कुछ भी नहीं है। अगर हमें अभी तक बुलाया नहीं गया है, तो तैयार कार्यों की सरणी के माध्यम से लूप करें और प्रत्येक को कॉल किए गए क्रम में कॉल करें। यह इंगित करने के लिए ध्वज सेट करें कि इन सभी को बुलाया गया है ताकि उन्हें कभी भी एक से अधिक बार निष्पादित नहीं किया जा सके।
  12. फ़ंक्शन सरणी साफ़ करें ताकि वे जो भी बंद कर रहे हों, उन्हें मुक्त किया जा सके।

docReady() साथ पंजीकृत हैंडलर को पंजीकृत किए गए क्रम में निकाल दिया जाएगा।

यदि दस्तावेज़ पहले से तैयार होने के बाद आप docReady(fn) कॉल docReady(fn) , तो कॉलबैक को निष्पादन के वर्तमान थ्रेड को setTimeout(fn, 1) का उपयोग करके पूरा करने के लिए निर्धारित किया जाएगा। यह कॉलिंग कोड को हमेशा यह मानने की अनुमति देता है कि वे एसिंक कॉलबैक हैं जिन्हें बाद में बुलाया जाएगा, भले ही बाद में जैसे ही जेएस के वर्तमान धागे खत्म हो जाएं और यह कॉलिंग ऑर्डर को सुरक्षित रखे।


मुझे पूरा यकीन नहीं है कि आप क्या पूछ रहे हैं, लेकिन शायद यह मदद कर सकता है:

window.onload = function(){
    // Code. . .

}

या:

window.onload = main;

function main(){
    // Code. . .

}

यदि आप jQuery के बिना वैनिला सादा जावास्क्रिप्ट कर रहे हैं, तो आपको (इंटरनेट एक्सप्लोरर 9 या बाद में) का उपयोग करना होगा:

document.addEventListener("DOMContentLoaded", function(event) {
    // Your code to run since DOM is loaded and ready
});

ऊपर jQuery के बराबर है .ready :

$(document).ready(function() {
    console.log("Ready!");
});

जो भी इस तरह शोरथैंड लिखा जा सकता है, जो भी तैयार होने के बाद jQuery चलाएगा।

$(function() {
    console.log("ready!");
});

नीचे विश्वास नहीं किया जाना चाहिए (जो डीओएम तैयार नहीं है):

इस तरह एक IIFE उपयोग न करें जो स्वयं निष्पादित है:

 Example:

(function() {
   // Your page initialization code here  - WRONG
   // The DOM will be available here   - WRONG
})();

यह IIFE आपके डोम को लोड करने की प्रतीक्षा नहीं करेगा। (मैं क्रोम ब्राउज़र के नवीनतम संस्करण के बारे में भी बात कर रहा हूं!)


यहां Ram-swaroop's "सभी ब्राउज़रों में काम करता है" विविधता का एक साफ-सुथरा, गैर-eval-उपयोग संस्करण है - सभी ब्राउज़रों में काम करता है!

function onReady(yourMethod) {
  var readyStateCheckInterval = setInterval(function() {
    if (document && document.readyState === 'complete') { // Or 'interactive'
      clearInterval(readyStateCheckInterval);
      yourMethod();
    }
  }, 10);
}
// use like
onReady(function() { alert('hello'); } );

यह चलाने के लिए अतिरिक्त 10 एमएस इंतजार करता है, हालांकि, यहां एक और जटिल तरीका है जो नहीं होना चाहिए:

function onReady(yourMethod) {
  if (document.readyState === 'complete') { // Or also compare to 'interactive'
    setTimeout(yourMethod, 1); // Schedule to run immediately
  }
  else {
    readyStateCheckInterval = setInterval(function() {
      if (document.readyState === 'complete') { // Or also compare to 'interactive'
        clearInterval(readyStateCheckInterval);
        yourMethod();
      }
    }, 10);
  }
}

// Use like
onReady(function() { alert('hello'); } );

// Or
onReady(functionName);

यह भी देखें कि क्या डीओएम ढांचे के बिना तैयार है या नहीं?


document.ondomcontentready=function(){} को चाल document.ondomcontentready=function(){} चाहिए, लेकिन इसमें पूर्ण ब्राउज़र संगतता नहीं है।

ऐसा लगता है कि आपको बस jQuery मिनट का उपयोग करना चाहिए





html