मुझे विस्तार क्षमता के लिए DOM परिवर्तन ला MutationEvents की समकालिक सूचनाओं की आवश्यकता है। MutationEvents, हालांकि, बहिष्कृत हैं। MutationObserver की उपयोगिता सीमित है क्योंकि जिस तरह से यह परिवर्तनों को एकत्रित करता है और परिवर्तन किए जाने के बाद उन्हें वितरित करता है।

तो, सरल प्रश्न। क्या मौजूदा (2019) ब्राउज़र एक्सटेंशन में एलिमेंट स्टाइल में बदलाव की सिंक्रोनस नोटिफिकेशन संभव है?

1
JQPx 31 अक्टूबर 2019, 04:52

1 उत्तर

सबसे बढ़िया उत्तर

आपने जिन लोगों का उल्लेख किया है, उनके अलावा कोई एपीआई नहीं है। एकमात्र अतिरिक्त तरीका है Node.prototype.appendChild को हुक करना, और DOM को पेज संदर्भ में बदलने के लिए अन्य तरीकों का एक समूह। स्वाभाविक रूप से आपको आंतरिक HTML/बाहरी HTML सेटर्स जैसी चीज़ों को भी हुक करना होगा।

प्रोटोटाइप विधियों को फिर से परिभाषित करने से कुछ ऐसी साइटें टूट सकती हैं जो समान निम्न-स्तरीय चीजें करती हैं।
सैद्धांतिक रूप से, कम से कम, तो चेतावनी दी जाए।

यहां एक सरल सामग्री स्क्रिप्ट है जो कुछ सामान्य विधियों को स्वीकार करती है:

const eventId = chrome.runtime.id + Math.random().toString(36);
const script = document.createElement('script');
script.textContent = `(${eventId => {
  let reportingEnabled = true;
  // only simple data can be transferred, not DOM elements, not functions, etc.
  const sendReport = detail => dispatchEvent(new CustomEvent(eventId, {detail}));
  const makeHook = (name, fn) =>
    function () {
      if (reportingEnabled) sendReport({name, phase: 'pre'});        
      const res = fn.apply(this, arguments);
      if (reportingEnabled) sendReport({name, phase: 'post'});        
      return res;
    };

  const {appendChild} = Node.prototype;
  Node.prototype.appendChild = 
    Element.prototype.appendChild = makeHook('appendChild', appendChild);

  const {append} = Element.prototype;
  Element.prototype.append = makeHook('append', append);

  const innerHTML = Object.getOwnPropertyDescriptor(Element.prototype, 'innerHTML');
  innerHTML.set = makeHook('innerHTML', innerHTML.set);
  Object.defineProperties(Element.prototype, {innerHTML});
}})('${eventId}')`;

document.documentElement.appendChild(script);
script.remove();

window.addEventListener(eventId, e => {
  console.log(e.detail);
});

जाहिर है आपको अन्य सभी विधियों जैसे कि removeChild, insertBefore, और इसी तरह हुक करने की आवश्यकता होगी।

पृष्ठ संदर्भ से सामग्री स्क्रिप्ट में संदेश के माध्यम से DOM तत्वों को स्थानांतरित नहीं किया जा सकता है। केवल तुच्छ प्रकार जैसे तार, संख्याएं, बूलियन, अशक्त, और सरणियाँ/वस्तुएँ जिनमें ऐसे प्रकार होते हैं, हस्तांतरणीय हैं। हालांकि मौजूदा डोम तत्व के लिए एक चाल है: आप इसकी अनुक्रमणिका [...document.getElementsByTagName('*')].indexOf(element) स्थानांतरित कर सकते हैं और फिर इसे तुरंत document.getElementsByTagName('*')[index] के रूप में उपयोग कर सकते हैं। शैडोडोम के लिए आपको एक पुनरावर्ती अनुक्रमणिका बनाना होगा।

2
wOxxOm 31 अक्टूबर 2019, 17:11