Sprawdzić, czy zawartość elementu jest przepełniona?
Jaki jest najprostszy sposób wykrycia, czy element został przepełniony?
Moim przypadkiem użycia jest to, że chcę ograniczyć pewne pole zawartości do wysokości 300px. Jeśli wewnętrzna zawartość jest wyższa, odetnę ją przelewem. Ale jeśli jest przepełniony, chcę pokazać przycisk "Więcej", ale jeśli nie, nie chcę pokazać tego przycisku.
Czy jest łatwy sposób na wykrycie przepełnienia, czy jest lepsza metoda?
14 answers
Jeśli chcesz pokazać tylko identyfikator dla większej ilości treści, możesz to zrobić za pomocą czystego CSS. Używam do tego czystego przewijania cieni. Sztuczka polega na użyciu background-attachment: local;
. Twój css wygląda tak:
.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>
Kod i przykład można znaleźć na http://dabblet.com/gist/2462915
I Wyjaśnienie można znaleźć tutaj: http://lea.verou.me/2012/04/background-attachment-local/.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-13 08:18:51
Element może być przepełniony pionowo, poziomo lub oba. Ta funkcja zwróci wartość logiczną, jeśli element DOM jest przepełniony:
function isOverflown(element) {
return element.scrollHeight > element.clientHeight || element.scrollWidth > element.clientWidth;
}
function isOverflown(element) {
return element.scrollHeight > element.clientHeight || element.scrollWidth > element.clientWidth;
}
var els = document.getElementsByClassName('demos');
for (var i = 0; i < els.length; i++) {
var el = els[i];
el.style.borderColor = (isOverflown(el) ? 'red' : 'green');
console.log("Element #" + i + " is " + (isOverflown(el) ? '' : 'not ') + "overflown.");
}
.demos {
white-space: nowrap;
overflow: hidden;
width: 120px;
border: 3px solid black;
}
<div class='demos'>This is some text inside the div which we are testing</div>
<div class='demos'>This is text.</div>
ES6 przykład:
const isOverflown = ({ clientWidth, clientHeight, scrollWidth, scrollHeight }) => {
return scrollHeight > clientHeight || scrollWidth > clientWidth;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-03-29 13:51:07
Porównanie element.scrollHeight
na element.clientHeight
powinien wykonać zadanie.
Poniżej znajdują się zdjęcia z MDN explaining Element.przewijanie i Element.clientHeight.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-19 08:15:35
Zrobiłem wieloczęściowy codepen demonstrując powyższe odpowiedzi (np. używając overflow hidden i height), ale także jak rozwijasz / zwijasz przepełnione Elementy
Przykład 1: https://codepen.io/Kagerjay/pen/rraKLB (prosty przykład, bez javascript, tylko do wycinania przepełnionych elementów)
Przykład 2: https://codepen.io/Kagerjay/pen/LBErJL (obsługa pojedynczego zdarzenia Pokaż więcej / Pokaż bez pokazu na przepełnionych elementach)
Przykład 3: https://codepen.io/Kagerjay/pen/MBYBoJ (Obsługa wielu zdarzeń dla wielu Pokaż więcej / Pokaż mniej dla przepełnionych elementów)
Mam załączony przykład 3 poniżej również, używam Jade / Pug, więc może to być trochę gadatliwe. Proponuję sprawdzić kody, które uprościłem do zrozumienia.
// 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>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-11 18:13:13
Update: dodano kod, aby utworzyć przycisk "Pokaż więcej" na górze kontenera.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-17 18:27:14
Jeśli używasz jQuery, możesz spróbować sztuczki: zrobić zewnętrzny div z overflow: hidden
i wewnętrzny div z treścią. Następnie użyj funkcji .height()
, aby sprawdzić, czy wysokość wewnętrznego div jest większa niż wysokość zewnętrznego div. Nie jestem pewien, czy to zadziała, ale spróbuj.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-17 18:29:53
Rozszerzyłem Element z powodów enkapsulacji. Od micnic answer.
/*
* isOverflowing
*
* Checks to see if the element has overflowing content
*
* @returns {}
*/
Element.prototype.isOverflowing = function(){
return this.scrollHeight > this.clientHeight || this.scrollWidth > this.clientWidth;
}
Użyj go w ten sposób
let elementInQuestion = document.getElementById("id_selector");
if(elementInQuestion.isOverflowing()){
// do something
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-25 12:21:15
Użyj js, aby sprawdzić, czy dziecko offsetHeight
jest więcej niż rodzice.. jeśli tak, spraw, aby rodzice przepełnili scroll/hidden/auto
cokolwiek chcesz, a także display:block
na więcej div..
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-17 18:28:20
Możesz sprawdzić granice względem elementu nadrzędnego offset.
// 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;
}
Jeśli przekażesz ten element, powie Ci, czy jego granice są całkowicie wewnątrz kontenera, i będzie domyślnie ustawione na rodzica offsetowego elementu, jeśli nie zostanie podany jawny kontener. Używa
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-17 18:35:55
Kolejną kwestią, którą powinieneś rozważyć, jest niedostępność JS. Pomyśl o postępującym zaczarowaniu lub pełnej wdzięku degradacji. Proponuję:
- dodanie domyślnie "więcej przycisku"
- Dodawanie reguł przelewu domyślnie
- ukrywanie przycisku i w razie potrzeby modyfikacje CSS w JS po porównaniu elementu.przewijanie do elementu.clientHeight
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-27 09:29:38
Tutaj jest fiddle do określenia, czy element został przepełniony za pomocą wrappera div z overflow: hidden i jQuery height (), aby zmierzyć różnicę między wrapperem a wewnętrzną zawartością 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);
});
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-11 15:12:35
setTimeout(function(){
isOverflowed(element)
},500)
function isOverflowed(element){
return element.scrollHeight > element.clientHeight || element.scrollWidth > element.clientWidth;
}
To zadziałało na mnie. Dziękuję.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-29 16:32:00
To jest rozwiązanie jQuery, które działało dla mnie. clientWidth
itd. nie zadziałało.
function is_overflowing(element, extra_width) {
return element.position().left + element.width() + extra_width > element.parent().width();
}
Jeśli to nie zadziała, upewnij się, że rodzic elementów ma żądaną szerokość (osobiście musiałem użyć parent().parent())
. position
jest względem rodzica. Dodałem również extra_width
, ponieważ moje elementy ("tagi") zawierają obrazy, które ładują się niewiele czasu, ale podczas wywołania funkcji mają zerową szerokość, psując obliczenia. Aby to obejść, używam następującego kodu wywołującego:
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();
}
});
Hope this pomaga.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-01 12:09:52
Alternatywą jquery dla odpowiedzi jest użycie klawisza [0], aby uzyskać dostęp do surowego elementu, takiego jak ten:
if ($('#elem')[0].scrollHeight > $('#elem')[0].clientHeight){
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-02-15 09:26:24