Kullanıcı yukarı kaydırmadıkça taşma divını aşağı kaydırın


224

Sadece 300 piksel büyüklüğünde bir div var ve sayfa yüklendiğinde içeriğin altına kaydırmak istiyorum. Bu div, dinamik olarak eklenmiş içeriğe sahiptir ve aşağı kaydırılmaya devam etmelidir. Eğer kullanıcı yukarı kaydırmaya karar verirse, kullanıcı tekrar aşağı kaydırıncaya kadar aşağıya atlamasını istemiyorum.

Kullanıcı yukarı kaydırmadıkça ve kullanıcı tekrar aşağıya kaydırdığında altta kaydırılacak bir div olması mümkün mü, yeni dinamik içerik eklendiğinde bile kendini altta tutması gerekir. Bunu yaratarak nasıl gideceğim.


1
css pozisyonu üstünü altta tutun {position : relative; bottom:0;}. Kullanıcı kaydırma yaptıktan sonra css özelliğini kaldırın.
TCHdvlp

Bir cevabı kabul etmediğin için şu soruyu sormak istiyorum: bu senin için işe yaradı mı?
Bay Manhattan


1
Bu soru için yeni , 2020 yılında css snap denemek gerekir .
wener

Yanıtlar:


136

Bu size yardımcı olabilir:

var element = document.getElementById("yourDivID");
element.scrollTop = element.scrollHeight;

[EDIT], yorumu eşleştirmek için ...

function updateScroll(){
    var element = document.getElementById("yourDivID");
    element.scrollTop = element.scrollHeight;
}

içerik eklendiğinde updateScroll () işlevini çağırın veya bir zamanlayıcı ayarlayın:

//once a second
setInterval(updateScroll,1000);

SADECE kullanıcı hareket etmediyse güncellemek istiyorsanız:

var scrolled = false;
function updateScroll(){
    if(!scrolled){
        var element = document.getElementById("yourDivID");
        element.scrollTop = element.scrollHeight;
    }
}

$("#yourDivID").on('scroll', function(){
    scrolled=true;
});

3
Bu iyi sayfa yükleme sırasında aşağı kaydırın, ancak kullanıcı yukarı kaydırmadıkça dinamik içerik eklendiğinde altta kalmak gerekir.
Robert E. McIntosh


@TvE Desteğin eklenebilmesi mümkün değil mi?
Barkermn01

6
Kötü çözüm. setIntervalBu hafif sorun için bir eklemek için hiçbir neden yoktur .
ehancrist

6
@ethancrist Ancak, alternatif yok ... omuz silkme.
Jarett Lloyd

180

Bunu sadece CSS ile çalıştırabildim.

Hile kullanmak display: flex;veflex-direction: column-reverse;

Tarayıcı, alt kısmı üst kısmı gibi davranır. Desteği hedeflediğiniz tarayıcıları varsayarsak, flex-boxtek uyarı işaretlemenin ters sırada olması gerektiğidir.

İşte çalışan bir örnek. https://codepen.io/jimbol/pen/YVJzBg


42
Ek bir sargı ekleyerek ve overflow:auto; display:flex; flex-direction:column-reverse;iç sargı yerine dış sargıya uygulayarak içeriği tersine çevirmek zorunda kalabilirsiniz .
Nathan Arthur

6
muhtemelen en iyi çözüm çünkü javascript gerekmez.
Amit Kumar Khare

3
@NathanArthur u da real mvp
php_nub_qq

13
@NathanArthur Aslında, her şeyi geri almak için konteyner altına bir div eklerseniz: codepen.io/anon/pen/pdrLEZ
Coo

6
Ne yazık ki bu çözüm Firefox'ta çalışmıyor :(
Stuart

166

Ben sadece bunu uyguladım ve belki benim yaklaşımımı kullanabilirsiniz.

Diyelim ki şu HTML'ye sahibiz:

<div id="out" style="overflow:auto"></div>

Ardından, aşağıya doğru kaydırılıp kaydırılmadığını kontrol edebiliriz:

var out = document.getElementById("out");
// allow 1px inaccuracy by adding 1
var isScrolledToBottom = out.scrollHeight - out.clientHeight <= out.scrollTop + 1;

scrollHeight , taşma nedeniyle görünmeyen alanlar da dahil olmak üzere öğenin yüksekliğini verir. clientHeight size CSS yüksekliğini verir veya başka bir şekilde öğenin gerçek yüksekliğini söyler. Her iki yöntem de yüksekliği döndürür margin, bu yüzden endişelenmenize gerek yoktur. scrollTop size dikey kaydırmanın konumunu verir. 0 en üstte ve max öğenin scrollHeight öğesi ile eleman yüksekliğinin kendisidir. Kaydırma çubuğunu kullanırken, kaydırma çubuğunu en alta kadar aşağı indirmek zor olabilir (benim için Chrome'da). 1 piksellik bir yanlışlıkla attım. Yani isScrolledToBottomkaydırma çubuğu alttan 1px olsa bile geçerli olacak. Bunu sizin için doğru olan her şeye ayarlayabilirsiniz.

Ardından, öğenin scrollTop öğesini en alta ayarlamak önemlidir.

if(isScrolledToBottom)
    out.scrollTop = out.scrollHeight - out.clientHeight;

Konsepti göstermeniz için bir keman yaptım: http://jsfiddle.net/dotnetCarpenter/KpM5j/

DÜZENLEME: zaman Eklenen kod parçacığı netleştirmek için isScrolledToBottomolduğunu true.

Kaydırma çubuğunu alta yapıştır

const out = document.getElementById("out")
let c = 0

setInterval(function() {
    // allow 1px inaccuracy by adding 1
    const isScrolledToBottom = out.scrollHeight - out.clientHeight <= out.scrollTop + 1

    const newElement = document.createElement("div")

    newElement.textContent = format(c++, 'Bottom position:', out.scrollHeight - out.clientHeight,  'Scroll position:', out.scrollTop)

    out.appendChild(newElement)

    // scroll to bottom if isScrolledToBottom is true
    if (isScrolledToBottom) {
      out.scrollTop = out.scrollHeight - out.clientHeight
    }
}, 500)

function format () {
  return Array.prototype.slice.call(arguments).join(' ')
}
#out {
    height: 100px;
}
<div id="out" style="overflow:auto"></div>
<p>To be clear: We want the scrollbar to stick to the bottom if we have scrolled all the way down. If we scroll up, then we don't want the content to move.
</p>


22
Bu aslında belirtilen soruyu gerçekleştiren tek çözümdür. Ve doğru cevap olarak işaretlenmiş olmalı.
preezzzy

1
@dotnetCarpenter: Size ihtiyaç olduğuna olarak bana bakıyor if(!isScrolledToBottom)testi bana yanlış görünüyor (ve iş vermedi: my tamir ettim dek kod).
luskwater

1
@ lukkwater düzeltmenizle bir fsfiddle sağlayabilir misiniz? Sorunu anlamıyorum out.scrollHeight - out.clientHeight <= out.scrollTop + 1. CSS'nizde dolgu kullanıyor musunuz?
dotnetCarpenter

2
Aradığım şey buydu. Ve bu OP'nin sorduğu sorunun cevabı. Teşekkürler dotnetCarperter.
Luis Menjivar

1
ScrollTop'u çağırdığında kimse 0 alıyorsa, document.getScrollingElementburada önerildiği gibi kullanılmasını öneririm : stackoverflow.com/questions/36227559/scrolltop-always-returns-0/…
Dane Jordan

29
$('#yourDiv').scrollTop($('#yourDiv')[0].scrollHeight);

Canlı demo: http://jsfiddle.net/KGfG2/


4
Bu iyi sayfa yükleme sırasında aşağı kaydırın, ancak kullanıcı yukarı kaydırmadıkça dinamik içerik eklendiğinde altta kalmak gerekir.
Robert E. McIntosh

Bu mükemmel çalışıyor. Dinamik içerikle güncelleme yapıyorum ve kaydırma her zaman en altta.
Andy Bajka

14
$('#div1').scrollTop($('#div1')[0].scrollHeight);

Or animated:

$("#div1").animate({ scrollTop: $('#div1')[0].scrollHeight}, 1000);

1
Bu iyi sayfa yükleme sırasında aşağı kaydırın, ancak kullanıcı yukarı kaydırmadıkça dinamik içerik eklendiğinde altta kalmak gerekir.
Robert E. McIntosh

İlk atışta div çok büyüdüğünde bu işe yaramaz. örneğin Açısal-js, tepki js, Meteor Blaze şablon yükleme, bu çalışmaz.
Ankur Soni

Bu benim için çalıştı. Bence söz konusu div tutarlı bir yükseklikte kalacaksa iyi çalışıyor. Dinamik yüksekliklerle test etmedim.
doij790

11

2020 yılında kullanabilirsiniz css çırpıda , ancak Chrome 81 düzen değişikliği öncesinde edecek tetik yeniden geçmeli değil , bir ui sohbet saf css Chrome 81 üzerinde çalışır, ayrıca kontrol edebilirsiniz Can I kullanımı CSS çırpıda .

Bu demo, görünürse son öğeyi yapıştıracaktır, efekti görmek için aşağı kaydırın.

.container {
  overflow-y: scroll;
  overscroll-behavior-y: contain;
  scroll-snap-type: y mandatory;
}

.container > div > div:last-child {
  scroll-snap-align: end;
}

.container > div > div {
  background: lightgray;
  height: 3rem;
  font-size: 1.5rem;
}
.container > div > div:nth-child(2n) {
  background: gray;
}
<div class="container" style="height:6rem">
<div>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</div>
</div>

resim açıklamasını buraya girin


5

.cont{
height: 100px;
overflow-x: hidden;
overflow-y: auto;
transform: rotate(180deg);
direction:rtl;
text-align:left;
}
ul{
overflow: hidden;
transform: rotate(180deg);
}
<div class="cont"> 
 <ul>
   <li>0</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>9</li>
   <li>10</li>  
 </ul>
</div>

  1. Run code snippetetkisi görmek için. (PS: Çalışmıyorsa şunu Run code snippetdeneyin: https://jsfiddle.net/Yeshen/xm2yLksu/3/ )

  2. Nasıl çalışır:

Varsayılan taşma yukarıdan aşağıya kaydırmadır.

transform: rotate(180deg) aşağıdan yukarıya doğru dinamik blok kaydırma veya yükleme yapabilirsiniz.

  1. Orijinal fikir:

https://blog.csdn.net/yeshennet/article/details/88880252


Lütfen kodunuzun OP'nin sorusunu nasıl çözdüğü hakkında daha fazla açıklama ekleyin
jro

1, ek bir giriş ekledi. 2, lütfen Run code snippet, doğrudan etkisini görmek.
yisheng wu

Kod çalıştırma snippet düğmesi benim için görünmüyor. Biçimlendirmenizi kontrol edin
jro

Bu harika. Lütfen cevabı cevabınıza ekleyin
jro

2
Çok yaratıcı bir çözüm. Ancak, faremin kaydırma tekerleğinin normal çalışmasını tersine çevirir. Yukarı çıkmak için "aşağı" kaydırmam ve tam tersi.
mfluehr

3
$('#yourDivID').animate({ scrollTop: $(document).height() }, "slow");
return false;

Bu , div öğesine dinamik içerik eklense bile kaydırma çubuğunun her zaman en alt konumda olmasını sağlamak için özelliği #yourDivIDkullanma yüksekliğinden ScrollTop Konumunu hesaplar $(document).height(). Bu yardımcı olur umarım. Ancak, yukarı kaydırıp fare işaretçisini kaydıraçtan bıraksak bile küçük bir hata var, otomatik olarak alt konuma gelecektir. Birisi bunu düzeltebilirse de iyi olur.


2
//Make sure message list is scrolled to the bottom
var container = $('#MessageWindowContent')[0];
var containerHeight = container.clientHeight;
var contentHeight = container.scrollHeight;

container.scrollTop = contentHeight - containerHeight;

İşte dotnetCarpenter'ın cevabına dayanan versiyonum. Benim yaklaşım saf bir jQuery olduğunu ve ben işleri biraz daha açık hale getirmek için değişkenleri adlandırdı .. Ne oluyor içerik yüksekliği daha büyük ise istenen sonuç elde etmek için ekstra mesafe aşağı kaydırmak konteyner.

IE ve krom ile çalışır ..


2

Jim Hall'un cevabı tercih edilir, çünkü yukarı kaydırdığınızda gerçekten aşağıya kaymazken, aynı zamanda saf CSS'dir.

Ancak maalesef bu kararlı bir çözüm değildir: Kromda (muhtemelen yukarıdaki dotnetCarpenter tarafından açıklanan scrollTop1 piksel boyutundan dolayı), kullanıcı etkileşimi olmadan bile (öğe eklendikten sonra) 1 piksel yanlış davranır. Ayarlayabilirsiniz scrollTop = scrollHeight - clientHeight, ancak başka bir öğe eklendiğinde div öğesini yerinde tutacaktır; diğer bir deyişle, "kendini altta tut" özelliği artık çalışmıyor.

Kısacası, az miktarda Javascript (iç çekme) eklemek bunu düzeltir ve tüm gereksinimleri karşılar:

Https://codepen.io/anon/pen/pdrLEZ gibi bir şey (örnek Coo tarafından) ve listeye bir öğe ekledikten sonra, aşağıdakiler de:

container = ...
if(container.scrollHeight - container.clientHeight - container.scrollTop <= 29) {
    container.scrollTop = container.scrollHeight - container.clientHeight;
}

burada 29 bir satırın yüksekliğidir.

Bu nedenle, kullanıcı yarım satır yukarı kaydırdığında (eğer mümkünse?), Javascript bunu yoksayar ve en alta kaydırır. Ama sanırım bu ihmal edilebilir. Ve Chrome 1 pikselini düzeltiyor.


2

İşte Ryan Hunt'ın bir blog yayınına dayanan bir çözüm . overflow-anchorKaydırma konumunu, kaydırılan içeriğin altındaki öğeye sabitleyen CSS özelliğine bağlıdır .

const messages = [
  'Expect rain today.',
  'Tomorrow will be sunny.',
  'Snow is coming next week.',
  'Hailstorms are imminent.',
];

function addMessage() {
  const $message = document.createElement('div');
  $message.className = 'message';
  $message.innerText = messages[(Math.random() * messages.length) | 0];
  $messages.insertBefore($message, $anchor);

  // Trigger the scroll pinning when the scroller overflows
  if (!overflowing) {
    overflowing = isOverflowing($scroller);
    $scroller.scrollTop = $scroller.scrollHeight;
  }
}

function isOverflowing($el) {
  return $el.scrollHeight > $el.clientHeight;
}

const $scroller = document.querySelector('.scroller');
const $messages = document.querySelector('.messages');
const $anchor = document.querySelector('.anchor');
let overflowing = false;

setInterval(addMessage, 1000);
.scroller {
  overflow: auto;
  height: 90vh;
  max-height: 11em;
  background: #555;
}

.messages > * {
  overflow-anchor: none;
}

.anchor {
  overflow-anchor: auto;
  height: 1px;
}

.message {
  margin: .3em;
  padding: .5em;
  background: #eee;
}
<section class="scroller">
  <div class="messages">
    <div class="anchor"></div>
  </div>
</section>

Not overflow-anchorBu çözüm şu anda tüm tarayıcılarda çalışmıyor bu yüzden, Safari veya Edge anda işi yapmaz.


1

Böyle bir şey kullanabilirsiniz,

var element = document.getElementById("yourDivID");
window.scrollTo(0,element.offsetHeight);

Lütfen açıklayınız!
Szabolcs

1.scrollTo, pencerenin tamamını belirli koordinatlara kaydıran bir yöntemdir.
Yashesh Chauhan

0

İşte böyle yaklaştım. Div yüksekliğim 650 piksel. Kaydırma yüksekliği alt kısmın 150 pikselinde ise otomatik kaydırmaya karar verdim. Aksi takdirde, kullanıcı için bırakın.

if (container_block.scrollHeight - container_block.scrollTop < 800) {
                    container_block.scrollTo(0, container_block.scrollHeight);
}
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.