检测元素是否溢出的最简单方法是什么?
我的用例是,我想限制某个内容框的高度为300px。如果内部含量高于那个,我会用溢出来切断它。但如果它溢出,我想显示一个“更多”按钮,但如果不是,我不想显示该按钮。
是否有一种简单的方法来检测溢出,还是有更好的方法?
答案 0 :(得分:149)
如果DOM元素溢出,此函数将返回布尔值:
function isOverflown(element) {
return element.scrollHeight > element.clientHeight || element.scrollWidth > element.clientWidth;
}
元素可能垂直或水平溢出或两者都
答案 1 :(得分:37)
如果您只想显示更多内容的标识符,那么您可以使用纯CSS执行此操作。我为此使用纯滚动阴影。诀窍是使用background-attachment: local;
。你的CSS看起来像这样:
.scrollbox {
overflow: auto;
width: 200px;
max-height: 200px;
margin: 50px auto;
background:
/* Shadow covers */
linear-gradient(white 30%, rgba(255,255,255,0)),
linear-gradient(rgba(255,255,255,0), white 70%) 0 100%,
/* Shadows */
radial-gradient(50% 0, farthest-side, rgba(0,0,0,.2), rgba(0,0,0,0)),
radial-gradient(50% 100%,farthest-side, rgba(0,0,0,.2), rgba(0,0,0,0)) 0 100%;
background:
/* Shadow covers */
linear-gradient(white 30%, rgba(255,255,255,0)),
linear-gradient(rgba(255,255,255,0), white 70%) 0 100%,
/* Shadows */
radial-gradient(farthest-side at 50% 0, rgba(0,0,0,.2), rgba(0,0,0,0)),
radial-gradient(farthest-side at 50% 100%, rgba(0,0,0,.2), rgba(0,0,0,0)) 0 100%;
background-repeat: no-repeat;
background-color: white;
background-size: 100% 40px, 100% 40px, 100% 14px, 100% 14px;
/* Opera doesn't support this in the shorthand */
background-attachment: local, local, scroll, scroll;
}
您可以在http://dabblet.com/gist/2462915
上找到的代码和示例您可以在此处找到解释:http://lea.verou.me/2012/04/background-attachment-local/。
答案 2 :(得分:12)
将element.scrollHeight
与element.clientHeight
进行比较应该完成任务。
以下是来自MDN的图片,解释了Element.scrollHeight和Element.clientHeight。
答案 3 :(得分:4)
会是这样的:http://jsfiddle.net/Skooljester/jWRRA/1/有效吗?它只检查内容的高度并将其与容器的高度进行比较。如果它大于您可以在代码中添加“显示更多”按钮。
更新:添加了代码,以便在容器顶部创建“显示更多”按钮。
答案 4 :(得分:3)
如果你正在使用jQuery,你可能会尝试一个技巧:使用overflow: hidden
创建外部div,使用内容创建内部div。然后使用.height()
函数检查内部div的高度是否大于外部div的高度。我不确定它会起作用,但试一试。
答案 5 :(得分:2)
我制作了一个多部分的代码笔,演示了上述答案(例如,使用隐藏的溢出和高度),以及如何扩展/折叠溢出的项目
示例1:https://codepen.io/Kagerjay/pen/rraKLB(真正的简单示例,没有javascript,仅用于剪辑溢出的项目)
示例2:https://codepen.io/Kagerjay/pen/LBErJL(单个事件处理程序在溢出的项目上显示更多/不显示)
示例3:https://codepen.io/Kagerjay/pen/MBYBoJ(许多事件处理程序在溢出项目中显示更多/显示更少)
我也有以下示例3 ,我使用的是Jade / Pug,所以可能有点冗长。我建议您检查一下我更易于掌握的代码笔。
// Overflow boolean checker
function isOverflown(element){
return element.scrollHeight > element.clientHeight || element.scrollWidth > element.clientWidth;
}
// Jquery Toggle Text Plugin
$.fn.toggleText = function(t1, t2){
if (this.text() == t1) this.text(t2);
else this.text(t1);
return this;
};
// Toggle Overflow
function toggleOverflow(e){
e.target.parentElement.classList.toggle("grid-parent--showall");
$(e.target).toggleText("Show More", "Show LESS");
}
// Where stuff happens
var parents = document.querySelectorAll(".grid-parent");
parents.forEach(parent => {
if(isOverflown(parent)){
parent.lastElementChild.classList.add("btn-show");
parent.lastElementChild.addEventListener('click', toggleOverflow);
}
})
body {
background-color: #EEF0ED;
margin-bottom: 300px;
}
.grid-parent {
margin: 20px;
width: 250px;
background-color: lightgrey;
display: flex;
flex-wrap: wrap;
overflow: hidden;
max-height: 100px;
position: relative;
}
.grid-parent--showall {
max-height: none;
}
.grid-item {
background-color: blue;
width: 50px;
height: 50px;
box-sizing: border-box;
border: 1px solid red;
}
.grid-item:nth-of-type(even) {
background-color: lightblue;
}
.btn-expand {
display: none;
z-index: 3;
position: absolute;
right: 0px;
bottom: 0px;
padding: 3px;
background-color: red;
color: white;
}
.btn-show {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section>
<p>Any grid-parent over 10 child items has a "SHOW MORE" button to expand</p>
<p>Click "SHOW MORE" to see the results</p>
</section>
<radio></radio>
<div class="wrapper">
<h3>5 child elements</h3>
<div class="grid-parent">
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="btn-expand">Show More</div>
</div>
<h3>8 child elements</h3>
<div class="grid-parent">
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="btn-expand">Show More</div>
</div>
<h3>10 child elements</h3>
<div class="grid-parent">
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="btn-expand">Show More</div>
</div>
<h3>13 child elements</h3>
<div class="grid-parent">
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="btn-expand">Show More</div>
</div>
<h3>16 child elements</h3>
<div class="grid-parent">
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="btn-expand">Show More</div>
</div>
<h3>19 child elements</h3>
<div class="grid-parent">
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="btn-expand">Show More</div>
</div>
</div>
答案 6 :(得分:2)
出于封装原因,我扩展了Element。来自麦克风的答案。
/*
* isOverflowing
*
* Checks to see if the element has overflowing content
*
* @returns {}
*/
Element.prototype.isOverflowing = function(){
return this.scrollHeight > this.clientHeight || this.scrollWidth > this.clientWidth;
}
像这样使用它
let elementInQuestion = document.getElementById("id_selector");
if(elementInQuestion.isOverflowing()){
// do something
}
答案 7 :(得分:1)
使用js来检查孩子的offsetHeight
是否超过父母..如果是,请让父母满意scroll/hidden/auto
以你想要的为准,并且display:block
在更多的div上。 。
答案 8 :(得分:1)
您应该考虑的另一个问题是JS不可用。想想渐进的结界或优雅的退化。我建议:
答案 9 :(得分:1)
这是一个小提琴,用于确定元素是否已使用包含overflow:hidden和JQuery height()的包装div溢出,以测量包装器和内部内容div之间的差异。
outers.each(function () {
var inner_h = $(this).find('.inner').height();
console.log(inner_h);
var outer_h = $(this).height();
console.log(outer_h);
var overflowed = (inner_h > outer_h) ? true : false;
console.log("overflowed = ", overflowed);
});
答案 10 :(得分:1)
这是适合我的jQuery解决方案。 clientWidth
等没有工作。
function is_overflowing(element, extra_width) {
return element.position().left + element.width() + extra_width > element.parent().width();
}
如果这不起作用,请确保元素&#39;父级具有所需的宽度(个人而言,我必须使用parent().parent())
。position
相对于父级。我还包括extra_width
因为我的元素(&#34;标签& #34;)包含需要很少时间加载的图像,但在函数调用期间它们的宽度为零,破坏了计算。为了解决这个问题,我使用以下调用代码:
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();
}
});
希望这有帮助。
答案 11 :(得分:0)
您可以检查相对于偏移父级的边界。
// Position of left edge relative to frame left courtesy
// http://www.quirksmode.org/js/findpos.html
function absleft(el) {
var x = 0;
for (; el; el = el.offsetParent) {
x += el.offsetLeft;
}
return x;
}
// Position of top edge relative to top of frame.
function abstop(el) {
var y = 0;
for (; el; el = el.offsetParent) {
y += el.offsetTop;
}
return y;
}
// True iff el's bounding rectangle includes a non-zero area
// the container's bounding rectangle.
function overflows(el, opt_container) {
var cont = opt_container || el.offsetParent;
var left = absleft(el), right = left + el.offsetWidth,
top = abstop(el), bottom = top + el.offsetHeight;
var cleft = absleft(cont), cright = cleft + cont.offsetWidth,
ctop = abstop(cont), cbottom = ctop + cont.offsetHeight;
return left < cleft || top < ctop
|| right > cright || bottom > cbottom;
}
如果你传递一个元素,它将告诉你它的边界是否完全在容器内,如果没有提供显式容器,它将默认为元素的偏移父元素。它使用
答案 12 :(得分:0)
setTimeout(function(){
isOverflowed(element)
},500)
function isOverflowed(element){
return element.scrollHeight > element.clientHeight || element.scrollWidth > element.clientWidth;
}
这对我有用。谢谢。
答案 13 :(得分:0)
答案的jquery替代方法是使用[0]键访问原始元素,例如:
if ($('#elem')[0].scrollHeight > $('#elem')[0].clientHeight){
答案 14 :(得分:0)
为条件可见性添加事件侦听器:
document.getElementById('parent').addEventListener('scroll', (e) => {
const childEl = document.getElementById('child');
childEl.style.visibility = e.target.scrollTop > 0 ? 'visible' : 'hidden';
});