2016-08-01 75 views
1

發現和支持信息子窗口上調用adoptNode和importNode無法在IE和邊緣

感謝user4749485您指出在下面的評論一個link I missed。正如創建它的人所指出的,看起來這是由MS將HTMLElement轉換爲普通對象所引起的,然後將其從另一個窗口傳遞給函數,如演示here所示。我把原版稍微加了一點,並在iframe上進行了測試,並添加了相同原點的測試。


將代碼從this answer修改爲採取文檔上下文。它進一步證實了IE在將它們傳遞給函數之前將外部窗口中的任何節點轉換爲普通對象的懷疑。我已經更新了this Plunkr以及由ConsustImportNode進行的新測試。

CustomImportNode2增加了另一個測試,它將自定義導入節點功能放在目標文檔上。它確實對元素進行了克隆,但事件並未保留。出現我只是要做一個特例。


另外example using angular幾乎可以工作。打開窗口,複製內容,並在$ compile上失敗。我認爲這是因爲它試圖使用導入或採用ngInlcude節點。


問題

我試圖從移動當前窗口到頁面打開一個新的窗口元素。下面的方法適用於除IE和Edge之外的所有瀏覽器。 Edge會拋出一個No such interface supported錯誤,IE會拋出一個通用錯誤。 This post指出問題在於它試圖從文檔片段中添加多個元素。但是,在我的測試代碼中,我只添加了一個元素,但仍然失敗。有趣的是,它也在importNodeadoptNode調用中失敗。是否有任何解決方法可以保留附加的數據和偵聽器?

<!doctype html> 
<html> 
    <head> 
     <script src="https://code.jquery.com/jquery-1.10.2.js"></script> 
    <head> 
    <body> 
    <div id="test">test</div> 
    <button onclick="byHtml()">by html()</button> 
    <button onclick="byClone()">by clone()</button> 
    <button onclick="byDirect()">direct append</button> 
    <button onclick="byAdoptNode()">adoptNode()</button> 
    <button onclick="byImportNode()">importNode()</button> 
    <script> 
     function byHtml(){ 
      var nwin= window.open('about:blank','',''); 
      // Works but loses any bound listeners 
      $(nwin.document.body).append($('#test').html()); 
     } 
     function byClone(){ 
      var nwin= window.open('about:blank','',''); 
      // Fails in Edge and IE 
      $(nwin.document.body).append($('#test').clone()); 
     } 
     function byDirect(){ 
      var nwin= window.open('about:blank','',''); 
      var node= document.getElementById('test'); 
      // Fails in Edge and IE 
      nwin.document.body.appendChild(node); 
     } 
     function byAdoptNode(){ 
      var nwin= window.open('about:blank','',''); 
      // IE and Edge fail on the adoptNode 
      var node= nwin.document.adoptNode(document.getElementById('test')); 
      nwin.document.body.appendChild(node); 
     } 
     function byImportNode(){ 
      var nwin= window.open('about:blank','',''); 
      // IE and Edge fail on the importNode 
      var node= nwin.document.importNode(document.getElementById('test'), true); 
      nwin.document.body.appendChild(node); 
     } 
    </script> 
    </body> 
</html> 

編輯

我曾嘗試在this post列出的項目。他們不解決問題。

  • 頁面正從服務器提供。
  • 我已將about:blank替換爲空白字符串和網址到同一服務器上視覺上空白的HTML頁面。沒有解決這個問題。
  • IE始終處於標準模式。採用節點和導入節點從未定義。他們拋出「沒有這樣的接口支持」的錯誤。

編輯2
Plunker test與上述編輯。 注意: Plunker在IE 11中給出了與我的服務器上運行的代碼不同的錯誤。 Plunker拋出一個不支持的方法錯誤。
邊緣仍然拋出No such interface supported error

+0

[importNode](https://developer.mozilla.org/en-US/docs/Web/API/Document/importNode)被支撐因爲IE 9.(主要區別採用節點就是克隆原始節點,所以如果你想從原始文檔中刪除它,你必須明確地做到這一點。) – CBroe

+0

對。但是,IE和Edge在'importNode'和'adoptNode'上引發錯誤。錯誤是'沒有這樣的接口支持' – Knyri

+1

它可能是「關於:空白」,這是造成你的問題,因爲它不在你的當前文檔相同的域。嘗試將URL指定給服務器上的空白HTML文件。 –

回答

0

該解決方案並不漂亮。您需要編譯它,獲取HTML內容,刪除所有出現的ngInclude,將其包裝在DIV中,將HTML字符串附加到新窗口並重新編譯。

Plnkr:http://plnkr.co/edit/aGpN3LHllU2ReHp1zG26?p=preview

$scope.window= window.open('', '', ''); 
var windowScope= $scope.$new(); 
var body= angular.element($scope.window.document.body); 
var contents= $compile($element.contents())(windowScope); 
setTimeout(function(){ 
    // The div is needed 
    // http://stackoverflow.com/a/38599093/631295 
    body.append('<div>'+$element.html().replace(/ng-include="[^"]+"/g,'')+'</div>'); 
    windowScope.$destroy(); 
    windowScope= $scope.$new(); 
    $compile(body)(windowScope); 
}, 1000);