使用 jQuery 检查 div 是否存在溢出元素。

134

我有一个高度固定且具有overflow:hidden;属性的

元素。

我想使用jQuery检查

元素中是否存在溢出到
固定高度之外的元素。我应该如何实现?


我可能错了,但我认为没有一个神奇的jQuery方法可以检查一个元素是否在另一个元素之外。你可能需要检查div内部元素的高度和位置,并进行一些计算来判断它们是否溢出。 - adeneo
1
是的,我在考虑检查 div 顶部位置和 div 内最后一个子元素底部位置之间的差距是否大于 div 的高度。 - Justin Meltzer
可能是detect elements overflow using jquery的重复问题。 - Noyo
9个回答

289

实际上,您不需要任何jQuery来检查是否发生了溢出。使用element.offsetHeightelement.offsetWidthelement.scrollHeightelement.scrollWidth,您可以确定您的元素是否具有比其大小更大的内容:

if (element.offsetHeight < element.scrollHeight ||
    element.offsetWidth < element.scrollWidth) {
    // your element have overflow
} else {
    // your element doesn't have overflow
}

查看示例操作:Fiddle

但是,如果你想知道你的元素内部的元素是可见还是不可见,那么你需要进行更多的计算。在可见性方面,子元素有三种状态:

enter image description here

如果你想计算半可见的项目,你需要使用以下脚本:

var invisibleItems = [];
for(var i=0; i<element.childElementCount; i++){
  if (element.children[i].offsetTop + element.children[i].offsetHeight >
      element.offsetTop + element.offsetHeight ||
      element.children[i].offsetLeft + element.children[i].offsetWidth >
      element.offsetLeft + element.offsetWidth ){

        invisibleItems.push(element.children[i]);
    }

}

如果您不想计算半可见元素,您可以略微调整计算结果。


4
@Robbie <p>是块级元素,它的宽度为100%。如果你想尝试在<p>内添加不同数量的文本,只需使用p{display:inline}即可使<p>变成行内元素,这样<p>的宽度将由其中的文本决定。 - Mohsen
1
适用于大多数情况,但无法覆盖CSS表格(display table-cell、table-row、table)的场景。 - User18165
1
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Lodewijk
1
@Lodewijk 我也看到了同样的问题。也许正确的属性是clientHeight? - Pete
这不是一个好的答案。我有一个 jQuery 对象,我需要一个完整的 jQuery 解决方案,类似于 $(obj).offset().left。 - Jonathan Simas
显示剩余4条评论

42

我和楼主有同样的问题,但那些回答都不能满足我的需求。我需要一个简单的条件,来满足我的简单需求。

以下是我的答案:

if ($("#myoverflowingelement").prop('scrollWidth') > $("#myoverflowingelement").width() ) {
  alert("this element is overflowing !!");
}
else {
 alert("this element is not overflowing!!");
}

同时,如果你需要测试两种情况,你可以通过更改scrollHeight来代替scrollWidth


1
谢谢,这对我有用。我只需要一个简单的jQuery示例,而不是纯JS。 - mikhail-t
4
对于具有填充/边距的元素,width属性无效。请使用outerWidth(true)代替。 - Vladimir Shmidt
不支持IE,在Mozilla和Chrome中良好运行。 - Sushil Kumar
我在使用这个脚本时遇到了一些奇怪的效果。在Chrome中进行测试。我重写了它来检查高度(使用OuterHeight),如果我使用F5重新加载页面来检查脚本,或者从另一个页面导航到它,它总是返回为overflow = true,但如果我使用ctrl-F5,则返回为overflow = false。这是在测试应该返回false的情况下发生的。当它应该是true时,它总是有效的。 - Dennis
好的,我自己解决了。我将我的脚本标签包装在window.addEventListener('DOMContentLoaded')中,这样它们就可以与我的异步加载的jquery和其他文件一起工作。但是在该阶段运行此脚本会返回明显错误的读数,因此对于此脚本,我用'load'替换了DOMContentLoaded以进一步延迟脚本的执行。现在它每次都返回正确的结果。而且对于我的目的来说,等待页面加载后再运行它是完全可以接受的,然后我甚至可以添加动画来突出显示用户对“阅读更多”按钮的注意力。 - Dennis

4

部分参考Mohsen的答案(添加的第一个条件覆盖了子元素在父元素之前被隐藏的情况):

jQuery.fn.isChildOverflowing = function (child) {
  var p = jQuery(this).get(0);
  var el = jQuery(child).get(0);
  return (el.offsetTop < p.offsetTop || el.offsetLeft < p.offsetLeft) ||
    (el.offsetTop + el.offsetHeight > p.offsetTop + p.offsetHeight || el.offsetLeft + el.offsetWidth > p.offsetLeft + p.offsetWidth);
};

那么只需要执行以下操作:
jQuery('#parent').isChildOverflowing('#child');

3

我使用了 jQuery 库:https://github.com/kevinmarx/overflowing

安装完库后,如果您想将类 overflowing 分配给所有溢出元素,只需运行以下代码:

$('.targetElement').overflowing('.parentElement')

这将会给所有溢出的元素添加类名overflowing,例如 <div class="targetElement overflowing">。你可以在某些事件处理程序(如点击、鼠标悬停)或其他函数中添加此代码,以使其动态更新。

2
我通过在溢出的 div 中添加另一个 div 来解决了这个问题。然后你可以比较这两个 div 的高度。
<div class="AAAA overflow-hidden" style="height: 20px;" >
    <div class="BBBB" >
        Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
    </div>
</div>

以及JS

    if ($('.AAAA').height() < $('.BBBB').height()) {
        console.log('we have overflow')
    } else {
        console.log('NO overflow')
    }

这看起来更容易了...


2

一种方法是将scrollTop与自身进行比较。给内容一个比其大小更大的滚动值,然后检查它的scrollTop是否为0(如果不为0,则存在溢出)。

http://jsfiddle.net/ukvBf/


1
这是对我有效的jQuery解决方案。offsetWidth等不起作用。
function is_overflowing(element, extra_width) {
    return element.position().left + element.width() + extra_width > element.parent().width();
}

如果这个方法不起作用,请确保元素的父级具有所需的宽度(个人而言,我必须使用parent().parent())。position相对于父级。我还包括了extra_width,因为我的元素(“标签”)包含需要一些时间加载的图像,在函数调用期间它们的宽度为零,破坏了计算。为了解决这个问题,我使用以下调用代码:
var extra_width = 0;
$(".tag:visible").each(function() {
    if (!$(this).find("img:visible").width()) {
        // tag image might not be visible at this point,
        // so we add its future width to the overflow calculation
        // the goal is to hide tags that do not fit one line
        extra_width += 28;
    }
    if (is_overflowing($(this), extra_width)) {
        $(this).hide();
    }
});

希望这能有所帮助。

1
以简单易懂的语言来说:获取父元素。检查其高度并保存该值。然后循环遍历所有子元素并检查它们各自的高度。
这样做有点不规范,但你可以了解基本思想: http://jsfiddle.net/VgDgz/

1
这是一个很好的例子,但是位置怎么处理呢?如果一个元素被绝对定位在父元素的顶部,即使高度低于父元素,它仍然可能会溢出。 - adeneo
当然,可能有很多不同的情况会导致这种情况发生。这里只是一个快速的例子,可以作为开始的地方。Op的具体情况可能会定义需要检查什么。 - Doozer Blake

0
这是一个纯jQuery解决方案,但它相当凌乱:
var div_height = $(this).height();
var vertical_div_top_position = $(this).offset().top;
var lastchild_height = $(this).children('p:last-child').height();
var vertical_lastchild_top_position = $(this).children('p:last-child').offset().top;
var vertical_lastchild_bottom_position = lastchild_height + vertical_lastchild_top_position;
var real_height = vertical_lastchild_bottom_position - vertical_div_top_position;

if (real_height > div_height){
    //overflow div
}

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