获取元素的内部文本,但排除隐藏的子元素

Get the innerText of an element, but exclude hidden children

本文关键字:元素 排除 隐藏 文本 内部 获取      更新时间:2023-09-26

如何从节点获取文本,以便它像"innerText"那样以空格格式返回它,但排除隐藏的后代节点(样式显示:none)?

更新:正如OP在下面的评论中指出的那样,尽管MDN明确指出IE引入了innerText来排除隐藏内容,但在IE中的测试表明情况并非如此。 总结一下:

  • Chrome:innerText仅从可见元素返回文本。
  • IE:innerText返回所有文本,而不考虑元素的可见性。
  • Firefox:innerText是未定义的(如W3C所示,在我的测试中)。

把所有这些加起来,你就有一个像瘟疫一样要避免的属性。 请继续阅读以获取解决方案。

如果你想要跨浏览器兼容性,你必须推出自己的函数。 这是一个效果很好的:

function getVisibleText( node ) {
    if( node.nodeType === Node.TEXT_NODE ) return node.textContent;
    var style = getComputedStyle( node );
    if( style && style.display === 'none' ) return '';
    var text = '';
    for( var i=0; i<node.childNodes.length; i++ ) 
        text += getVisibleText( node.childNodes[i] );
    return text;
}

如果你想变得非常聪明,你可以在Node对象上创建一个属性,这样感觉更"自然"。 起初,我认为这是在 Firefox 上填充 innerText 属性的聪明方法,但该属性不是作为Node对象原型上的属性创建的,所以你真的会在那里玩火。 但是,您可以创建一个新属性,例如textContentVisible

Object.defineProperty( Node.prototype, 'textContentVisible', {
    get: function() { 
       return getVisibleText( this );
    }, 
    enumerable: true
});

下面是一个演示这些技术的 JsFiddle: http://jsfiddle.net/8S82d/

这很有趣,我来这里是因为我正在寻找为什么在 Chrome 中省略了display:none元素的文本。

所以,这最终是我的解决方案.
基本上,我克隆节点并删除设置display:none的类/样式。

如何添加隐藏元素的innerText

function getInnerText(selector) {
    let d = document.createElement('div')
    d.innerHTML = document.querySelector(selector).innerHTML.replaceAll(' class="hidden"', '')
    return d.innerText
}