javascript - क्या कोई जावास्क्रिप्ट/jQuery डोम परिवर्तन श्रोता है?




google-chrome-extension (4)

अनिवार्य रूप से मैं एक डीआईवी परिवर्तन की सामग्री जब एक स्क्रिप्ट निष्पादित करना चाहता हूं। चूंकि स्क्रिप्ट अलग हैं (क्रोम एक्सटेंशन और वेबपृष्ठ स्क्रिप्ट में सामग्री स्क्रिप्ट), मुझे बस डीओएम राज्य में बदलावों का पालन करने की आवश्यकता है। मैं मतदान स्थापित कर सकता था लेकिन यह मैला लगता है।


आप div को कैसे बदल रहे हैं इस पर निर्भर करते हुए एक और दृष्टिकोण। यदि आप अपनी एचटीएमएल () विधि के साथ div की सामग्री को बदलने के लिए JQuery का उपयोग कर रहे हैं, तो आप उस विधि को बढ़ा सकते हैं और हर बार जब आप एक div में html डालते हैं तो पंजीकरण फ़ंक्शन कॉल कर सकते हैं।

(function( $, oldHtmlMethod ){
    // Override the core html method in the jQuery object.
    $.fn.html = function(){
        // Execute the original HTML method using the
        // augmented arguments collection.

        var results = oldHtmlMethod.apply( this, arguments );
        com.invisibility.elements.findAndRegisterElements(this);
        return results;

    };
})( jQuery, jQuery.fn.html );

हम एचटीएमएल () को कॉल को अवरुद्ध करते हैं, इसके साथ पंजीकरण फ़ंक्शन को कॉल करते हैं, जो संदर्भ में नई सामग्री प्राप्त करने वाले लक्ष्य तत्व को संदर्भित करता है, फिर हम मूल jquery.html () फ़ंक्शन पर कॉल को पास करते हैं। मूल HTML () विधि के परिणामों को वापस याद रखना याद रखें, क्योंकि JQuery विधि श्रृंखला के लिए इसकी अपेक्षा करता है।

विधि ओवरराइडिंग और एक्सटेंशन के बारे में अधिक जानकारी के लिए, http://www.bennadel.com/blog/2009-Using-Self-Executing-Function-Arguments-To-Override-Core-jQuery-Methods.htm उपयोग करना- स्वयं- निष्पादन - कार्य- अनुबंध- टू- ओवरराइड- कोर- jQuery-Methods.htm, जहां है मैंने बंद समारोह को पकड़ लिया। JQuery की साइट पर प्लगइन ट्यूटोरियल भी देखें।


कई साइटें गतिशील रूप से सामग्री को जोड़ने / दिखाने / बदलने के लिए AJAX का उपयोग करती हैं। कभी-कभी इसका उपयोग इन-साइट नेविगेशन के बजाय किया जाता है, इसलिए वर्तमान यूआरएल प्रोग्रामेटिक रूप से बदल दिया जाता है और इस मामले में सामग्री स्क्रिप्ट स्वचालित रूप से ब्राउज़र द्वारा निष्पादित नहीं होती हैं क्योंकि पृष्ठ दूरस्थ सर्वर से पूरी तरह से नहीं लाया जाता है।

सामग्री स्क्रिप्ट में उपलब्ध पृष्ठ परिवर्तनों का पता लगाने के सामान्य जेएस तरीके।

  • उत्परिवर्तन ऑब्सर्वर ( docs ) को सचमुच डीओएम परिवर्तनों का पता लगाने के लिए:

    • HTML सामग्री को पृष्ठ पर लोड होने के रूप में कैसे बदलें
    • पूरे डोम में नोड्स का पता लगाने के लिए उत्परिवर्तन ऑब्सर्वर का प्रदर्शन ।
  • उन साइटों के लिए ईवेंट श्रोता जो एक DOM ईवेंट भेजकर सामग्री परिवर्तन को इंगित करते हैं:

    • pjax:end कई pjax- आधारित साइटों द्वारा उपयोग किए जाने वाले document पर pjax:end जैसे गिटहब,
      पीजेक्स लोड से पहले और उसके बाद jQuery को कैसे चलाएं देखें ?
    • window पर message जैसे कि क्रोम ब्राउज़र में Google खोज,
      क्रोम एक्सटेंशन को Google खोज रीफ्रेश का पता लगाएं
    • यूट्यूब द्वारा प्रयुक्त document पर spfdone ,
      देखें कि पेज यूट्यूब पर पृष्ठ नेविगेशन का पता कैसे लगाया जाए और पृष्ठ प्रस्तुत करने से पहले HTML को संशोधित करें?
  • सेट इंटरवल के माध्यम से डीओएम की आवधिक जांच :
    जाहिर है यह केवल उन मामलों में काम करेगा जब आप अपने आईडी / चयनकर्ता द्वारा प्रकट होने वाले विशिष्ट तत्व की प्रतीक्षा करेंगे, और यह आपको सार्वभौमिक रूप से नई गतिशील रूप से अतिरिक्त सामग्री का पता लगाने नहीं देगा जबतक कि आप किसी भी प्रकार की फिंगरप्रिंटिंग को मौजूदा सामग्री का आविष्कार नहीं करते।

  • इंजेक्शन डीओएम स्क्रिप्ट के अंदर क्लोकिंग हिस्ट्री एपीआई :

    document.head.appendChild(document.createElement('script')).text = '(' +
        function() {
            // injected DOM script is not a content script anymore, 
            // it can modify objects and functions of the page
            var _pushState = history.pushState;
            history.pushState = function(state, title, url) {
                _pushState.call(this, state, title, url);
                window.dispatchEvent(new CustomEvent('state-changed', {detail: state}));
            };
            // repeat the above for replaceState too
        } + ')(); this.remove();'; // remove the DOM script element
    
    // And here content script listens to our DOM script custom events
    window.addEventListener('state-changed', function(e) {
        console.log('History state changed', e.detail, location.hash);
        doSomething();
    });
    
  • hashchange , popstate घटनाओं को सुनना:

    window.addEventListener('hashchange', function(e) {
        console.log('URL hash changed', e);
        doSomething();
    });
    window.addEventListener('popstate', function(e) {
        console.log('State changed', e);
        doSomething();
    });
    


एक्सटेंशन-विशिष्ट: background / ईवेंट पृष्ठ में यूआरएल परिवर्तन का पता लगाएं।

नेविगेशन के साथ काम करने के लिए उन्नत एपीआई हैं: webNavigation , webRequest , लेकिन हम सरल chrome.tabs.onUpdated ईवेंट श्रोता का उपयोग करेंगे जो सामग्री स्क्रिप्ट को संदेश भेजता है :

  • manifest.json:
    पृष्ठभूमि / घटना पृष्ठ घोषित करें
    सामग्री स्क्रिप्ट घोषित करें
    "tabs" permission जोड़ें।

  • background.js

    var rxLookfor = /^https?:\/\/(www\.)?google\.(com|\w\w(\.\w\w)?)\/.*?[?#&]q=/;
    chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
        if (rxLookfor.test(changeInfo.url)) {
            chrome.tabs.sendMessage(tabId, 'url-update');
        }
    });
    
  • content.js

    chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
        if (msg === 'url-update') {
            doSomething();
        }
    });
    

docs द्वारा प्रदान किए गए "कच्चे" टूल के अतिरिक्त, डोम उत्परिवर्तन के साथ काम करने के लिए "सुविधा" पुस्तकालय मौजूद हैं।

विचार करें: उत्परिवर्तन ऑब्सर्वर subtrees के मामले में प्रत्येक डोम परिवर्तन का प्रतिनिधित्व करता है। तो यदि आप उदाहरण के लिए, एक निश्चित तत्व को डालने की प्रतीक्षा कर रहे हैं, तो यह mutations.mutation[i].addedNodes[j] के बच्चों के अंदर गहरा हो सकता है। mutations.mutation[i].addedNodes[j]

एक और समस्या यह है कि जब आपका कोड, उत्परिवर्तन की प्रतिक्रिया में, डीओएम बदलता है - आप अक्सर इसे फ़िल्टर करना चाहते हैं।

एक अच्छी सुविधा लाइब्रेरी जो ऐसी समस्याओं को हल करती है mutation-summary (अस्वीकरण: मैं लेखक नहीं हूं, केवल एक संतुष्ट उपयोगकर्ता हूं), जो आपको अपनी रुचि के बारे में प्रश्न निर्दिष्ट करने में सक्षम बनाता है, और ठीक उसी तरह मिलता है।

दस्तावेज़ों से मूल उपयोग उदाहरण:

var observer = new MutationSummary({
  callback: updateWidgets,
  queries: [{
    element: '[data-widget]'
  }]
});

function updateWidgets(summaries) {
  var widgetSummary = summaries[0];
  widgetSummary.added.forEach(buildNewWidget);
  widgetSummary.removed.forEach(cleanupExistingWidget);
}

इस उत्तर की पुरानी सामग्री अब deprecated
MutationObserver आधार पर अन्य उत्तरों देखें।






google-chrome-extension