Bir elemanın içeriğinin taşıp taşmadığını kontrol edin.


168

Bir elemanın dolup taşmadığını tespit etmenin en kolay yolu nedir?

Benim kullanım durumum, belirli bir içerik kutusunu 300 piksel yüksekliğiyle sınırlamak istiyorum. İç içerik bundan daha uzunsa, bir taşma ile keserim. Ancak taşmışsa, bir 'daha fazla' düğmesi göstermek istiyorum, ancak değilse o düğmeyi göstermek istemiyorum.

Taşmayı tespit etmenin kolay bir yolu var mı yoksa daha iyi bir yöntem var mı?

Yanıtlar:


89

Daha fazla içerik için yalnızca bir tanımlayıcı göstermek istiyorsanız, bunu saf CSS ile yapabilirsiniz. Bunun için saf kayan gölgeler kullanıyorum. İşin püf noktası kullanımıdır background-attachment: local;. CSS'niz şöyle görünür:

.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 adresinde bulabileceğiniz kod ve örnek

Ve burada bulabileceğiniz bir açıklama: http://lea.verou.me/2012/04/background-attachment-local/ .


1
Güzel fikir ama sizin örneğinizde arka plan (gölge) metnin arkasında olacaktır!
DreamTeK

Harika numara, ancak Chrome'da yalnızca altta statik gölge gösteriyor, asla kaybolmuyor ve üst gölge asla
Jared

235

Eleman dikey, yatay veya her iki şekilde taşabilir. DOM öğesi taşmışsa, bu işlev size bir boole değeri döndürecektir:

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

ES6 örneği:

const isOverflown = ({ clientWidth, clientHeight, scrollWidth, scrollHeight }) => {
    return scrollHeight > clientHeight || scrollWidth > clientWidth;
}

43
Harika çözüm! İşte bir jQuery varyantı (birlikte kullanılacak $("#element").overflown()):$.fn.overflown=function(){var e=this[0];return e.scrollHeight>e.clientHeight||e.scrollWidth>e.clientWidth;}
Sygmoral

@micnic merhaba, ionic2 kullanıyorum ve aynı şeyi yapmaya çalışıyorum ... ama işlev her zaman doğru döndürüyor ... işleri açısal 2'de yapmanın farklı bir yolu var mı
Yasir

@DavidBracoly, bu işlev saf DOM API içindir, Ionic / Angular ile deneyimim yok, sanırım orijinal DOM Elementini almalı ve bu işlevi kullanmalısınız
micnic

4
Yalnızca Firefox için: element.addEventListener ("overflow", () => log( "overflow" ), false);Referans: taşma olayı
Reza

19

Karşılaştırma element.scrollHeightiçin element.clientHeightgörev yapmalıdır.

Aşağıda, Element.scrollHeight ve Element.clientHeight'ı açıklayan MDN'den gelen resimler bulunmaktadır.

Kaydırma Yüksekliği

Müşteri Yüksekliği


2
Evet, ama tuhaf moda göre en çok işe yarıyor - ve yayınlanan diğer çözümlerden çok daha basit.
Bergi

@Harry: Mevcut tüm tarayıcılarda desteklenir (en azından masaüstü olanlar), bu nedenle resmi olarak standart olmaması önemli değil.
Marat Tanalin

1
Burada bu özellikler her zaman aynı değerlere sahiptir.
koppor

8

Yukarıdaki cevapları (ör. Gizli taşma ve yüksekliği kullanarak) ve aynı zamanda taşan öğeleri nasıl genişleteceğinizi / daraltacağınızı gösteren çok parçalı bir kod parçası yaptım

Örnek 1: https://codepen.io/Kagerjay/pen/rraKLB (Gerçekten basit bir örnek, javascript yok, sadece taşan öğeleri kırpmak için)

Örnek 2: https://codepen.io/Kagerjay/pen/LBErJL (Tek olay işleyici, taşan öğelerde daha fazlasını / gösterişsiz gösterir)

Örnek 3: https://codepen.io/Kagerjay/pen/MBYBoJ (Birçoğundaki çoklu etkinlik işleyicisi daha fazla gösterir / taşan öğelerde daha az gösterir)

I olan ve aşağıda örnek 3 bağlı bu ayrıntılı biraz olabilir, böylece Jade / Pug kullanın. Anlaşılmasını kolaylaştırdığım kod kalemlerini kontrol etmenizi öneririm.

// 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>


4

Bunun gibi bir şey olur mu : http://jsfiddle.net/Skooljester/jWRRA/1/ çalışır? Yalnızca içeriğin yüksekliğini kontrol eder ve bunu kabın yüksekliğiyle karşılaştırır. Daha büyükse, bir "Daha fazla göster" düğmesi eklemek için koda koyabilirsiniz.

Güncelleme: Kabın üst kısmına "Daha Fazla Göster" düğmesi oluşturmak için kod eklendi.


3

JQuery kullanıyorsanız, bir numara deneyebilirsiniz: dış overflow: hiddendiv ile içerik ve iç div yapın. Ardından .height(), iç div yüksekliğinin dış div yüksekliğinden büyük olup olmadığını kontrol etmek için işlevi kullanın. İşe yarayacağından emin değilim ama bir dene.


2

Kapsülleme nedenleriyle Element'i genişlettim. Miknik cevaptan.

/*
 * isOverflowing
 * 
 * Checks to see if the element has overflowing content
 * 
 * @returns {}
 */
Element.prototype.isOverflowing = function(){
    return this.scrollHeight > this.clientHeight || this.scrollWidth > this.clientWidth;
}

Bunu böyle kullan

let elementInQuestion = document.getElementById("id_selector");

    if(elementInQuestion.isOverflowing()){
        // do something
    }

1

js kullanarak çocuğun offsetHeightebeveynlerden daha fazla olup olmadığını kontrol edin .. eğer öyleyse, ebeveynlerin scroll/hidden/autohangisini istersen taşmasını sağla ve ayrıca display:blockdaha fazla div ..


1

Sınırları öteleme ebeveynine göre kontrol edebilirsiniz.

// 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;
}

Bunu bir öğeyi iletirseniz, sınırlarının tamamen bir kap içinde olup olmadığını size söyleyecektir ve açık bir kap sağlanmadıysa, varsayılan olarak öğenin uzaklığı üst öğesi olacaktır. Kullanır


1

Dikkate almanız gereken bir diğer konu da JS'nin kullanılamamasıdır. Aşamalı büyü veya zarif bozulmayı düşünün. Öneririm:

  • varsayılan olarak "daha fazla düğme" eklemek
  • varsayılan olarak taşma kuralları ekleme
  • element.scrollHeight ile element.clientHeight karşılaştırıldıktan sonra JS'de gizli düğmesi ve gerekirse CSS değişiklikleri

1

Burada, bir öğenin taşma içeren bir sarmalayıcı div kullanılarak taşıp taşmadığını belirlemeye yönelik bir keman vardır: sarmalayıcı ile iç içerik div arasındaki farkı ölçmek için hidden ve JQuery height ().

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);
});

Kaynak: jsfiddle.net'teki Çerçeveler ve Uzantılar


1
setTimeout(function(){
    isOverflowed(element)           
},500)

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

Bu benim için çalıştı. Teşekkür ederim.


4
Bunun micnic'in cevabından farkı nedir?
carefulnow1

1

Bu, benim için çalışan jQuery çözümü. clientWidthvb işe yaramadı.

function is_overflowing(element, extra_width) {
    return element.position().left + element.width() + extra_width > element.parent().width();
}

Bu işe yaramazsa, öğelerin ebeveyninin istenen genişliğe sahip olduğundan emin olun (kişisel olarak, kullanmak zorundaydım parent().parent()). positionEbeveyne göre. extra_widthÖğelerim ("etiketler") de kısa zaman alan resimler içerdiği için de dahil ettim. yük, ancak işlev çağrısı sırasında sıfır genişliğe sahipler ve hesaplamayı bozuyor. Bunu aşmak için aşağıdaki çağrı kodunu kullanıyorum:

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();
    }
});

Bu yardımcı olur umarım.


0

Cevaba alternatif jquery, aşağıdaki gibi ham öğeye erişmek için [0] tuşunu kullanmaktır:

if ($('#elem')[0].scrollHeight > $('#elem')[0].clientHeight){
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.