检查元素的内容是否溢出?

IT技术 javascript css overflow
2021-01-29 04:26:23

检测元素是否溢出的最简单方法是什么?

我的用例是,我想限制某个内容框的高度为 300 像素。如果内部内容比那个高,我会用溢出将其切断。但是如果它溢出了,我想显示一个“更多”按钮,但如果没有,我不想显示那个按钮。

有没有一种简单的方法来检测溢出,或者有没有更好的方法?

6个回答

元素可能会垂直、水平或同时溢出。如果 DOM 元素溢出,此函数将返回一个布尔值:

function isOverflown(element) {
  return element.scrollHeight > element.clientHeight || element.scrollWidth > element.clientWidth;
}

ES6 示例:

const isOverflown = ({ clientWidth, clientHeight, scrollWidth, scrollHeight }) => {
    return scrollHeight > clientHeight || scrollWidth > clientWidth;
}
哇,这甚至可以在 a 中工作grid,其中边界客户端 rect 不包括溢出的内容。
2021-03-18 04:26:23
@micnic 嗨,我正在使用 ionic2 并尝试做同样的事情...但该函数始终返回 true... 是否有不同的方式在 angular 2 中做事
2021-03-21 04:26:23
很棒的解决方案!这是一个 jQuery 变体(与 一起使用$("#element").overflown()):$.fn.overflown=function(){var e=this[0];return e.scrollHeight>e.clientHeight||e.scrollWidth>e.clientWidth;}
2021-03-28 04:26:23
仅适用于 Firefox:element.addEventListener ("overflow", () => log( "overflow" ), false);参考:溢出事件
2021-03-29 04:26:23
@DavidBracoly,这个函数是针对纯 DOM API 的,我没有使用 Ionic/Angular 的经验,我猜你应该得到原始的 DOM 元素并使用这个函数
2021-04-12 04:26:23

如果您只想显示更多内容的标识符,那么您可以使用纯 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;
}
<div class="scrollbox">
  <ul>
    <li>Not enough content to scroll</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
  </ul>
</div>


<div class="scrollbox">
  <ul>
    <li>Ah! Scroll below!</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
    <li>7</li>
    <li>8</li>
    <li>9</li>
    <li>10</li>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
    <li>5</li>
    <li>6</li>
    <li>7</li>
    <li>8</li>
    <li>The end!</li>
    <li>No shadow there.</li>
  </ul>
</div>

您可以在http://dabblet.com/gist/2462915 上找到代码和示例

您可以在此处找到解释:http : //lea.verou.me/2012/04/background-attachment-local/

很棒的技巧,但是在 Chrome 中它只在底部显示静态阴影,它永远不会消失并且上阴影永远不会显示
2021-03-16 04:26:23
好主意,但在您的示例中,背景(阴影)将在文本后面!
2021-03-25 04:26:23
/* Opera 不支持速记 */ -> 我在 Opera 上,它似乎对我有用。
2021-03-31 04:26:23

相比element.scrollHeightelement.clientHeight应该做的任务。

下面是 MDN 中解释 Element.scrollHeight 和 Element.clientHeight 的图片。

滚动高度

客户高度

在这里,这些属性始终具有相同的值。
2021-03-15 04:26:23
是的,但根据quirksmode它最有效 - 并且比其他发布的解决方案简单得多。
2021-03-29 04:26:23
@Harry:当前所有浏览器(至少是桌面浏览器)都支持它,因此它是否正式非标准并不重要。
2021-04-02 04:26:23

我制作了一个多部分代码笔来演示上述答案(例如使用溢出隐藏和高度)以及如何展开/折叠溢出的项目

示例 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>

会像这样:http : //jsfiddle.net/Skooljester/jWRRA/1/工作吗?它只是检查内容的高度并将其与容器的高度进行比较。如果它大于您可以放入代码以附加“显示更多”按钮。

更新:添加了在容器顶部创建“显示更多”按钮的代码。