• [转]被玩坏的innerHTML、innerText、textContent和value属性


    一、前言                              

      由于innerText并非W3C标准属性,因此我们无法在FireFox中使用它,一般情况下我们可以使用textContent来代替,但它两者是否就能完全等同呢?在坑爹的表单元素(如input、textarea等)中表现是否依旧诡异呢?文本将记录一些实验结果,避免日后被玩坏。

    二、innerHTML                          

      由于innerText和textContent均为对innerHTML内容作不同的处理而成,因此我们需要先明确innerHTML属性的特点。

      赋值操作:先对值内容进行模式匹配,然后把处理后的值赋予给innerHTML属性。

            模式匹配结果将导致 保留将字符转换为HTML实体 两个操作。

            a). 以下情况将被保留

                 1. HTML实体(ASCII实体、符号实体和字符实体)的实体名或实体编号;

                 2. 符号实体和字符实体对应的字符;

                 3. 没有HTML实体与之对应的字符。

            b). 以下情况将会执行字符转换为HTML实体

                  1. ASCII实体对应的字符(<、>、&、'和")。

            也就是说除了 <、>、&、'和" 会被转换为实体名外,将原封不动地将值赋予给innerHTML属性。

      取值操作:直接获取innerHTML属性值。

      后面的innerText和textContent内容将以下面的HTML Markup作为实验原材料

    <style type="text/css">
     .line3, .line4{
       float: left;
     }
     .line5::after{
       content: "test"
     }
    </style>
    <div id="view">
      <div>line1</div>
      <div>line2</div><br/>
      <div class="line3">line3</div>
      <div class="line4">line4</div>
      <div style="clear:both;"></div>
      <div class="line5">line5</div>
    </div>
    <script type="text/javascript">
      var view = document.getElementById('view')
    </script>

      

    二、innerText                         

      浏览器支持:IE、Chrome

      赋值操作:先将ASCII实体对应的字符(<、>、&、'和")转换为实体名,然后把处理后的值赋予给innerHTML属性。

      取值操作:innerText的取值实际上就是对innerHTML的属性值进行一系列处理,然后返回,具体步骤如下

             1. 对HTML标签进行解析;

             2. 对CSS样式进行带限制的解析和渲染;

             3. 将ASCII实体转换为对应的字符;

             4. 剔除格式信息(如 、 和 等),将多个连续的空格合并为一个。

      IE各版本和Chrome下对innerText进行取值均执行上述4步,但效果不尽相同。实验结果如下:

      IE5.5~8

         页面显示效果:

    line1
    line2
    
    line3line4
    line5

        innerText取值结果:

    "line1
    line2
    
    line3line4line5"

       不全面的小结:在进行CSS样式渲染时,不支持伪元素和clear:both。

      IE9~11

         页面显示效果:

    line1
    line2
    
    line3line4
    line5test

         innerText取值结果:

    "line1
    
    line2
    
    
    line3
    
    line4
    
    
    
    line5"

       不全面的小结:在进行CSS样式渲染时,只会应用元素的默认样式。

      Chrome

         页面显示效果:

    line1
    line2
    
    line3line4
    line5test

         innerText取值结果:

    "line1
    line2
    
    line3line4
    line5"

       不全面的小结:在进行CSS样式渲染时,不支持伪元素。

    三、textContent                        

      浏览器支持:IE9~11、FireForx、Chrome

      赋值操作:先将ASCII实体对应的字符(<、>、&、'和")转换为实体名,然后把处理后的值赋予给innerHTML属性。

      取值操作:textContent的取值实际上就是对innerHTML的属性值进行一系列处理,然后返回,具体步骤如下

            1. 对HTML标签进行剔除;

            2. 将ASCII实体转换为相应的字符。

           注意:

                a). 对HTML标签是剔除不是解析,也不会出现CSS解析和渲染的处理,因此<br/>等元素是不生效的。

                b). 不会剔除格式信息和合并连续的空格,因此 、 、 和连续的空格将生效。

      所有浏览器效果统一,界面效果:

    line1
    line2
    
    line3line4
    line5test

      textContent取值结果:

    "
      line1
      line2
      line3
      line4
    
      line5
    "

    四、表单元素中的innerHTML、innerText、textContent和value  

       到这里大家应该对innerHTML、innerText和textContent之间的关系和行为有一定了解了,但不幸的是表单元素一如既往地会推翻我们之前的理解。请注意的是上述的关系和行为仅限于非表单元素,而本节将介绍表单元素textarea和input[type="text"]相关的蛋疼……

       前置信息: textarea和input[type="text"]的value属性与界面输入框是对应的,通过value属性赋值与在界面输入框输入值属于同一个操作。

      textarea

         FireFox

           a). innerHTML可被设置并且生效,对其他属性的影响:

                1. 无条件影响textContent的取值;

                2. 在通过value属性赋值前,会影响value的取值;

                3. 在通过value属性赋值后,则value的取值与innerHTML无关。

           b). textContent可被设置且生效,对其他属性的影响:

         1. 无条件影响innerHTML的取值; 

         2. 在通过value属性赋值前,会影响value的取值;

                3. 在通过value属性赋值后,则value的取值与textContent无关。

           c). value可被设置且生效。

        Chrome

       a). innerHTML可被设置并且生效,对其他属性的影响:

                1. 无条件影响innerText、textContent的取值;

                2. 在通过value属性赋值前,会影响value的取值;

                3. 在通过value属性赋值后,则value的取值与innerHTML无关。

       b). innerText可被设置并且生效,对其他属性的影响:

                1. 无条件影响innerHTML、textContent的取值;

                2. 在通过value属性赋值前,会影响value的取值;

                3. 在通过value属性赋值后,则value的取值与innerText无关。

           c). textContent可被设置且生效,对其他属性的影响:

         1. 无条件影响innerHTML、innerText的取值; 

         2. 在通过value属性赋值前,会影响value的取值;

                3. 在通过value属性赋值后,则value的取值与textContent无关。

           d). value可被设置且生效。

        IE9~11

      innerHTML、value、innerText和textContent均可设置且有效,无条件相互影响取值。

        IE5.5~8

         innerHTML、value、innerText和textContent均可设置且有效,无条件相互影响取值。

      input[type="text"]

        FireFox

      a). innerHTML可被设置且生效,无条件影响innerText和textContent的取值,但不会影响value的取值。

          b). textContent可被设置且生效,无条件影响innerHTML的取值,但不会影响value的取值。

      c). value可被设置且生效,不会影响innerHTML和textContent的取值。

        Chrome   

      a). innerHTML可被设置但无效,属性值永远保持空字符串。

      b). textContent可被设置且生效,但不会影响value、innerHTML和innerText的取值。

      c). innerText可被设置,但实际设置时会抛异常

    <input type="text" id="target">
    <script type="text/javascript">
      var getDesc = function(){ return Object.getOwnPropertyDescriptor.apply(Object, arguments) }
        , get = function(){ return document.getElementById.apply(docuemnt, arguments) }
      var target = get('target');
      console.log(getDesc(target, 'innerText'))   // Object {value: "", writable: true, enumerable: true, configurable: true}
      target.innerText = "1" // NoModificationAllowedError: Failed to set the 'innerText' property on 'HTMLElement': The 'input' element does not support text insertion.
    </script>
    
    
    

      d). value可被设置且生效,但不会影响textContent、innerHTML和innerText的取值。

       IE5.5~8

          a). innerHTML可被设置,但实际设置时会抛异常

    <input type="text" id="target">
    <script type="text/javascript">
      var getDesc = function(){ return Object.getOwnPropertyDescriptor.apply(Object, arguments) }
        , get = function(){ return document.getElementById.apply(docuemnt, arguments) }
      var target = get('target');
      console.log(getDesc(target, 'innerHTML'))   // Object {value: "", writable: true, enumerable: true, configurable: true}
      target.innerText = "1" // 未知的运行时错误
    </script>
    

         b). innerText可被设置且有效,无条件影响value取值。但innerText的取值永远是空字符串。

         c). value可被设置且生效,但不会影响innerHTML和innerText的取值。

     IE9~11

       a). innerHTML可被设置且生效,无条件影响innerText和textContent的取值。但不影响value的取值。

         b). innerText可被设置且生效,无条件影响value取值。但不影响innerHTML和textContent。innerText的取值由innerHTML的属性值经过处理后返回。

    // 假设a是input[type="text"]
    a.innerHTML = "<"
    a.innerText = "test"
    console.log(a.innerHTML) // <
    console.log(a.value) // test
    console.log(a.innerHTML) // <
    

         c). textContent可被设置且生效,无条件影响innerHTML和innerText的取值,textContent的取值由innerHTML的属性值经过处理后返回。

         d). value可被设置且生效,但不会影响innerHTML、textContent和innerText的取值。

    五、HTML编码                         

      所谓HTML编码其实就是将字符转换为HTML实体,这是防止脚本注入的重要手段之一。

      由于表单元素的value与innerHTML关系在不同浏览器上表现各不相同,因此最保险的方式还是

    ;(function(exports, doc){
      var dom = doc.createElement('textarea')
      
      exports.encode = function(raw){
        dom.innerHTML = raw
        return dom.innerHTML
      }
      exports.decode = function(str){
        dom.innerHTML = str
        return dom['innerText' in dom ? 'innerText' : 'textContent']
      }
    }(window.htmlEncoder = {}, document))
    

    六、总结                            

      本文若有纰漏请大家指正补充,谢谢!

      尊重原创,转载请注明来自:http://www.cnblogs.com/fsjohnhuang/p/4319635.html ^_^肥仔John

  • 相关阅读:
    devise 异步发邮件
    ubuntutweak for lucid
    960gs blueprint
    Amoeba for mysql 0.31发布(读写分离、负载均衡、Failover、数据切分)
    Google App Servlet容器转型 – 从Tomcat到Jetty
    DBeaver
    用simple from暂不用formtastic
    [SQL Server]ORDER BY的问题
    PHP pathinfo() 函数
    php中使用head进行二进制流输出,让用户下载PDF等附件的方法
  • 原文地址:https://www.cnblogs.com/rubylouvre/p/4321442.html
Copyright © 2020-2023  润新知