'innerText'适用于IE,但不适用于Firefox

时间:2009-08-31 21:17:45

标签: javascript internet-explorer firefox cross-browser

我有一些在IE中有效的JavaScript代码,包含以下内容:

myElement.innerText = "foo";

然而,似乎'innerText'属性在Firefox中不起作用。是否有一些Firefox等价?或者是否有可以使用的更通用的跨浏览器属性?

15 个答案:

答案 0 :(得分:277)

更新:我写了blog post detailing all the differences好多了。


Firefox使用W3C标准Node::textContent,但其行为与MSHTML的专有innerText略有不同(由Opera复制,前段时间,还有许多其他MSHTML功能)。< / p>

首先,textContent空格表示与innerText空格表示不同。其次,更重要的是,textContent 包含所有SCRIPT标记内容,而innerText则不包含。

为了让事情变得更有趣,Opera除了实施标准textContent之外 - 还决定添加MSHTML的innerText ,但将其更改为textContent - 即包括SCRIPT内容(事实上,Opera中的textContentinnerText似乎产生相同的结果,可能只是彼此别名。)

textContentNode界面的一部分,而innerTextHTMLElement的一部分。例如,这意味着您可以从文本节点“检索”textContent而不是innerText

var el = document.createElement('p');
var textNode = document.createTextNode('x');

el.textContent; // ""
el.innerText; // ""

textNode.textContent; // "x"
textNode.innerText; // undefined

最后,Safari 2.x也有bug innerText实现。在Safari中,innerText仅在元素有效时才能正常运行 既没有隐藏(通过style.display == "none")也没有隐藏在文档中。否则,innerText会产生一个空字符串。

我正在玩textContent抽象(以解决这些缺陷),但事实证明是rather complex

您最好的选择是首先确定您的确切要求并从那里开始。通常可以简单地从元素的innerHTML剥离标记,而不是处理所有可能的textContent / innerText偏差。

当然,另一种可能性是遍历DOM树并递归收集文本节点。

答案 1 :(得分:247)

Firefox使用W3C-compliant textContent属性。

我猜Safari和Opera也支持这个属性。

答案 2 :(得分:81)

如果您只需要设置文本内容而不需要检索,这里有一个可以在任何浏览器上使用的简单DOM版本;它不需要IE innerText扩展或DOM Level 3 Core textContent属性。

function setTextContent(element, text) {
    while (element.firstChild!==null)
        element.removeChild(element.firstChild); // remove all existing content
    element.appendChild(document.createTextNode(text));
}

答案 3 :(得分:25)

jQuery提供了一种.text()方法,可以在任何浏览器中使用。例如:

$('#myElement').text("Foo");

答案 4 :(得分:21)

根据Prakash K的回答,Firefox不支持innerText属性。因此,您只需测试用户代理是否支持此属性,并按以下步骤进行相应操作:

function changeText(elem, changeVal) {
    if (typeof elem.textContent !== "undefined") {
        elem.textContent = changeVal;
    } else {
        elem.innerText = changeVal;
    }
}

答案 5 :(得分:13)

一个非常简单的Javascript系列可以在所有主浏览器中获得“非标记”文本......

var myElement = document.getElementById('anyElementId');
var myText = (myElement.innerText || myElement.textContent);

答案 6 :(得分:5)

请注意,Element::innerText属性包含Google Chrome中CSS样式“display:none”隐藏的文字(同时它会删除已被其他CSS技术掩盖(包括font-size:0,color:transparent,以及一些其他类似的效果,导致文本无法以任何可见的方式呈现)。

还考虑了其​​他CSS属性:

  • 首先解析内部元素的“display:”样式,以确定它是否分隔块内容(例如“display:block”,它是浏览器内置样式表中HTML块元素的默认值,并且其行为不是被你自己的CSS风格覆盖);如果是这样,将在innerText属性的值中插入换行符。 textContent属性不会发生这种情况。
  • 还将考虑生成内联内容的CSS属性:例如,生成内联换行符的内联元素<br \>也将生成innerText值的换行符。
  • “display:inline”样式在textContent或innerText中不会产生换行符。
  • “display:table”样式在表格和表格行之间生成换行符,但“display:table-cell”将生成制表符。
  • “position:absolute”属性(用于display:block或display:inline,无关紧要)也会导致插入换行符。
  • 某些浏览器还会在跨度之间包含单个空格分隔

但是Element::textContent仍将包含所有内部文本元素的内容,与所应用的CSS无关,即使它们是不可见的。并且textContent中不会生成额外的换行符或空格,只会忽略所有样式和内部元素的内联/块或定位类型。

使用鼠标选择的复制/粘贴操作将丢弃放在剪贴板中的纯文本格式的隐藏文本,因此它不会包含textContent中的所有内容,而只包含innerText内的所有内容{1}}(在上面的空格/换行符生成之后)。

Google Chrome随后都支持这两种属性,但其内容可能会有所不同。较旧的浏览器仍然包含在innetText中,就像textContent现在包含的一样(但是它们与当时生成的空格/换行相关的行为是不一致的)。

jQuery将使用添加到通过$()查询返回的已解析元素的“.text()”方法解决浏览器之间的这些不一致问题。在内部,它通过查看HTML DOM来解决困难,只使用“节点”级别。所以它会返回看起来更像标准textContent的内容。

需要注意的是,此jQuery方法不会插入由内容的子元素(如<br />)引起的屏幕上可见的任何额外空格或换行符。

如果您为可访问性设计了一些脚本,并且您的样式表被解析为非听觉呈现,例如用于与盲文阅读器通信的插件,则此工具应使用textContent,如果它必须包含添加的特定标点符号spans样式为“display:none”,通常包含在页面中(例如上标/下标),否则innerText将在盲文阅读器上非常混乱。

CSS技巧隐藏的文本现在通常被主要搜索引擎忽略(它们也将解析HTML页面的CSS,并且还将使用HTML / CSS解析器忽略背景上没有对比颜色的文本) DOM属性“innerText”与现代视觉浏览器完全一样(至少这个不可见内容不会被索引,所以隐藏文本不能用作强制在页面中包含一些关键字来检查其内容的技巧);但是这个隐藏文本将在结果页面中显示(如果页面仍然从索引中限定为要包含在结果中),则使用“textContent”属性而不是完整的HTML来去除额外的样式和脚本。

如果在这两个属性中的任何一个中分配一些纯文本,这将覆盖应用于它的内部标记和样式(只有指定的元素将保留其类型,属性和样式),因此这两个属性将包含相同的内容。但是,某些浏览器现在不再遵循对innerText的写入,并且只允许您覆盖textContent属性(在写入这些属性时不能插入HTML标记,因为HTML特殊字符将使用数字字符引用正确编码,从字面上看,如果您在分配innerHTMLinnerText后阅读textContent媒体资源。

答案 7 :(得分:5)

myElement.innerText = myElement.textContent = "foo";

编辑(感谢Mark Amery对下面的评论):只有在你不知道没有代码依赖于检查这些属性的存在时才会这样做,例如(例如){{3} }。但是如果你正在使用jQuery,你可能只是使用“text”函数并执行$('#myElement')。text('foo'),如其他一些答案所示。

答案 8 :(得分:4)

innerText已添加到Firefox中,应该可以在FF45版本中找到:https://bugzilla.mozilla.org/show_bug.cgi?id=264412

草稿规范已经编写,预计将来会纳入HTML生活标准:http://rocallahan.github.io/innerText-spec/https://github.com/whatwg/html/issues/465

请注意,目前Firefox,Chrome和IE实现都不兼容。展望未来,我们可能会期望Firefox,Chrome和Edge融合,而旧的IE仍然不兼容。

另请参阅:https://github.com/whatwg/compat/issues/5

答案 9 :(得分:1)

这样的事情怎么样?

//$elem is the jQuery object passed along.

var $currentText = $elem.context.firstChild.data.toUpperCase();

**我需要让我的大写。

答案 10 :(得分:1)

与2016年的Firefox v45一样,innerText适用于Firefox,请查看其支持:http://caniuse.com/#search=innerText

如果您希望它能够在以前版本的Firefox上运行,您可以使用textContent,它对Firefox有更好的支持,但在较旧的IE版本上更糟:http://caniuse.com/#search=textContent < / p>

答案 11 :(得分:0)

这是我使用innerTexttextContentinnerHTML和值的经验:

// elem.innerText = changeVal;  // works on ie but not on ff or ch
// elem.setAttribute("innerText", changeVal); // works on ie but not ff or ch
// elem.textContent = changeVal;  // works on ie but not ff or ch
// elem.setAttribute("textContent", changeVal);  // does not work on ie ff or ch
// elem.innerHTML = changeVal;  // ie causes error - doesn't work in ff or ch
// elem.setAttribute("innerHTML", changeVal); //ie causes error doesn't work in ff or ch
   elem.value = changeVal; // works in ie and ff -- see note 2 on ch
// elem.setAttribute("value", changeVal); // ie works; see note 1 on ff and note 2 on ch

ie = internet explorer,ff = firefox,ch = google chrome。 注1:ff一直有效,直到用退格键删除值后 - 请参阅Ray Vega上面的注释。 注释2:在chrome中有所作为 - 更新后它不变,然后单击并单击返回到该字段并显示值。 最好的是elem.value = changeVal;我没有在上面评论。

答案 12 :(得分:0)

只需重新发布原帖后的评论。 innerHTML适用于所有浏览器。谢谢stefita。

myElement.innerHTML =“foo”;

答案 13 :(得分:-1)

在这里找到了:

<!--[if lte IE 8]>
    <script type="text/javascript">
        if (Object.defineProperty && Object.getOwnPropertyDescriptor &&
            !Object.getOwnPropertyDescriptor(Element.prototype, "textContent").get)
          (function() {
            var innerText = Object.getOwnPropertyDescriptor(Element.prototype, "innerText");
            Object.defineProperty(Element.prototype, "textContent",
              { // It won't work if you just drop in innerText.get
                // and innerText.set or the whole descriptor.
                get : function() {
                  return innerText.get.call(this)
                },
                set : function(x) {
                  return innerText.set.call(this, x)
                }
              }
            );
          })();
    </script>
<![endif]-->

答案 14 :(得分:-2)

也可以在其他浏览器中模拟innerText行为:

 if (((typeof window.HTMLElement) !== "undefined") && ((typeof HTMLElement.prototype.__defineGetter__) !== "undefined")) {
     HTMLElement.prototype.__defineGetter__("innerText", function () {
         if (this.textContent) {
             return this.textContent;
         } else {
             var r = this.ownerDocument.createRange();
             r.selectNodeContents(this);
             return r.toString();
         }
     });
     HTMLElement.prototype.__defineSetter__("innerText", function (str) {
         if (this.textContent) {
             this.textContent = str;
         } else {
             this.innerHTML = str.replace(/&/g, '&amp;').replace(/>/g, '&gt;').replace(/</g, '&lt;').replace(/\n/g, "<br />\n");
         }
     });
 }