क्या स्क्रिप्ट को HTML के साथ डाला जा सकता है?


223

मैंने पृष्ठ innerHTMLपर कुछ स्क्रिप्ट को लोड करने का प्रयास किया <div>। ऐसा प्रतीत होता है कि स्क्रिप्ट डोम में लोड होती है, लेकिन इसे कभी भी निष्पादित नहीं किया जाता है (कम से कम फ़ायरफ़ॉक्स और क्रोम में)। क्या स्क्रिप्ट को निष्पादित करने का एक तरीका है जब उन्हें सम्मिलित किया जाता है innerHTML?

नमूना कोड:

<!DOCTYPE html>
<html>
  <body onload="document.getElementById('loader').innerHTML = '<script>alert(\'hi\')<\/script>'">
    Shouldn't an alert saying 'hi' appear?
    <div id="loader"></div>
  </body>
</html>

जवाबों:


88

आपको किसी भी स्क्रिप्ट कोड को निष्पादित करने के लिए eval () का उपयोग करना होगा जिसे आपने DOM टेक्स्ट के रूप में डाला है।

MooTools आप के लिए यह स्वचालित रूप से करेंगे, और मुझे यकीन है कि jQuery के रूप में अच्छी तरह से होगा (संस्करण पर निर्भर करता है। jQuery संस्करण 1.6+ उपयोग करता है eval)। यह <script>टैग्स को पार्स करने और अपनी सामग्री से बचने के साथ-साथ अन्य "गोचैकों" का एक गुच्छा बचाता है ।

आमतौर पर यदि आप eval()इसे स्वयं करने जा रहे हैं , तो आप बिना किसी HTML मार्कअप के जैसे स्क्रिप्ट कोड बनाना / भेजना चाहते हैं <script>, क्योंकि ये eval()ठीक से नहीं होंगे ।


12
जो मैं वास्तव में करना चाहता हूं वह बाहरी स्क्रिप्ट को लोड करना है, न कि केवल कुछ स्थानीय स्क्रिप्ट को निकालना। आंतरिक HTML के साथ एक स्क्रिप्ट टैग जोड़ना एक स्क्रिप्ट DOM तत्व बनाने और इसे शरीर में जोड़ने की तुलना में बहुत कम है, और मैं अपने कोड को यथासंभव कम करने की कोशिश कर रहा हूं। क्या आपको इनर HTML जैसी किसी चीज़ का उपयोग करने के बजाय डोम स्क्रिप्ट तत्वों को बनाना है और उन्हें डोम में जोड़ना है? वहाँ एक दस्तावेज़ के साथ ऐसा करने का एक तरीका है। एक समारोह के भीतर से लिखें?
क्रेग

5
जैसा कि ज़ोम्बैट का सुझाव है, बाहरी स्क्रिप्ट को लोड करने के लिए एक जावास्क्रिप्ट फ्रेमवर्क का उपयोग करें, पहिया को फिर से स्थापित करने का प्रयास न करें। JQuery इसे बहुत आसान बनाता है, बस JQuery और कॉल शामिल करें: $ .getScript (url)। आप एक कॉलबैक फ़ंक्शन भी प्रदान कर सकते हैं जो स्क्रिप्ट लोड होने के बाद निष्पादित हो जाएगा।
एरियल पोपोव्स्की

2
एरियल सही है। मैं आपके कोड को छोटा रखने की कोशिश कर रहा हूं और <script>टैग को छोटा करने की कोशिश कर रहा हूं innerHTML, लेकिन यह काम नहीं करता है। यह सब सिर्फ सादा पाठ है जब तक यह माध्यम से नहीं चलता eval()। और दुख की बात है, eval()HTML टैग को पार्स नहीं करता है, इसलिए आप समस्याओं की एक श्रृंखला के साथ समाप्त होते हैं।
ज़ोम्बैट

21
eval () किसी भी समस्या का एक महान समाधान नहीं है।
buley

2
मैंने खुद को निकालने () की कोशिश की। यह एक भयानक विचार है। आपको पूरी चीज EACH TIME से निकालनी होगी । यहां तक ​​कि अगर आप एक चर नाम और मूल्य घोषित करते हैं, तो आपको इसे काम करने के लिए हर बार नए सिरे से घोषित करना होगा। यह त्रुटियों का एक बुरा सपना है।
यूस्टे इगो

88

यहाँ आपकी समस्या का एक बहुत ही दिलचस्प समाधान है: http://24ways.org/2005/have-your-dom-and-script-too-too

इसलिए स्क्रिप्ट टैग के बजाय इसका उपयोग करें:

<img src="empty.gif" onload="alert('test');this.parentNode.removeChild(this);" />


12
ये जबरदस्त है!
सीमित करें

मेरे लिए काम नहीं करता है, जब अजाक्स अनुरोध के परिणामस्वरूप डाला जाता है: सिंटैक्स त्रुटि गायब; स्क्रिप्ट स्ट्रिंग की शुरुआत में वक्तव्य से पहले
ओलिवर

आप लोग अपने पेज कोड में & lt; img src ... लाइन कैसे जोड़ सकते हैं? क्या आप इसके लिए document.write () दस्तावेज या इसका उपयोग करते हैं। दोनों मेरे लिए असफल हो रहे हैं :(
यूस्टे इगो

एक onloadविशेषता के अंदर बहुत सारे कोड लिखने के लिए बहुत व्यावहारिक नहीं है । इसके अलावा इसमें मौजूद होने और लोड होने के लिए एक अतिरिक्त फ़ाइल की आवश्यकता होती है। मोमो का हल समझौता से कम नहीं है।
प्रात:

15
आप बेस 64 को अपनी ट्रिगर-इमेज को एनकोड कर सकते हैं <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">(यह नेटवर्क रिक्वेस्ट नहीं करेगा) वास्तव में ... आपको एक इमेज की जरूरत नहीं है, एक गैर-मौजूदा इमेज का संदर्भ लें और onloadउपयोग के बजाय onerror(लेकिन यह नेटवर्क रिक्वेस्ट करेगा)
डैनी '365CSI' एंगेलमैन

83

यहाँ एक विधि है जो पुनरावर्ती के साथ सभी लिपियों को बदल देती है:

function nodeScriptReplace(node) {
        if ( nodeScriptIs(node) === true ) {
                node.parentNode.replaceChild( nodeScriptClone(node) , node );
        }
        else {
                var i        = 0;
                var children = node.childNodes;
                while ( i < children.length ) {
                        nodeScriptReplace( children[i++] );
                }
        }

        return node;
}
function nodeScriptIs(node) {
        return node.tagName === 'SCRIPT';
}
function nodeScriptClone(node){
        var script  = document.createElement("script");
        script.text = node.innerHTML;
        for( var i = node.attributes.length-1; i >= 0; i-- ) {
                script.setAttribute( node.attributes[i].name, node.attributes[i].value );
        }
        return script;
}

उदाहरण कॉल:

nodeScriptReplace(document.getElementsByTagName("body")[0]);

9
मैं थोड़ा हैरान हूँ कि आपका जवाब यह सब नीचे है। IMHO, यह सबसे अच्छा समाधान है, यह विधि आपको विशिष्ट यूआरएल या सामग्री के साथ स्क्रिप्ट को प्रतिबंधित करने की अनुमति भी देगी।
द्विविम

1
@ inf3rno करता है या नहीं? यह काम करता था, कभी किसी ने कुछ भी अलग दावा किया?
मिमी

[0] का उद्देश्य क्या है? क्या आप नोडस्क्रिप्टReplace (document.getElementById ()। html) का उपयोग कर सकते हैं;
बाओ थाई

@ बाओहाई हाँ। आप ऐसा कर सकते हैं।
एमएमएम

IWebBrowser2 में मदद करने के लिए प्रतीत नहीं होता है; मैं पुष्टि कर सकता हूं कि स्क्रिप्ट टैग createElement के साथ पुनः प्राप्त हो सकते हैं, लेकिन मैं अभी भी इनवोकस्क्रिप्ट () के माध्यम से उन्हें आमंत्रित करने में असमर्थ हूं।
डेव

46

आप स्क्रिप्ट बना सकते हैं और फिर सामग्री को इंजेक्ट कर सकते हैं।

var g = document.createElement('script');
var s = document.getElementsByTagName('script')[0];
g.text = "alert(\"hi\");"
s.parentNode.insertBefore(g, s);

यह सभी ब्राउज़रों में काम करता है :)


1
जब तक दस्तावेज़ में कोई अन्य स्क्रिप्ट तत्व न हों। document.documentElementइसके बजाय उपयोग करें ।
एली ग्रे

4
आवश्यक नहीं है क्योंकि आप दूसरी स्क्रिप्ट से स्क्रिप्ट लिख रहे हैं। <script> var g = document.createElement('script'); var s = document.getElementsByTagName('script')[0]; //reference this script g.text = "alert(\"hi\");" s.parentNode.insertBefore(g, s); </script>
पाब्लो मोरेटी

3
कौन कहता है कि यह दूसरी स्क्रिप्ट से है? आप <script>तत्वों के बिना जावास्क्रिप्ट चला सकते हैं। जैसे <img onerror="..." src="#">और <body onload="...">। यदि आप तकनीकी होना चाहते हैं, तो यह गैर-एचटीएमएल / एसवीजी दस्तावेजों में बेवजह नाम बदलने के कारण काम नहीं करेगा।
एली ग्रे

2
फेसबुक अपने एसडीके में पाब्लो के जवाब का उपयोग करता है। Developers.facebook.com/docs/javascript/quickstart/v2.2#loading
geoyws

30

मैंने इस कोड का उपयोग किया है, यह ठीक काम कर रहा है

var arr = MyDiv.getElementsByTagName('script')
for (var n = 0; n < arr.length; n++)
    eval(arr[n].innerHTML)//run script inside div

1
धन्यवाद। इसने TinyBox2 Jquery प्लगइन का उपयोग करके बनाई गई एक मोडल पॉपअप में Disqus Universal कोड को जोड़ने की मेरी समस्या को ठीक किया।
gsinha

3
दुर्भाग्य से, यह समाधान तब काम नहीं करता है जब स्क्रिप्ट में फ़ंक्शन होते हैं जो बाद में लागू किए जाएंगे।
जोस गोमेज़

7

मुझे इनरएचटीएमएल के साथ यह समस्या थी, मुझे अपने रिएक्टज एप्लिकेशन के "हेड" टैग के लिए एक हॉटज़र स्क्रिप्ट को संलग्न करना था और इसे ठीक करने के बाद निष्पादित करना होगा।

"हेड" टैग में डायनामिक नोड आयात के लिए अच्छे समाधानों में से एक रिएक्ट-हेलमेंट मॉड्यूल है।


इसके अलावा, प्रस्तावित मुद्दे के लिए एक उपयोगी समाधान है:

आंतरिक HTML में कोई स्क्रिप्ट टैग नहीं!

यह पता चलता है कि एचटीएमएल 5 स्क्रिप्ट टैग को आंतरिक HTML संपत्ति का उपयोग करके गतिशील रूप से जोड़ने की अनुमति नहीं देता है। तो निम्नलिखित कार्य नहीं करेगा और हैलो वर्ल्ड कहे जाने वाला कोई अलर्ट नहीं होगा!

element.innerHTML = "<script>alert('Hello World!')</script>";

यह HTML5 कल्पना में प्रलेखित है:

नोट: इनर HTML का उपयोग करके डाले गए स्क्रिप्ट तत्व निष्पादित होने पर निष्पादित नहीं होते हैं।

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

समाधान: गतिशील रूप से स्क्रिप्ट जोड़ना

स्क्रिप्ट टैग को गतिशील रूप से जोड़ने के लिए, आपको एक नया स्क्रिप्ट तत्व बनाना होगा और उसे लक्ष्य तत्व में जोड़ना होगा।

आप बाहरी स्क्रिप्ट के लिए ऐसा कर सकते हैं:

var newScript = document.createElement("script");
newScript.src = "http://www.example.com/my-script.js";
target.appendChild(newScript);

और इनलाइन स्क्रिप्ट:

var newScript = document.createElement("script");
var inlineScript = document.createTextNode("alert('Hello World!');");
newScript.appendChild(inlineScript); 
target.appendChild(newScript);

5

किसी को अब भी यह करने के लिए कोशिश कर रहा है के लिए, नहीं, आप एक स्क्रिप्ट का उपयोग कर इंजेक्षन नहीं कर सकते हैं innerHTML, लेकिन यह का उपयोग कर एक स्क्रिप्ट टैग में एक स्ट्रिंग लोड करने के लिए संभव है एक BlobऔरURL.createObjectURL

मैंने एक उदाहरण बनाया है जो आपको एक स्क्रिप्ट के रूप में एक स्ट्रिंग चलाने और एक वादा के माध्यम से लौटाए गए स्क्रिप्ट का 'निर्यात' प्राप्त करने की अनुमति देता है:

function loadScript(scriptContent, moduleId) {
    // create the script tag
    var scriptElement = document.createElement('SCRIPT');

    // create a promise which will resolve to the script's 'exports'
    // (i.e., the value returned by the script)
    var promise = new Promise(function(resolve) {
        scriptElement.onload = function() {
            var exports = window["__loadScript_exports_" + moduleId];
            delete window["__loadScript_exports_" + moduleId];
            resolve(exports);
        }
    });

    // wrap the script contents to expose exports through a special property
    // the promise will access the exports this way
    var wrappedScriptContent =
        "(function() { window['__loadScript_exports_" + moduleId + "'] = " + 
        scriptContent + "})()";

    // create a blob from the wrapped script content
    var scriptBlob = new Blob([wrappedScriptContent], {type: 'text/javascript'});

    // set the id attribute
    scriptElement.id = "__loadScript_module_" + moduleId;

    // set the src attribute to the blob's object url 
    // (this is the part that makes it work)
    scriptElement.src = URL.createObjectURL(scriptBlob);

    // append the script element
    document.body.appendChild(scriptElement);

    // return the promise, which will resolve to the script's exports
    return promise;
}

...

function doTheThing() {
    // no evals
    loadScript('5 + 5').then(function(exports) {
         // should log 10
        console.log(exports)
    });
}

मैंने इसे अपने वास्तविक कार्यान्वयन से सरल कर दिया है, इसलिए कोई वादा नहीं करता कि इसमें कोई कीड़े नहीं हैं। लेकिन सिद्धांत काम करता है।

यदि आप स्क्रिप्ट चलाने के बाद किसी भी मूल्य को वापस पाने के बारे में परवाह नहीं करते हैं, तो यह और भी आसान है; बस बाहर Promiseऔर onloadबिट्स छोड़ दें । आपको स्क्रिप्ट को लपेटने या वैश्विक window.__load_script_exports_संपत्ति बनाने की भी आवश्यकता नहीं है ।


1
मैंने अभी इसकी कोशिश की और यह क्रोम 57 पर काम करता है। एक स्क्रिप्ट टैग पर इनरएचटीएमएल टेक्स्ट को निष्पादित करता है।
iPherian

यह दिलचस्प है, यह पहले काम नहीं करता था। मुझे आश्चर्य है कि अगर यह व्यवहार क्रॉस-ब्राउज़र या केवल क्रोम 57 में है।
JayArby

4

यहाँ हमारे विज्ञापन सर्वर में उपयोग किए जाने वाले एक तत्व का आंतरिक HTML सेट करने के लिए एक पुनरावर्ती कार्य है:

// o: container to set the innerHTML
// html: html text to set.
// clear: if true, the container is cleared first (children removed)
function setHTML(o, html, clear) {
    if (clear) o.innerHTML = "";

    // Generate a parseable object with the html:
    var dv = document.createElement("div");
    dv.innerHTML = html;

    // Handle edge case where innerHTML contains no tags, just text:
    if (dv.children.length===0){ o.innerHTML = html; return; }

    for (var i = 0; i < dv.children.length; i++) {
        var c = dv.children[i];

        // n: new node with the same type as c
        var n = document.createElement(c.nodeName);

        // copy all attributes from c to n
        for (var j = 0; j < c.attributes.length; j++)
            n.setAttribute(c.attributes[j].nodeName, c.attributes[j].nodeValue);

        // If current node is a leaf, just copy the appropriate property (text or innerHTML)
        if (c.children.length == 0)
        {
            switch (c.nodeName)
            {
                case "SCRIPT":
                    if (c.text) n.text = c.text;
                    break;
                default:
                    if (c.innerHTML) n.innerHTML = c.innerHTML;
                    break;
            }
        }
        // If current node has sub nodes, call itself recursively:
        else setHTML(n, c.innerHTML, false);
        o.appendChild(n);
    }
}

आप यहां डेमो देख सकते हैं ।


3

आप इसे इस तरह से कर सकते हैं:

var mydiv = document.getElementById("mydiv");
var content = "<script>alert(\"hi\");<\/script>";

mydiv.innerHTML = content;
var scripts = mydiv.getElementsByTagName("script");
for (var i = 0; i < scripts.length; i++) {
    eval(scripts[i].innerText);
}

3

यहां एक समाधान जो स्क्रिप्ट का उपयोग नहीं करता है eval, और स्क्रिप्ट , लिंक्ड स्क्रिप्ट के साथ-साथ मॉड्यूल के साथ काम करता है ।

फ़ंक्शन 3 मापदंडों को स्वीकार करता है:

  • html : डालने के लिए html कोड के साथ स्ट्रिंग
  • भाग्य : लक्ष्य तत्व का संदर्भ
  • append : लक्ष्य तत्व HTML के अंत में सक्षम करने के लिए बूलियन ध्वज
function insertHTML(html, dest, append=false){
    // if no append is requested, clear the target element
    if(!append) dest.innerHTML = '';
    // create a temporary container and insert provided HTML code
    let container = document.createElement('div');
    container.innerHTML = html;
    // cache a reference to all the scripts in the container
    let scripts = container.querySelectorAll('script');
    // get all child elements and clone them in the target element
    let nodes = container.childNodes;
    for( let i=0; i< nodes.length; i++) dest.appendChild( nodes[i].cloneNode(true) );
    // force the found scripts to execute...
    for( let i=0; i< scripts.length; i++){
        let script = document.createElement('script');
        script.type = scripts[i].type || 'text/javascript';
        if( scripts[i].hasAttribute('src') ) script.src = scripts[i].src;
        script.innerHTML = scripts[i].innerHTML;
        document.head.appendChild(script);
        document.head.removeChild(script);
    }
    // done!
    return true;
}

मेरा मतलब है ... कोड सामग्री के साथ एक स्क्रिप्ट टैग लागू करना एक स्पष्ट है, है ना?
केविन बी

@ केविनबी कुख्यात मतभेद हैं ... कोशिश करें eval('console.log(this)')और आप सबसे स्पष्ट एक
कोलक्षी देखेंगे

इसलिए संदर्भ अलग है, और? यह अभी भी सिर्फ एक eval है।
केविन बी

@ केविनबी नहीं यह एक स्पष्ट नहीं है। यह कोशिश करो eval('let b=100').. और फिर beval के बाहर से जाने की कोशिश करो .... इसके साथ शुभकामनाएं, आपको इसकी आवश्यकता है
colxi

मेरे लिये कार्य करता है। चीयर्स
बेज़्ज़ो

1

क्रॉसमिर सोनोव के पास एक शानदार समाधान है जो सभी समस्याओं को दूर करता है। उनकी पद्धति को eval का उपयोग करने की आवश्यकता नहीं है, इसलिए कोई प्रदर्शन या सुरक्षा समस्याएं मौजूद नहीं हैं। यह आपको आंतरिक HTML स्ट्रिंग सेट करने की अनुमति देता है जिसमें js के साथ html शामिल है और इसे एक DOM तत्व में तुरंत अनुवाद करते हैं जबकि कोड के साथ मौजूद js भागों को भी निष्पादित करता है। संक्षिप्त, सरल, और जैसा आप चाहते हैं वैसा ही काम करता है।

उसके समाधान का आनंद लें:

http://krasimirtsonev.com/blog/article/Convert-HTML-string-to-DOM-element

महत्वपूर्ण लेख:

  1. आपको div टैग के साथ लक्ष्य तत्व को लपेटने की आवश्यकता है
  2. आपको div टैग के साथ src string को रैप करना होगा।
  3. यदि आप सीधे src स्ट्रिंग लिखते हैं और इसमें js भाग शामिल हैं, तो कृपया क्लोजिंग स्क्रिप्ट टैग को सही तरीके से लिखने के लिए ध्यान रखें (with \ इससे पहले /) यह एक स्ट्रिंग है।

1

के $(parent).html(code)बजाय का उपयोग करेंparent.innerHTML = code

निम्नलिखित उन स्क्रिप्ट को भी ठीक करता है जो उपयोग document.writeऔर स्क्रिप्ट को srcविशेषता के माध्यम से भरी हुई हैं । दुर्भाग्य से यह भी गूगल ऐडसेंस लिपियों के साथ काम नहीं करता है।

var oldDocumentWrite = document.write;
var oldDocumentWriteln = document.writeln;
try {
    document.write = function(code) {
        $(parent).append(code);
    }
    document.writeln = function(code) {
        document.write(code + "<br/>");
    }
    $(parent).html(html); 
} finally {
    $(window).load(function() {
        document.write = oldDocumentWrite
        document.writeln = oldDocumentWriteln
    })
}

स्रोत


1
यहां थोड़ी देर हो गई, लेकिन जो कोई भी इस पद्धति का उपयोग कर रहा है, वह नोटिस कर सकता है कि JQuery में आपको <स्क्रिप्ट src = "url> </ script> के बजाय $ .loadScript (url) का उपयोग करके अपनी स्क्रिप्ट लोड करने की आवश्यकता है - बाद वाला एक कारण होगा ब्राउज़रों पर पदावनत सिंक्रोनस XMLHttpRequest त्रुटि।
Stavm

1

टेम्पलेट और document.importNode का उपयोग करने का प्रयास करें। यहाँ एक उदाहरण है:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Sample</title>
</head>
<body>
<h1 id="hello_world">Sample</h1>
<script type="text/javascript">
 var div = document.createElement("div");
  var t = document.createElement('template');
  t.innerHTML =  "Check Console tab for javascript output: Hello world!!!<br/><script type='text/javascript' >console.log('Hello world!!!');<\/script>";
  
  for (var i=0; i < t.content.childNodes.length; i++){
    var node = document.importNode(t.content.childNodes[i], true);
    div.appendChild(node);
  }
 document.body.appendChild(div);
</script>
 
</body>
</html>


1
यह Microsoft Edge, किसी भी अन्य समाधान के साथ काम नहीं करता है?
सोल

1

आप अपनी <script>पसंद को भी लपेट सकते हैं और इसे निष्पादित किया जाएगा:

<your target node>.innerHTML = '<iframe srcdoc="<script>alert(top.document.title);</script>"></iframe>';

कृपया ध्यान दें: अंदर का दायरा srcdocआइफ्रेम को संदर्भित करता है, इसलिए आपको topमूल दस्तावेज तक पहुंचने के लिए ऊपर के उदाहरण में उपयोग करना होगा।


1

मैं हर बार ऐसा करता हूं कि मैं एक स्क्रिप्ट टैग को गतिशील रूप से सम्मिलित करना चाहता हूं!

  const html =
    `<script>
        alert('👋 there ! Wanna grab a 🍺'); 
    </script>`;

  const scriptEl = document.createRange().createContextualFragment(html);
  parent.append(scriptEl);

नोट: ES6 का इस्तेमाल किया

संपादित करें 1: आप लोगों के लिए स्पष्टीकरण - मैंने बहुत सारे उत्तर उपयोग किए हैं appendChildऔर आप लोगों को बताना चाहते हैं कि यह ठीक उसी तरह काम करता हैappend


0

हां, आप कर सकते हैं, लेकिन आपको इसे DOM के बाहर करना होगा और ऑर्डर सही होना चाहिए।

var scr = '<scr'+'ipt>alert("foo")</scr'+'ipt>';
window.onload = function(){
    var n = document.createElement("div");
    n.innerHTML = scr;
    document.body.appendChild(n);
}

... सतर्क करेगा 'फू'। यह काम नहीं करेगा:

document.getElementById("myDiv").innerHTML = scr;

और यहां तक ​​कि यह काम नहीं करेगा, क्योंकि नोड पहले डाला जाता है:

var scr = '<scr'+'ipt>alert("foo")</scr'+'ipt>';
window.onload = function(){
    var n = document.createElement("div");
    document.body.appendChild(n);
    n.innerHTML = scr;  
}

16
इसके लायक क्या है: यह वर्तमान ब्राउज़रों पर काम नहीं करता है।
विचर्ट अकरमन

0

इस समस्या के लिए मेरा समाधान नोड्स का पता लगाने के लिए एक म्यूटेशन ऑब्जर्वर सेट करना है <script></script>और फिर इसे <script></script>उसी नोड के साथ एक नए नोड के साथ बदलना है । उदाहरण के लिए:

let parentNode = /* node to observe */ void 0
let observer = new MutationObserver(mutations=>{
    mutations.map(mutation=>{
        Array.from(mutation.addedNodes).map(node=>{
            if ( node.parentNode == parentNode ) {
                let scripts = node.getElementsByTagName('script')
                Array.from(scripts).map(script=>{
                    let src = script.src
                    script = document.createElement('script')
                    script.src = src
                    return script
                })
            }
        })
    })
})
observer.observe(document.body, {childList: true, subtree: true});

1
बिना कहे मुझे नीचा दिखाने के लिए धन्यवाद। आप सभी को प्यार।
गाब्रिएल गार्सिया

0

गेब्रियल गार्सिया का उल्लेख MutationObservers सही रास्ते पर है, लेकिन मेरे लिए काफी काम नहीं आया। मुझे यकीन नहीं है कि अगर वह ब्राउज़र क्विकर के कारण था या मेरे अंत में गलती के कारण था, लेकिन मेरे लिए काम करने वाला संस्करण निम्नलिखित था:

document.addEventListener("DOMContentLoaded", function(event) {
    var observer = new MutationObserver(mutations=>{
        mutations.map(mutation=>{
            Array.from(mutation.addedNodes).map(node=>{
                if (node.tagName === "SCRIPT") {
                    var s = document.createElement("script");
                    s.text=node.text;
                    if (typeof(node.parentElement.added) === 'undefined')
                        node.parentElement.added = [];
                    node.parentElement.added[node.parentElement.added.length] = s;
                    node.parentElement.removeChild(node);
                    document.head.appendChild(s);
                }
            })
        })
    })
    observer.observe(document.getElementById("element_to_watch"), {childList: true, subtree: true,attributes: false});
};

बेशक, आपको element_to_watchउस तत्व के नाम से प्रतिस्थापित करना चाहिए जिसे संशोधित किया जा रहा है।

node.parentElement.addedउस स्क्रिप्ट टैग को संग्रहीत करने के लिए उपयोग किया जाता है जो इसमें जोड़े जाते हैं document.head। बाहरी पेज को लोड करने के लिए उपयोग किए जाने वाले फ़ंक्शन में, आप निम्न का उपयोग कर सकते हैं जैसे कि अब प्रासंगिक स्क्रिप्ट टैग को हटाने के लिए नहीं:

function freeScripts(node){
    if (node === null)
        return;
    if (typeof(node.added) === 'object') {
        for (var script in node.added) {
            document.head.removeChild(node.added[script]);
        }
        node.added = {};
    }
    for (var child in node.children) {
        freeScripts(node.children[child]);
    }
}

और एक लोड फ़ंक्शन की शुरुआत का एक उदाहरण:

function load(url, id, replace) {
    if (document.getElementById(id) === null) {
        console.error("Element of ID "+id + " does not exist!");
        return;
    }
    freeScripts(document.getElementById(id));
    var xhttp = new XMLHttpRequest();
    // proceed to load in the page and modify innerHTML
}

आप नोटिस करते हैं कि आप MutationObserverहर बार एक तत्व जोड़कर एक नया दस्तावेज़ जोड़ रहे हैं, है ना? Btw, मुझे आश्चर्य है कि आप क्यों कहते हैं कि मेरा कोड कार्यात्मक नहीं है।
गाब्रिएल गार्सिया

@gabrielgarcia मैंने कहा कि आपका कोड कार्यात्मक नहीं था क्योंकि मैंने इसे आज़माया था और यह बस काम नहीं आया। इसे देखते हुए, यह पूरी तरह से संभव है कि मुझ पर था, आप नहीं, और मैं ईमानदारी से इस बात के लिए माफी माँगता हूं कि मैंने यह किस तरह से किया था। अब इसे ठीक कर रहे हैं।
Pixherodev

पुन: प्रत्येक बार एक तत्व जोड़कर MutationObserver को दस्तावेज़ में जोड़ा जाता है, आप किस बारे में बात कर रहे हैं? DOMContentLoaded, और मैं MDN से यहाँ उद्धृत करता हूं, "जब लोडिंग समाप्त करने के लिए स्टाइलशीट, चित्र और सबफ़्रेम की प्रतीक्षा किए बिना प्रारंभिक HTML दस्तावेज़ को पूरी तरह से लोड और पार्स किया गया है, तो आग लग जाती है।" वह एक बार है, और केवल एक बार। इसके अलावा, यह स्क्रिप्ट मेरी साइट पर मुद्दों के बिना काम कर रही है, और डिबगिंग यह केवल एक बार हो रहा है दिखाता है, इसलिए यह एक बार अभ्यास के साथ-साथ सिद्धांत में भी है।
Pixherodev

1
तुम ठीक कह रहे हो ... मैंने इसे मिस कर दिया है। मेरी क्षमा याचना।
गैब्रिएल गार्सिया


0

मेरे लिए सबसे अच्छा तरीका है कि इनरएचटीएमएल के माध्यम से नई एचटीएमएल सामग्री डालें और फिर उपयोग करें

setTimeout(() => {
        var script_el = document.createElement("script")
        script_el.src = 'script-to-add.js'
        document.body.appendChild(script_el)
    }, 500)

सेटटाइमआउट की आवश्यकता नहीं है, लेकिन यह बेहतर काम करता है। इसने मेरे लिए काम किया।


-1

आंतरिक HTML से एक्ज़िक्यूट (जावा स्क्रिप्ट) टैग

अपने स्क्रिप्ट तत्व को div में एक क्लास एट्रिब्यूट क्लास = "जावास्क्रिप्ट" के साथ बदलें और इसे बंद करें </div>

उस सामग्री को न बदलें जिसे आप निष्पादित करना चाहते हैं (पहले यह स्क्रिप्ट टैग में था और अब यह div टैग में है)

अपने पृष्ठ में एक शैली जोड़ें ...

<style type="text/css"> .javascript { display: none; } </style>

अब jquery (Jquery js को पहले से ही शामिल किया जाना चाहिए) का उपयोग करके निष्कासन चलाएं

   $('.javascript').each(function() {
      eval($(this).text());

    });`

आप मेरे ब्लॉग पर यहाँ और खोज कर सकते हैं ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.