Tıklamayla belirli bir div öğesine yumuşak kaydırma


94

Yapmaya çalıştığım şey, bir düğmeyi tıkladığınızda, aşağıya (sorunsuz bir şekilde) sayfadaki belirli bir div'e kaydırılmasını sağlamaktır.

İhtiyacım olan şey, düğmeyi tıklarsanız, div 'saniye'ye düzgün kaydırır.

.first {
    width: 100%;
    height: 1000px;
    background: #ccc;
}

.second {
    width: 100%;
    height: 1000px;
    background: #999;
}
<div class="first"><button type="button">Click Me!</button></div>
<div class="second">Hi</div>


Bu eklentiyi deneyebilirsiniz Yine de, bu çok daha kullanıcı dostudur. Hemen hemen JS dosyasını başlıkta bağlamanız ve işaretlemenizi çalışması için uygun şekilde değiştirmeniz gerekir.
joshrathke

1
bu size yardımcı olacaktır :: stackoverflow.com/questions/3432656/…
Sudhir Bastakoti

Yanıtlar:


178

yapmak:

$("button").click(function() {
    $('html,body').animate({
        scrollTop: $(".second").offset().top},
        'slow');
});

Güncellenmiş Jsfiddle


Burada javaScript mi ​​yoksa jQuery mi kullanıyorsunuz?

1
@FahadUddin jQuery.
Sudhir Bastakoti

@SudhirBastakoti: JsFiddle neden jquery kitaplığını o sayfaya eklemiyor?

@Sudhir Bastakoti, ancak birçok kullanıcı düzgün kaydırmanın olmadığından şikayet ediyor.
Maulik

40

JQuery, Mootools, Prototype vb.Gibi JS kitaplıklarını kullanan pek çok yumuşak kaydırma örneği vardır.

Aşağıdaki örnek saf JavaScript üzerinedir. Sayfada jQuery / Mootools / Prototype yoksa veya yoğun JS kitaplıklarıyla sayfayı aşırı yüklemek istemiyorsanız, örnek yardımcı olacaktır.

http://jsfiddle.net/rjSfP/

HTML Bölümü:

<div class="first"><button type="button" onclick="smoothScroll(document.getElementById('second'))">Click Me!</button></div>
<div class="second" id="second">Hi</div>

CSS Bölümü:

.first {
    width: 100%;
    height: 1000px;
    background: #ccc;
}

.second {
    width: 100%;
    height: 1000px;
    background: #999;
}

JS Bölümü:

window.smoothScroll = function(target) {
    var scrollContainer = target;
    do { //find scroll container
        scrollContainer = scrollContainer.parentNode;
        if (!scrollContainer) return;
        scrollContainer.scrollTop += 1;
    } while (scrollContainer.scrollTop == 0);

    var targetY = 0;
    do { //find the top of target relatively to the container
        if (target == scrollContainer) break;
        targetY += target.offsetTop;
    } while (target = target.offsetParent);

    scroll = function(c, a, b, i) {
        i++; if (i > 30) return;
        c.scrollTop = a + (b - a) / 30 * i;
        setTimeout(function(){ scroll(c, a, b, i); }, 20);
    }
    // start scrolling
    scroll(scrollContainer, scrollContainer.scrollTop, targetY, 0);
}

Bunu kullanıyorum ve harika çalışıyor. Yine de kaydırmayı nasıl yavaşlatırım?
jamescampbell

Bu kodda sabit navbar için ofsetin nasıl ekleneceği hakkında bir fikriniz var mı? İşte keman
Plavookac

3
5 yıl sonra hala yardımcı oluyor
Owaiz Yusufi

9

Nico'nun cevabıyla biraz oynadım ve gergin hissettim. Biraz araştırma yaptım ve window.requestAnimationFrameher bir yeniden boyama döngüsünde çağrılan bir işlev olan buldum . Bu, daha temiz görünen bir animasyona izin verir. Hala adım boyutu için iyi varsayılan değerlere odaklanmaya çalışıyorum, ancak benim örneğim için bu uygulamayı kullanarak işler oldukça iyi görünüyor.

var smoothScroll = function(elementId) {
    var MIN_PIXELS_PER_STEP = 16;
    var MAX_SCROLL_STEPS = 30;
    var target = document.getElementById(elementId);
    var scrollContainer = target;
    do {
        scrollContainer = scrollContainer.parentNode;
        if (!scrollContainer) return;
        scrollContainer.scrollTop += 1;
    } while (scrollContainer.scrollTop == 0);

    var targetY = 0;
    do {
        if (target == scrollContainer) break;
        targetY += target.offsetTop;
    } while (target = target.offsetParent);

    var pixelsPerStep = Math.max(MIN_PIXELS_PER_STEP,
                                 (targetY - scrollContainer.scrollTop) / MAX_SCROLL_STEPS);

    var stepFunc = function() {
        scrollContainer.scrollTop =
            Math.min(targetY, pixelsPerStep + scrollContainer.scrollTop);

        if (scrollContainer.scrollTop >= targetY) {
            return;
        }

        window.requestAnimationFrame(stepFunc);
    };

    window.requestAnimationFrame(stepFunc);
}

1
@Alfonso Yukarıya bakınız. Bu, basitçe, önceki bir cevapta yer alan nico kodunun optimize edilmiş bir versiyonudur.
Ned rockson

@NedRockson Benim için çalışmıyor konsol mesajı "Yakalanmamış TypeError: Boş değerin 'parentNode' özelliği okunamıyor" ama nico'ın kodu çalışıyor, ne yapmalıyım ki temiz animasyon uygulayabilir?
Kartik Watwani

@KartikWatwani Bu, satır okumasında scrollContainer = scrollContainer.parentNodescrollContainer'ın boş olduğu anlamına gelir . Bu muhtemelen, elementIdbu işlevi çağırırken doğru olanı geçmediğiniz anlamına gelir . Bu komut dosyasını, elementId'nin bulunmadığı bir sayfada çalıştırmanız da mümkündür.
Ned rockson

@NedRockson elementIdYanlış olsaydı @nico örneğinde aynı hatayı alırdım ama bu durumda kaydırma çalışıyor ama sorunsuz olmuyor.
Kartik Watwani

requestAnimationFrameBunun yerine kullanmak setTimeout, gitmenin yoludur. setTimeoutanimasyonlar için kullanılmamalıdır.
tsnkff


2

Ned Rockson'ın sürümünü aldım ve yukarı doğru kaydırmalara izin verecek şekilde ayarladım.

var smoothScroll = function(elementId) {
  var MIN_PIXELS_PER_STEP = 16;
  var MAX_SCROLL_STEPS = 30;
  var target = document.getElementById(elementId);
  var scrollContainer = target;
  do {
    scrollContainer = scrollContainer.parentNode;
    if (!scrollContainer) return;
    scrollContainer.scrollTop += 1;
  } while (scrollContainer.scrollTop === 0);

  var targetY = 0;
  do {
    if (target === scrollContainer) break;
    targetY += target.offsetTop;
  } while (target = target.offsetParent);

  var pixelsPerStep = Math.max(MIN_PIXELS_PER_STEP,
    Math.abs(targetY - scrollContainer.scrollTop) / MAX_SCROLL_STEPS);

  var isUp = targetY < scrollContainer.scrollTop;

  var stepFunc = function() {
    if (isUp) {
      scrollContainer.scrollTop = Math.max(targetY, scrollContainer.scrollTop - pixelsPerStep);
      if (scrollContainer.scrollTop <= targetY) {
        return;
      }
    } else {
        scrollContainer.scrollTop = Math.min(targetY, scrollContainer.scrollTop + pixelsPerStep);

      if (scrollContainer.scrollTop >= targetY) {
        return;
      }
    }

    window.requestAnimationFrame(stepFunc);
  };

  window.requestAnimationFrame(stepFunc);
};

2

Düzgün kaydırma elde etmek için temel css kullanabilirsiniz

html {
  scroll-behavior: smooth;
}

0

Ned Rockson temelde bu soruyu yanıtlıyor. Ancak çözümünde ölümcül bir kusur var. Hedeflenen öğe, sayfanın alt kısmına görüntü alanı yüksekliğinden daha yakın olduğunda, işlev çıkış ifadesine ulaşmaz ve kullanıcıyı sayfanın altına hapseder. Bu, basitçe yineleme sayısını sınırlayarak çözülür.

var smoothScroll = function(elementId) {
    var MIN_PIXELS_PER_STEP = 16;
    var MAX_SCROLL_STEPS = 30;
    var target = document.getElementById(elementId);
    var scrollContainer = target;
    do {
        scrollContainer = scrollContainer.parentNode;
        if (!scrollContainer) return;
        scrollContainer.scrollTop += 1;
    } while (scrollContainer.scrollTop == 0);

    var targetY = 0;
    do {
        if (target == scrollContainer) break;
        targetY += target.offsetTop;
    } while (target = target.offsetParent);

    var pixelsPerStep = Math.max(MIN_PIXELS_PER_STEP,
                                 (targetY - scrollContainer.scrollTop) / MAX_SCROLL_STEPS);

    var iterations = 0;
    var stepFunc = function() {
        if(iterations > MAX_SCROLL_STEPS){
            return;
        }
        scrollContainer.scrollTop =
            Math.min(targetY, pixelsPerStep + scrollContainer.scrollTop);

        if (scrollContainer.scrollTop >= targetY) {
            return;
        }

        window.requestAnimationFrame(stepFunc);
    };

    window.requestAnimationFrame(stepFunc);
}
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.