2013-03-22 57 views
4

我正在嘗試將腳本塊動態添加到文檔。當我這樣做時,腳本塊沒有被執行。將腳本元素動態添加到div不會執行腳本

<body> 
    <div id="dynamicDiv"> 
    </div> 

    <script type="text/javascript"> 
     var elem = document.getElementById("dynamicDiv"); 
     var tmpStr = "<script type=\"text\/javascript\"> "; 
     tmpStr += "function hello (val)"; 
     tmpStr += "{"; 
     tmpStr += "alert('hello ' + val);"; 
     tmpStr += "}"; 
     tmpStr += "<\/script>"; 

     elem.innerHTML = tmpStr; 

     hello("World"); 
    </script> 
</body> 

上述代碼無效。在另一篇文章(How do you execute a dynamically loaded JavaScript block?)中,我看到了一個回覆,如果腳本被添加到innerHTML,它將不會被執行。不是直接使用innerHTML,而是使用innerHTML創建一個div,並使用appendChild添加腳本。

<body> 
    <div id="dynamicDiv"> 
    </div> 

    <script type="text/javascript"> 
     var elem = document.getElementById("dynamicDiv"); 
     var tmpStr = "<script type=\"text\/javascript\"> "; 
     tmpStr += "function hello (val)"; 
     tmpStr += "{"; 
     tmpStr += "alert('hello ' + val);"; 
     tmpStr += "}"; 
     tmpStr += "<\/script>"; 

     var newdiv = document.createElement('div'); 
     newdiv.innerHTML = tmpStr; 

     elem.appendChild(newdiv); 

     hello("World"); 
    </script> 
</body> 

如何,這個解決方案也沒有爲我工作。

在另一個回覆中,我再次看到我們應該獲取腳本元素並使用eval執行它們。

<body> 
    <div id="dynamicDiv"> 
    </div> 

    <script type="text/javascript"> 
     var elem = document.getElementById("dynamicDiv"); 
     var tmpStr = "<script type=\"text\/javascript\"> "; 
     tmpStr += "function hello (val)"; 
     tmpStr += "{"; 
     tmpStr += "alert('hello ' + val);"; 
     tmpStr += "}"; 
     tmpStr += "<\/script>"; 

     var newdiv = document.createElement('div'); 
     newdiv.innerHTML = tmpStr; 

     elem.appendChild(newdiv); 

     var scripts = newdiv.getElementsByTagName('script'); 
     for (var ix = 0; ix < scripts.length; ix++) { 
      eval(scripts[ix].text); 
     } 

     hello("World"); 
    </script> 
</body> 

此解決方案適用於我。

但是,如果在一個函數中這樣做,那麼它不起作用。

<body> 
    <div id="dynamicDiv"> 
    </div> 

    <script type="text/javascript"> 

     function createFunction(){ 
      var elem = document.getElementById("dynamicDiv"); 
      var tmpStr = "<script type=\"text\/javascript\"> "; 
      tmpStr += "function hello (val)"; 
      tmpStr += "{"; 
      tmpStr += "alert('hello ' + val);"; 
      tmpStr += "}"; 
      tmpStr += "<\/script>"; 

      var newdiv = document.createElement('div'); 
      newdiv.innerHTML = tmpStr; 

      elem.appendChild(newdiv); 

      var scripts = newdiv.getElementsByTagName('script'); 
      for (var ix = 0; ix < scripts.length; ix++) { 
       eval(scripts[ix].text); 
      } 
      hello("World 1"); 
     } 

     createFunction(); 
     hello("World 2"); 
    </script> 
</body> 

我可以看到該函數在腳本被撤銷後可用。並在函數createFunction中可用。在createFunction()作用域之外,hello()不可用。

我在做什麼錯?我錯過了一些非常基本的東西?請檢查並提供幫助。

感謝, 保羅

附:我不使用jQuery。 我正在使用chrome來測試這個。

+0

您不能在函數內動態添加腳本.. – 2013-03-22 09:57:29

+0

我在'firefox'中測試了您的第一個代碼,它正在工作。 – 2013-03-22 09:58:02

+0

@RohanKumar第三個代碼片段也適用於我的Chrome和Firefox。但是第四個片段在兩者中都不起作用。第四個片段應該提醒2次。 「你好世界1」和「你好世界2」。不知何故,hello函數不能在createFunction()作用域之外訪問。 – 2013-03-22 11:12:03

回答

0

在第一次嘗試中,您創建了一個字符串,而js解釋器將其作爲字符串處理,而不是html標記,因此js並不在意您呈現在該字符串中的腳本標記。

然後,當然,當你開始使用eval(),因爲EVAL它的工作 - 是邪惡的:))

畢竟,你可以動態創建腳本標記,然後用代碼填充它:

var elem = document.getElementById("dynamicDiv"), 
    scriptTag = document.createElement('script'), 
    scriptTagCode = 'function hello (val){alert("hello " + val);}'; 

scriptTag.innerHTML = scriptTagCode; 
elem.appendChild(scriptTag); 
hello('foo'); 
2

想指出你提供的第三個代碼片段在for循環中工作的原因,但不是外部的原因是因爲你使用的是evaleval需要一個字符串並將其作爲js執行,這就是爲什麼它在循環內部工作的原因,但使用eval不會解析它以備將來使用,這會導致它在其他地方無法使用。因此,當您在循環外調用它時,會出現參考錯誤。

UPDATE:

如果你所得到的字符串返回在它的<script>標籤,你可以解析出的腳本標記。

var string = "<script type=\"text\/javascript\"> "; 
    string += "function hello (val)"; 
    string += "{"; 
    string += "alert('hello ' + val);"; 
    string += "}"; 
    string += "<\/script>"; 
string = string.replace(/<(script|\/script).*?>/g,''); 
function createFunction() { 
    var elem = document.getElementById("dynamicDiv"); 
    var script = document.createElement('script'); 
    script.innerHTML = string; 
    elem.appendChild(script); 
    hello("World 1"); 
} 
createFunction() 
hello('world 2'); 

的jsfiddle:http://jsfiddle.net/3wYD6/

我實在不明白這一點,但如果你真的想這樣做,你可以創建一個新的腳本元素,然後將其設置的innerHTML的功能,然後將新腳本附加到div。

var elem = document.getElementById("dynamicDiv"), 
    script = document.createElement('script'); 
script.innerHTML = 
    'function hello (val) {' + 
     'alert("hello " + val);' + 
    '}'; 
elem.appendChild(script); 
hello('world'); 
+0

這個測試案例工作正常。 但在我的情況下,我會從外部文件中獲取tempStr。 tempStr將包含腳本和pcData。如果我需要使用上面的soln,那麼我需要解析給我的字符串以找到pcData和腳本塊。普通pcData,我可以添加到innerHTML和腳本,我需要創建腳本元素 是否有一種簡單的方法比解析tempStr?工作中的第三個代碼片段對我來說很好。在這種方法中,我不需要解析pcData和腳本塊的tempString。但是當我把它變成一個func時(就像在第四段中)它停止工作。 – 2013-03-22 11:08:09

+0

我正在更新答案。 – 2013-03-22 12:20:35

+0

感謝Jeff提供了最新的答案。如果我的tmpStr是類似的東西。 \t \t \t \t var tmpStr =「我是一個pcdata,我不應該添加爲腳本。」; \t \t \t \t tmpStr + =「

  • 11. 動態添加AngularJS腳本
  • 12. 如何將加載的腳本應用到動態添加的元素?
  • 13. 將元素動態添加到div不會被解析
  • 14. TFS將不會執行NuGet腳本
  • 15. crontab將不會執行腳本
  • 16. 腳本不執行動態生成的JQuery腳本標記
  • 17. Crontab將不會執行我手動執行的腳本
  • 18. 動態添加選項到腳本
  • 19. jQuery腳本不會添加活動類
  • 20. 該腳本將不執行
  • 21. 刪除動態添加腳本動態
  • 22. 在div裏面寫執行腳本時在div動態加載到頁面
  • 23. ExtJs自動加載腳本不執行
  • 24. 將腳本添加到LaunchScreen.storyboard?
  • 25. 動態添加輸入元素沒有在腳本
  • 26. 如何在Blackberry瀏覽器上動態添加腳本元素?
  • 27. Google Apps腳本 - 動態添加刪除UiApp表單元素
  • 28. 的Java腳本動態網格HTML視頻添加元素
  • 29. 將動畫添加到此jQuery腳本
  • 30. 如何在執行腳本元素之前刪除腳本元素?