• 跨文档的节点操作时,抛异常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="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等字符串操作,变相实现节点的剪切。

  • 相关阅读:
    BIND简易教程(2):BIND视图配置
    BIND简易教程(1):安装及基本配置
    大学本科计算机专业应该学点什么?
    Bukkit之yaml动态读取
    将指定世界中的指定位置的Block转化为箱子
    iframe中父页面与子页面的传值方法
    ajax提交数据
    a标签响应onclick事件,并且不执行href动作
    jsp重新打开一个新的页面
    java.lang.NoClassDefFoundError: org/hibernate/QueryTimeoutException
  • 原文地址:https://www.cnblogs.com/withasi/p/crossdom.html
Copyright © 2020-2023  润新知