如何最佳地测试DOM中的元素?

6

我知道有几种方法可以做到这一点。

测试 CSS 显示

if ($('#foo').css('display') == 'none')

测试可见性

if ($('#foo').is(':visible'))

在可见性中,我可以检查元素是否存在。

如果元素在文档中占用空间,则认为它们是可见的。可见元素的宽度或高度大于零。

具有visibility: hidden或opacity: 0的元素被视为可见,因为它们仍然在布局中占用空间。

来源

但是,请注意,在这两种情况下,我都无法测试用户的可见性,因为:

通过将display属性设置为“none”或将visibility属性设置为“hidden”来隐藏元素。但是,请注意,这两种方法会产生不同的结果:

visibility: hidden隐藏元素,但它仍将占用与以前相同的空间。元素将被隐藏,但仍会影响布局。

display: none隐藏元素,它将不占用任何空间。元素将被隐藏,并且页面将显示为如果该元素不存在:

来源

所以在这两个示例中,我都没有测试元素是否对用户来说是完全可见的。

所以我的问题是:

  • 上面两个if代码的区别是什么?
  • 测试元素是否对用户可见的最佳方法是什么:

我应该使用类似以下的方式:

if ($('#foo').is(':visible') && 
    $('#foo').css('opacity') > 0 && 
    $('#foo').css('visibility') != 'hidden')

你尝试运行过最后一段代码看它是否可行? - Ashley Strout
  1. 如何测试元素是否对用户可见?>> $('#foo').is(':visible') 是检查元素是否对用户可见(即显示)的最佳方法。
  2. 上述两个if代码之间有什么区别?>> 您引用了“visible”和“display”的区别。那么,您的问题是什么?
- Selvakumar Arumugam
如果一个元素通过 z-index 定位在另一个元素之上,但是它本身是完全可见的,那怎么办?如果这个最上层的 div 具有不透明的背景呢?或者是透明的?或者是部分透明的?那么被遮盖的元素是否被认为是可见的呢? - Jon
你可以直接看屏幕,自己找到元素怎么样?永远不要相信用户,他们什么都不懂。 - adeneo
@Vega和其他人,我在+Caleb的答案中发表了一条评论,解释了我在问题中的大部分评论,请看看我的评论。我希望这能让事情变得清晰,并且我们都能得到最好的结果。提前感谢您的关注。 - Michel Ayres
3个回答

2
我认为最好的方法是实现一个自定义函数,如下所示,并在新问题出现时进行测试/改进。
$.fn.isReallyVisible = function () { //rename function name as you like..
    return (this.css('display') != 'none' &&
            this.css('visibility') != 'hidden' &&
            this.css('opacity') > 0);
}

由于我们使用jQuery的.css函数(特别是透明度),上述内容应该跨浏览器保证。

演示


非常好。只是想知道,你使用 this.css('display') != 'none' 而不是 $('#foo').is(':visible')。你能告诉我为什么做出这个选择吗? - Michel Ayres
1
@MichelAyres 只是一个小的改进。 is 是 jQuery 函数,它可以处理不同类型的参数,其中 :visible 是其中之一。在内部,它首先会过滤出它是否为 :visible,并执行其相应的流程,最终它将执行相同的操作。 - Selvakumar Arumugam

0

两者之间的区别在于使用“visible”属性隐藏的元素仍然存在于页面上,只是不会被实际显示。因此,当页面呈现其余显示内容时,其间距将被考虑在内。

看起来另一种方法实际上会阻止元素放置在页面上,这可能会改变页面上其他元素的布局。

通常从我的经验来看,测试可见部分就足够了,但如果您想要更完整,那么您需要使用多个属性上的“&&”条件进行检查。它实际上取决于您使用的代码有多干净,以及系统的其余UI方面经过了多少测试。

另一个要考虑的问题是测试的目的。您是在测试您编写的代码,还是测试浏览器如何使用Javascript呈现页面?您希望测试您正在创建的代码,并依赖于浏览器工作的事实(因为如果浏览器停止工作,那么整个系统都是不可靠的)。因此,如果您的代码告诉元素设置某些属性,则检查该属性就足以进行测试。除此之外的任何东西都只能通过在代码本身之外进行测试(例如手动查看页面和其他类似内容)来证明。


我的关注点更多地集中在跨浏览器和性能方面。此外,如果我的逻辑中有什么我忽略的地方,这也是我希望有人向我解释差异和最佳实践的原因。如果你看一下SO,你会发现有很多不同的答案关于“在我的DOM中查找Waldo”的类型问题。 - Michel Ayres

0
如果您想查看DOM中是否存在元素,只需执行以下操作:
$.fn.exists = function () {
    return this.length > 0;
}

使用方法:

$('#myid').exists();

这是一个不错的答案,但是它需要的时间不会比问题中的前两个更长吧?或者它们是彼此的别名? - Michel Ayres
@FelixKling 他正在使用 this.length > 0。我没有理解你的评论(他只是在他的编辑中添加了对JavaScript函数的调用)。 - Michel Ayres
它并不基于显示属性来确定元素的存在,而是返回它是否实际存在。 - Gabe
1
@Michel:当我评论时,它是$(this).length > 1。Gabe可能在5分钟的宽限期内进行了编辑。否则,我为什么要评论呢? - Felix Kling
1
@FelixKling,我不知道这个5分钟的限制。我刚刚检查了编辑记录,并没有看到有关于此的主题,所以我才问为什么,以理解背后的含义。感谢您对没有显示编辑的解释。通常当我在短时间内编辑我的问题/答案时,它会被记录在日志中。以前从未注意到过。 - Michel Ayres
2
@Michel:别担心 :) 是的,在前5分钟内,更改不会被记录下来... - Felix Kling

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接