Javascript 在IE和Edge中,在子窗口上调用adoptNode和importNode失败
调查结果和支持信息 感谢用户4749485在下面的评论中指出了一个错误。正如制作它的人所指出的,这似乎是由MS在将HtmleElement从另一个窗口传递到函数之前将其转换为普通对象引起的,如图所示。我把原始版本放远了一点,并在iframe上对其进行了测试,并添加了相同来源的测试Javascript 在IE和Edge中,在子窗口上调用adoptNode和importNode失败,javascript,jquery,internet-explorer,microsoft-edge,Javascript,Jquery,Internet Explorer,Microsoft Edge,调查结果和支持信息 感谢用户4749485在下面的评论中指出了一个错误。正如制作它的人所指出的,这似乎是由MS在将HtmleElement从另一个窗口传递到函数之前将其转换为普通对象引起的,如图所示。我把原始版本放远了一点,并在iframe上对其进行了测试,并添加了相同来源的测试 修改源代码以获取文档上下文。它进一步证实了IE将任何节点从外部窗口转换为普通对象,然后再将其传递给函数的怀疑。我已经更新了CustomImportNode的新测试 添加了CustomImportNode2的另一个测试
修改源代码以获取文档上下文。它进一步证实了IE将任何节点从外部窗口转换为普通对象,然后再将其传递给函数的怀疑。我已经更新了CustomImportNode的新测试 添加了CustomImportNode2的另一个测试,它将自定义导入节点函数放在目标文档上。它确实克隆了元素,但没有保留事件。看来我要做个特殊的案子了
另一个几乎有效。打开窗口,复制内容,并在$compile上失败。我认为这是因为它试图为ngInlcude使用import或adopt节点
问题 我正在尝试将元素从当前窗口移动到页面打开的新窗口。以下方法适用于除IE和Edge之外的所有浏览器。Edge抛出一个
不支持的此类接口
错误,IE抛出一个通用错误。
声明问题在于它试图从一个文档片段添加多个元素。然而,在下面的测试代码中,我只添加了一个元素,但仍然失败。有趣的是,它在调用importNode
和adoptNode
时也会失败。是否存在保留附加数据和侦听器的解决方法
<!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>
测试
按html()编写
按克隆()
直接附加
adoptNode()
importNode()
函数byHtml(){
var nwin=window.open('about:blank','','');
//可以工作,但会丢失所有绑定的侦听器
$(nwin.document.body).append($('#test').html());
}
函数byClone(){
var nwin=window.open('about:blank','','');
//在Edge和IE中失败
$(nwin.document.body).append($('#test').clone());
}
函数byDirect(){
var nwin=window.open('about:blank','','');
var节点=document.getElementById('test');
//在Edge和IE中失败
nwin.document.body.appendChild(节点);
}
函数byAdoptNode(){
var nwin=window.open('about:blank','','');
//应用节点上的IE和边缘故障
var node=nwin.document.adoptNode(document.getElementById('test');
nwin.document.body.appendChild(节点);
}
函数byImportNode(){
var nwin=window.open('about:blank','','');
//IE和Edge在导入节点上失败
var node=nwin.document.importNode(document.getElementById('test'),true);
nwin.document.body.appendChild(节点);
}
编辑
我试过表中列出的项目。他们不能解决问题
- 正在从服务器提供该页面
- 我已经用一个空白字符串和一个指向同一服务器上一个可视空白HTML页面的URL替换了
。两人都没有解决问题about:blank
- IE总是处于标准模式。adoptNode和importNode从未定义过。他们抛出了“不支持这样的接口”错误
通过以上编辑注意:Plunker在IE 11中给我的错误与在我的服务器上运行的代码不同。Plunker抛出一个不支持的方法错误。
Edge仍然抛出
无此接口支持的错误
解决方案不太好。您需要编译它,获取HTML内容,删除所有出现的ngInclude,将其包装在一个DIV中,将HTML字符串附加到新窗口中,然后再次编译它
Plnkr:
$scope.window=window.open(“”,“”);
var windowScope=$scope.$new();
var body=angular.element($scope.window.document.body);
var contents=$compile($element.contents())(WindowsScope);
setTimeout(函数(){
//这个部门是需要的
// http://stackoverflow.com/a/38599093/631295
body.append(“”+$element.html().replace(/ng include=“[^”]+”/g,”)+“”);
windowScope.$destroy();
WindowsScope=$scope.$new();
$compile(body)(windowScope);
}, 1000);
解决方案不太好。您需要编译它,获取HTML内容,删除所有出现的ngInclude,将其包装在一个DIV中,将HTML字符串附加到新窗口中,然后再次编译
Plnkr:
$scope.window=window.open(“”,“”);
var windowScope=$scope.$new();
var body=angular.element($scope.window.document.body);
var contents=$compile($element.contents())(WindowsScope);
setTimeout(函数(){
//这个部门是需要的
// http://stackoverflow.com/a/38599093/631295
body.append(“”+$element.html().replace(/ng include=“[^”]+”/g,”)+“”);
windowScope.$destroy();
WindowsScope=$scope.$new();
$compile(body)(windowScope);
}, 1000);
自IE 9以来一直受支持。(与adoptNode的主要区别是克隆原始节点,因此如果要将其从原始文档中删除,则必须在以后明确地执行此操作。)对。但是,IE和Edge在importNode
和adoptNode
上抛出错误。错误是不支持此类接口
可能是“about:blank”导致了您的问题,因为它与当前文档不在同一域中。请尝试指定服务器上空白HTML文件的url。问题的根源可能是ms浏览器在弹出窗口中隐藏了HTMLImageElement标记,而只是给出了[object]。因此importNode/adoptNode拒绝“
$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);