跨文档的节点操作时,抛异常WRONG_DOCUMENT_ERR: DOM Exception 4

1)问题描述:

  在Android自带浏览器中,如果出现跨文档的节点操作时(这里的操作指剪切节点),抛异常——WRONG_DOCUMENT_ERR: DOM Exception 4

 

  例如对一个元素进行inserBefore、appendChild操作,其参数子节点来自其他文档。

2)测试如下:

  crossdom.html页面中引入了一个同源的test.html,当点击按钮时,会将test.html中的div1从test.html中剪切到当前页面crossdom.html中

  2-1)crossdom.html中如下:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
 <HEAD>
  <meta http-equiv="Content-Type" content="text/html;charset=gbk">
  <TITLE> 跨文档appendChild操作 </TITLE>
  <script type="text/javascript">
    function crossDom(){
        var ifr = document.getElementById('ifr'); 
        var doc = document.all ? ifr.Document : ifr.contentDocument;
        document.body.appendChild(doc.getElementById('div1'));
    }
  </script>
 </HEAD>
 <BODY>
    <fieldset style='float:left;border:solid #000 2px;padding:5px;'>
        <legend>test page 中的内容:</legend>
        <iframe id='ifr' src='test.html'></iframe>
    </fieldset>
  <button style='margin-top:200px' onclick='crossDom()'>将test page中你的div剪切到本文档中</button>
 </BODY>
</HTML>

  2-2)test.html中内容如下:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
 <HEAD>
  <meta http-equiv="Content-Type" content="text/html;charset=gbk">
  <TITLE> test page </TITLE>
 </HEAD>
 <BODY>
    <div id="div1" style="width:100px;height:100px;background-color:green;">test page
    </div>
 </BODY>
</HTML>

 

3)测试结果:

  3-1)pc端:包括ie6+、chrome和firefox最新更新版本等,均没有抛错,能正常实现跨文档剪切。

  3-2)移动端:Android自带浏览器中,2.3及其以下版本进行测试。无法剪切,抛异常——WRONG_DOCUMENT_ERR: DOM Exception 4

 

   W3C DomException中已经定义了WRONG_DOCUMENT_ERR的含义,并且描述了跨文档节点操作会抛此异常,可参照下此处关于WRONG_DOCUMENT_ERR的定义:http://reference.sitepoint.com/javascript/DOMException

   但是经过一轮测试发现,除了android自带浏览器遵循此规范,抛此错误,其它的均不会,包括Android下的第三方浏览器uc8.7竟然也没错(其它一些杂七杂八的android第三方浏览器没有测试)。

    

4)实现Android自带浏览器下的跨文档的节点操作:

   其实就是在剪切前,对节点进行复制。

  可通过document.importNode(http://reference.sitepoint.com/javascript/Document/importNode,ie不支持importNode)或者cloneNode接口,复制节点后再进行appendChild操作即可。

例如将crossdom.html改成如下即可:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
 <HEAD>
  <meta http-equiv="Content-Type" content="text/html;charset=gbk">
  <TITLE> 跨文档appendChild操作 </TITLE>
  <script type="text/javascript">
    function crossDom(){
        var ifr = document.getElementById('ifr'); 
        var doc = document.all ? ifr.Document : ifr.contentDocument;
     var div1 =
doc.getElementById('div1');
      document.body.appendChild(div1.cloneNode());      
    
//或者如下:     
     //
document.body.appendChild(docuemnt.importNode(doc.getElementById('div1')));
      div1.parentNode.removeChild(div1);
    }
  </script>
 </HEAD>
 <BODY>
    <fieldset style='float:left;border:solid #000 2px;padding:5px;'>
        <legend>test page 中的内容:</legend>
        <iframe id='ifr' src='test.html'></iframe>
    </fieldset>
  <button style='margin-top:200px' onclick='crossDom()'>将test page中你的div剪切到本文档中</button>
 </BODY>
</HTML>

 

  

ps:

   个人猜测Android自带浏览器在理解W3C DomException中的WRONG_DOCUMENT_ERR也许有偏差。因为跨文档剪切看似阻止了文档间dom直接操作,但是仅仅通过一个复制就突破了。而且只要dom文档间能访问,就可通过innerHTML等字符串操作,变相实现节点的剪切。

 

 

posted @ 2012-10-09 19:34  @si  阅读(3066)  评论(0编辑  收藏  举报