Javascript 更健壮的jQuery:隐藏实现

Javascript 更健壮的jQuery:隐藏实现,javascript,jquery,html,dom,hidden,Javascript,Jquery,Html,Dom,Hidden,我正在处理一个奇怪的问题,jQuery的.is(':hidden')返回true作为一个围绕清晰可见内容的元素。看看这个问题 :hidden伪检查offsetWidth和offsetHeight,在本例中实际报告为0 根本原因似乎是错误的标记:DIV嵌套在SPAN中。不幸的是,这个例子是从几个大型站点上的标记中缩减出来的,在这些站点上脚本需要操作。没有机会更改标记 在现实世界中标记被滥用的情况下,如何获得可靠的:隐藏的实现?这个问题不是关于修复jQuery,而是关于健壮可见性检查的逻辑,因为现实

我正在处理一个奇怪的问题,jQuery的
.is(':hidden')
返回
true
作为一个围绕清晰可见内容的元素。看看这个问题

:hidden
伪检查
offsetWidth
offsetHeight
,在本例中实际报告为0

根本原因似乎是错误的标记:
DIV
嵌套在
SPAN
中。不幸的是,这个例子是从几个大型站点上的标记中缩减出来的,在这些站点上脚本需要操作。没有机会更改标记

在现实世界中标记被滥用的情况下,如何获得可靠的
:隐藏的
实现?这个问题不是关于修复jQuery,而是关于健壮可见性检查的逻辑,因为现实世界的HTML经常被破坏

更新:


根据已接受的答案,添加
getBoundingClientRect
检查将使
.is(“:hidden”)
在CSS未用于彻底改变定位的情况下更加健壮,例如

function isHiddenSubtree($node) {
  if ($node.is(':hidden')) {
    var rect = $node.get(0).getBoundingClientRect();
    return rect.width === 0 && rect.height === 0;
  } else {
    return false;
  }
}

但是,对于浮动或定位的图元,这将失败,如中所示

没关系,它是隐藏的:

在此上下文中,元素div不允许作为元素span的子元素。 (正在抑制来自此子树的进一步错误。)

Span是内联元素。在
HTML5解析器
中,标记不会中断,而是将
块元素
设置为
内联元素
。但是
计算引擎
不是
HTML5解析器
。它适用于正确的标记

什么是计算引擎?例如,在任何大型站点的devtool栏中打开
timeline
,获取任何ajax操作的
计算层
消息。也就是说,此引擎计算/重新计算
DOM
偏移量和大小

编辑:

返回无零大小。但其工作原理如下:

  • 将节点克隆到抽象沙盒
  • 计算需要应用节点的所有样式
  • 那就申请吧
  • 计算尺寸

因此
getBoundingClientRect
会执行许多不必要的操作。

jquery报告:如果元素的宽度和高度为0,则隐藏,这对于您的

这意味着,如果元素的CSS显示为“无”,或其父/父元素的任何显示为“无”,或者如果元素的宽度为0,元素的高度为0,则元素将被报告为隐藏


您应该检查的可见性,并删除周围(见皮纳尔的回答)

我同意,这是错误的标记。也就是说,浏览器总是能够处理错误的标记,理想情况下,现实世界的库也应该具有处理错误标记的智能。jQuery已经有了大量代码来解决怪癖、浏览器错误和糟糕的标记使用。这个问题是关于在标记错误的情况下找到正确隐藏报告问题的解决方案。@sb9的回答假设我可以更改HTML,但我不能。问题中已清楚说明这一点。另外,我不是在为这个案子寻找解决方案。我正在寻找一个通用的解决方案。
getBoundingClientRect
为您的案例返回none-zero大小,但它的节点是其他案例的保证。真有趣。你能用提琴演示一下吗?这似乎是一个有用的启发,可以添加到
:hidden
检查中。是的,我在问题中提到过。这里的问题不是隐藏的逻辑如何运作背后的想法在理论上是否良好。问题是如何使它即使在标记错误的站点上也能正常工作。@Sim使用其他东西。并不是所有的代码都能在任何条件下工作。您可以自由编辑jQuery的开发版本,并根据您的需要进行调整。@JeffNoel对,这个问题是关于“其他东西”是什么。有什么想法吗?@sb9我无法更改HTML:这在问题中已明确说明。我的脚本在第三方HTML上运行。