Div içindeki bir öğeye nasıl geçilir?


170

Bir kaydırılan var divve ben bu zorlayacaktır üzerine tıklayın bir bağlantı olmasını istediğiniz divbir öğe içini görüntülemek için ilerleyin. Onun JavasSript böyle yazdı:

document.getElementById(chr).scrollIntoView(true);

ancak bu, sayfayı kaydırırken tüm sayfayı kaydırır div. Bunu nasıl düzeltirim?

Böyle söylemek istiyorum

MyContainerDiv.getElementById(chr).scrollIntoView(true);

Scrolltop her zaman kullanılabilir bir değer döndürmez. Bir kullanma eğiliminde SetTimeoutiçinde $(document).ready({})işlev ve sette focus()sizi ilerleyin istediğiniz öğeye. Benim için çalışıyor
DerpyNerd

Yanıtlar:


342

Görünüme kaydırmak istediğiniz öğenin, üst öğesine (kaydırma div kabı) göre üst ofsetini almanız gerekir:

var myElement = document.getElementById('element_within_div');
var topPos = myElement.offsetTop;

TopPos değişkeni, artık kaydırma div'inin üst kısmı ile görünür olmasını istediğiniz öğe (piksel olarak) arasındaki mesafeye ayarlanmıştır.

Şimdi div'e şunu kullanarak bu konuma geçmesini söyleriz scrollTop:

document.getElementById('scrolling_div').scrollTop = topPos;

Prototip JS çerçevesini kullanıyorsanız, aynı şeyi şu şekilde yaparsınız:

var posArray = $('element_within_div').positionedOffset();
$('scrolling_div').scrollTop = posArray[1];

Yine, bu div'ı görmek istediğiniz öğenin tam olarak en üstte olmasını sağlayacak şekilde kaydırır (veya bu mümkün değilse, görünür olduğu kadar aşağı kaydırılır).


9
Bu gerçekten yardımcı oldu! Kaydırma işlemini birden çok kez ayarlamak istiyorsanız, geçerli kaydırma konumunuza göre dengelemeniz gerekir. JQuery'de şöyle yaptım: $ ('# scrolling_div'). ScrollTop ($ ('# scrolling_div'). ScrollTop () + $ ('# element_within_div'). Position (). Top);
Will

3
İsteyen dikkat myElement.offsetTopbir olabilir irade tetik Yeniden düzenleme (düzen dayak) performans darboğazı
Kestutis

27
Kaydırma üst öğesini css ile ayarlamayı unutmayın: position: relativeaksi takdirde yaptığım gibi hata ayıklamak için çok zaman harcayacaksınız.
savedario

2
Üst öğe ( ) için overflow-yözelliği ayarlamak zorunda kaldı , aksi takdirde çalışma değildi. İçin varsayılan css değer özelliği olduğunu ve aynı zamanda manuel kaydırma mümkün kılan rağmen olmaz işlev (hatta ile js kodu ..)scrollscrolling_divoverflowauto{psition: relative}
Evgenia Manolova

2
Ek bilgi: .offsetTop 0 değerini döndürebilir. Ardından bir üst öğeye başvurmalı ve tekrar denemelisiniz. Ben etiketler için yaptım h4sonra divo articleetiketi ve articlebenim için çalıştı.
Fenio

66

DIV'de kaydırmak istediğiniz öğenin konumunu bulmanız ve scrollTop özelliğini ayarlamanız gerekir.

divElem.scrollTop = 0;

Güncelleme :

Yukarı veya aşağı hareket etmek için örnek kod

  function move_up() {
    document.getElementById('divElem').scrollTop += 10;
  }

  function move_down() {
    document.getElementById('divElem').scrollTop -= 10;
  }

3
görünümü kaydırmak istiyorum, belli bir değer ile kaydırma olmadığını görmek için
Amr Elgarhy

39

Yöntem 1 - Bir öğenin içindeki bir öğeye düzgün kaydırma

var box = document.querySelector('.box'),
    targetElm = document.querySelector('.boxChild'); // <-- Scroll to here within ".box"

document.querySelector('button').addEventListener('click', function(){
   scrollToElm( box, targetElm , 600 );   
});


/////////////

function scrollToElm(container, elm, duration){
  var pos = getRelativePos(elm);
  scrollTo( container, pos.top , 2);  // duration in seconds
}

function getRelativePos(elm){
  var pPos = elm.parentNode.getBoundingClientRect(), // parent pos
      cPos = elm.getBoundingClientRect(), // target pos
      pos = {};

  pos.top    = cPos.top    - pPos.top + elm.parentNode.scrollTop,
  pos.right  = cPos.right  - pPos.right,
  pos.bottom = cPos.bottom - pPos.bottom,
  pos.left   = cPos.left   - pPos.left;

  return pos;
}
    
function scrollTo(element, to, duration, onDone) {
    var start = element.scrollTop,
        change = to - start,
        startTime = performance.now(),
        val, now, elapsed, t;

    function animateScroll(){
        now = performance.now();
        elapsed = (now - startTime)/1000;
        t = (elapsed/duration);

        element.scrollTop = start + change * easeInOutQuad(t);

        if( t < 1 )
            window.requestAnimationFrame(animateScroll);
        else
            onDone && onDone();
    };

    animateScroll();
}

function easeInOutQuad(t){ return t<.5 ? 2*t*t : -1+(4-2*t)*t };
.box{ width:80%; border:2px dashed; height:180px; overflow:auto; }
.boxChild{ 
  margin:600px 0 300px; 
  width: 40px;
  height:40px;
  background:green;
}
<button>Scroll to element</button>
<div class='box'>
  <div class='boxChild'></div>
</div>

Yöntem 2 - Element.scrollIntoView Kullanımı :

Tarayıcı desteğinin bunun için harika olmadığını unutmayın

var targetElm = document.querySelector('.boxChild'),  // reference to scroll target
    button = document.querySelector('button');        // button that triggers the scroll
  
// bind "click" event to a button 
button.addEventListener('click', function(){
   targetElm.scrollIntoView()
})
.box {
  width: 80%;
  border: 2px dashed;
  height: 180px;
  overflow: auto;
  scroll-behavior: smooth; /* <-- for smooth scroll */
}

.boxChild {
  margin: 600px 0 300px;
  width: 40px;
  height: 40px;
  background: green;
}
<button>Scroll to element</button>
<div class='box'>
  <div class='boxChild'></div>
</div>

Yöntem 3 - CSS kaydırma davranışını kullanma :

.box {
  width: 80%;
  border: 2px dashed;
  height: 180px;
  overflow-y: scroll;
  scroll-behavior: smooth; /* <--- */
}

#boxChild {
  margin: 600px 0 300px;
  width: 40px;
  height: 40px;
  background: green;
}
<a href='#boxChild'>Scroll to element</a>
<div class='box'>
  <div id='boxChild'></div>
</div>


1
Kaydırma davranış IE desteklenmediğini Not / Kenar / Safari
kılıfları

1
@ sheats - tam olarak büyük yazı tipi boyutuna yerleştirdiğim MDN dokümantasyon bağlantısında olduğunu söylüyor. Bu tarayıcılarda işe yaramasa bile, kullanmamanız gerektiği anlamına gelmez. "Kural" yoktur, her şey tüm tarayıcılarda aynı şekilde davranmalıdır. Modern tarayıcılar sihir yapabilirse, sihir yapmalarına izin verin.
vsync

Bu yazı, kaydırılabilir bir öğe yerine belgenin tamamını kaydırmakla ilgilidir.

@ DoMiNeLa10 - Bu bir varsayım. OP, meselesini açıklamak için keyfi bir örnek sunmuş olabilir. Ayrıca, OP ana endişe değil, sağlıklı bir çözüm arayan arama motorlarından gelen insanlar ve büyük olasılıkla özellikle OP ihtiyaçlarına cevap vermek onlara yardımcı olmayacak ve bu web sitesinin amacı, çok yardımcı olabilecek sağlam cevaplar oluşturmaktır. olabildiğince. Cevabım ikisini de sağlıyor .
vsync

12

Bir öğeyi yalnızca gerektiğinde div görünümüne kaydırmak için bu scrollIfNeededişlevi kullanabilirsiniz :

function scrollIfNeeded(element, container) {
  if (element.offsetTop < container.scrollTop) {
    container.scrollTop = element.offsetTop;
  } else {
    const offsetBottom = element.offsetTop + element.offsetHeight;
    const scrollBottom = container.scrollTop + container.offsetHeight;
    if (offsetBottom > scrollBottom) {
      container.scrollTop = offsetBottom - container.offsetHeight;
    }
  }
}

document.getElementById('btn').addEventListener('click', ev => {
  ev.preventDefault();
  scrollIfNeeded(document.getElementById('goose'), document.getElementById('container'));
});
.scrollContainer {
  overflow-y: auto;
  max-height: 100px;
  position: relative;
  border: 1px solid red;
  width: 120px;
}

body {
  padding: 10px;
}

.box {
  margin: 5px;
  background-color: yellow;
  height: 25px;
  display: flex;
  align-items: center;
  justify-content: center;
}

#goose {
  background-color: lime;
}
<div id="container" class="scrollContainer">
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div id="goose" class="box">goose</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
</div>

<button id="btn">scroll to goose</button>


1
Bu gerçekten yardımcı oldu. Biraz mücadele ettim çünkü pozisyonu kaçırmıştım: konteynere göre. Bu çok önemliydi!
brohr

11

Kod şöyle olmalıdır:

var divElem = document.getElementById('scrolling_div');
var chElem = document.getElementById('element_within_div');
var topPos = divElem.offsetTop;
divElem.scrollTop = topPos - chElem.offsetTop;

Alt üst konum ve div üst konumu arasındaki farkı kaydırmak istiyorsunuz.

Aşağıdakileri kullanarak alt öğelere erişin:

var divElem = document.getElementById('scrolling_div'); 
var numChildren = divElem.childNodes.length;

ve bunun gibi....


1
2. satır gerçekten okunmamalı var chElem = document.getElementById('element_within_div');ve 3. satır okunmamalı var topPos = divElem.offsetTop;mı?
jayp

7

JQuery kullanıyorsanız, aşağıdakileri kullanarak bir animasyonla kaydırma yapabilirsiniz:

$(MyContainerDiv).animate({scrollTop: $(MyContainerDiv).scrollTop() + ($('element_within_div').offset().top - $(MyContainerDiv).offset().top)});

Animasyon isteğe bağlıdır: ayrıca yukarıda hesaplanan scrollTop değerini alıp doğrudan kabın scrollTop özelliğine koyabilirsiniz .


5

Yerel JS, Çapraz Tarayıcı, Düzgün Kaydırma (Güncelleme 2020)

Ayar ScrollTopistenen sonucu verir, ancak kaydırma çok ani olur. Kullanılması jquerypürüzsüz kaydırma olması bir seçenek değildi. İşte tüm büyük tarayıcıları destekleyen işi yapmanın yerel bir yolu. Referans - caniuse

// get the "Div" inside which you wish to scroll (i.e. the container element)
const El = document.getElementById('xyz');

// Lets say you wish to scroll by 100px, 
El.scrollTo({top: 100, behavior: 'smooth'});

// If you wish to scroll until the end of the container
El.scrollTo({top: El.scrollHeight, behavior: 'smooth'});

Bu kadar!


Ve işte şüpheli için çalışan bir pasaj -

document.getElementById('btn').addEventListener('click', e => {
  e.preventDefault();
  // smooth scroll
  document.getElementById('container').scrollTo({top: 175, behavior: 'smooth'});
});
/* just some styling for you to ignore */
.scrollContainer {
  overflow-y: auto;
  max-height: 100px;
  position: relative;
  border: 1px solid red;
  width: 120px;
}

body {
  padding: 10px;
}

.box {
  margin: 5px;
  background-color: yellow;
  height: 25px;
  display: flex;
  align-items: center;
  justify-content: center;
}

#goose {
  background-color: lime;
}
<!-- Dummy html to be ignored -->
<div id="container" class="scrollContainer">
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div id="goose" class="box">goose</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
  <div class="box">duck</div>
</div>

<button id="btn">goose</button>

Güncelleme: Yorumlarda algılayabileceğiniz gibi, Element.scrollTo()IE11'de desteklenmiyor gibi görünüyor . Yani IE11 ile ilgilenmiyorsanız (gerçekten yapmamalısınız), bunu tüm projelerinizde kullanmaktan çekinmeyin. Edge için destek olduğunu unutmayın! Yani Edge / Windows kullanıcılarınızı gerçekten geride bırakmıyorsunuz;)

Referans


1
scrollTo()Windownesneler için tüm büyük tarayıcılarda desteklenebilir, ancak öğeler için IE veya Edge'de desteklenmez.
Tim Down

Caniuse'a göre IE11 ve Edge'de destekleniyor. Bu tarayıcılarda şahsen test etmedim, ancak desteklendiği görülüyor.
Niket Pathak

1
Bu window.scrollTodeğil Element.scrollTo. Örneğin Edge'de bunu deneyin ve konsolu kontrol edin: codepen.io/timdown/pen/abzVEMB
Tim Down

Haklısın. IE11 desteklenmez. Ancak Edge v76 (ref) ve üstü destekleniyor gibi görünüyor
Niket Pathak

2

İki gerçek var:

1) scrollIntoView bileşeni safari tarafından desteklenmiyor.

2) JS framework jQuery bu işi yapabilir:

parent = 'some parent div has css position==="fixed"' || 'html, body';

$(parent).animate({scrollTop: $(child).offset().top}, duration)

1

Hedef sayı (değeri scrollTop), hedef DOM öğesi veya bazı özel Dize örnekleri için çalışan basit bir saf JavaScript çözümü :

/**
 * target - target to scroll to (DOM element, scrollTop Number, 'top', or 'bottom'
 * containerEl - DOM element for the container with scrollbars
 */
var scrollToTarget = function(target, containerEl) {
    // Moved up here for readability:
    var isElement = target && target.nodeType === 1,
        isNumber = Object.prototype.toString.call(target) === '[object Number]';

    if (isElement) {
        containerEl.scrollTop = target.offsetTop;
    } else if (isNumber) {
        containerEl.scrollTop = target;
    } else if (target === 'bottom') {
        containerEl.scrollTop = containerEl.scrollHeight - containerEl.offsetHeight;
    } else if (target === 'top') {
        containerEl.scrollTop = 0;
    }
};

İşte bazı kullanım örnekleri:

// Scroll to the top
var scrollableDiv = document.getElementById('scrollable_div');
scrollToTarget('top', scrollableDiv);

veya

// Scroll to 200px from the top
var scrollableDiv = document.getElementById('scrollable_div');
scrollToTarget(200, scrollableDiv);

veya

// Scroll to targetElement
var scrollableDiv = document.getElementById('scrollable_div');
var targetElement= document.getElementById('target_element');
scrollToTarget(targetElement, scrollableDiv);

1

JQuery ve animate kullanımına başka bir örnek.

var container = $('#container');
var element = $('#element');

container.animate({
    scrollTop: container.scrollTop = container.scrollTop() + element.offset().top - container.offset().top
}, {
    duration: 1000,
    specialEasing: {
        width: 'linear',
        height: 'easeOutBounce'
    },
    complete: function (e) {
        console.log("animation completed");
    }
});

0

Kullanıcı Animasyonlu Kaydırma

JQuery olmadan<div> yatay olarak programlı olarak nasıl kaydırılacağına dair bir örnek . Dikey kaydırmak için, JavaScript'in yazma yerini alacak olan yerine,. scrollLeftscrollTop

JSFiddle

https://jsfiddle.net/fNPvf/38536/

HTML

<!-- Left Button. -->
<div style="float:left;">
    <!-- (1) Whilst it's pressed, increment the scroll. When we release, clear the timer to stop recursive scroll calls. -->
    <input type="button" value="«" style="height: 100px;" onmousedown="scroll('scroller',3, 10);" onmouseup="clearTimeout(TIMER_SCROLL);"/>
</div>
<!-- Contents to scroll. -->
<div id="scroller" style="float: left; width: 100px; height: 100px; overflow: hidden;">
    <!-- <3 -->
    <img src="https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.png?v=9c558ec15d8a" alt="image large" style="height: 100px" />
</div>
<!-- Right Button. -->
<div style="float:left;">
    <!-- As (1). (Use a negative value of 'd' to decrease the scroll.) -->
    <input type="button" value="»" style="height: 100px;" onmousedown="scroll('scroller',-3, 10);" onmouseup="clearTimeout(TIMER_SCROLL);"/>
</div>

JavaScript

// Declare the Shared Timer.
var TIMER_SCROLL;
/** 
Scroll function. 
@param id  Unique id of element to scroll.
@param d   Amount of pixels to scroll per sleep.
@param del Size of the sleep (ms).*/
function scroll(id, d, del){
    // Scroll the element.
    document.getElementById(id).scrollLeft += d;
    // Perform a delay before recursing this function again.
    TIMER_SCROLL = setTimeout("scroll('"+id+"',"+d+", "+del+");", del);
 }

Dux'a kredi .


Otomatik Hareketli Kaydırma

Ayrıca, burada <div>tamamen sola ve sağa kaydırma işlevleri bulunmaktadır . Burada değiştirdiğimiz tek şey, tekrar kaydırmak için özyinelemeli bir çağrı yapmadan önce kaydırmanın tam uzantısının kullanılıp kullanılmadığını kontrol etmemizdir.

JSFiddle

https://jsfiddle.net/0nLc2fhh/1/

HTML

<!-- Left Button. -->
<div style="float:left;">
    <!-- (1) Whilst it's pressed, increment the scroll. When we release, clear the timer to stop recursive scroll calls. -->
    <input type="button" value="«" style="height: 100px;" onclick="scrollFullyLeft('scroller',3, 10);"/>
</div>
<!-- Contents to scroll. -->
<div id="scroller" style="float: left; width: 100px; height: 100px; overflow: hidden;">
  <!-- <3 -->
  <img src="https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.png?v=9c558ec15d8a" alt="image large" style="height: 100px" />
</div>
<!-- Right Button. -->
<div style="float:left;">
    <!-- As (1). (Use a negative value of 'd' to decrease the scroll.) -->
    <input type="button" value="»" style="height: 100px;" onclick="scrollFullyRight('scroller',3, 10);"/>
</div>

JavaScript

// Declare the Shared Timer.
var TIMER_SCROLL;
/** 
Scroll fully left function; completely scrolls  a <div> to the left, as far as it will go.
@param id  Unique id of element to scroll.
@param d   Amount of pixels to scroll per sleep.
@param del Size of the sleep (ms).*/
function scrollFullyLeft(id, d, del){
    // Fetch the element.
    var el = document.getElementById(id);
    // Scroll the element.
    el.scrollLeft += d;
    // Have we not finished scrolling yet?
    if(el.scrollLeft < (el.scrollWidth - el.clientWidth)) {
        TIMER_SCROLL = setTimeout("scrollFullyLeft('"+id+"',"+d+", "+del+");", del);
    }
}

/** 
Scroll fully right function; completely scrolls  a <div> to the right, as far as it will go.
@param id  Unique id of element to scroll.
@param d   Amount of pixels to scroll per sleep.
@param del Size of the sleep (ms).*/
function scrollFullyRight(id, d, del){
    // Fetch the element.
    var el = document.getElementById(id);
    // Scroll the element.
    el.scrollLeft -= d;
    // Have we not finished scrolling yet?
    if(el.scrollLeft > 0) {
        TIMER_SCROLL = setTimeout("scrollFullyRight('"+id+"',"+d+", "+del+");", del);
    }
}

0

Sonunda bana hizmet eden bu oldu

/** Set parent scroll to show element
 * @param element {object} The HTML object to show
 * @param parent {object} The HTML object where the element is shown  */
var scrollToView = function(element, parent) {
    //Algorithm: Accumulate the height of the previous elements and add half the height of the parent
    var offsetAccumulator = 0;
    parent = $(parent);
    parent.children().each(function() {
        if(this == element) {
            return false; //brake each loop
        }
        offsetAccumulator += $(this).innerHeight();
    });
    parent.scrollTop(offsetAccumulator - parent.innerHeight()/2);
}

0

tarayıcı odaklanılan bir öğeye otomatik olarak kaydırır, böylece kaydırılması gereken öğeyi sarmak için ne yapabilirsiniz <a>...</a>ve daha sonra kaydırma gerektiğinde odak noktasını ayarlayına


0

Elemanı seçtikten sonra scrollIntoViewaşağıdaki seçenekle fonksiyonu kullanın:

const option = {
  top: 0, // number,
  left: 0, // number,
  behavior: 'auto', // auto or smooth 
    // - auto for one jump motion and smooth for animated motion -
};

Yani bu yazının cevabı:

const el = document.getElementById('id-name');
el.scrollIntoView({
  top: 0,
  left: 0,
  behavior: 'auto',
});

0

içeri kaydırmanız gereken bir div öğeniz varsa, bu kod parçasını deneyin

document.querySelector('div').scroll(x,y)

bu bir kaydırma ile bir div içinde benimle çalışır, bu öğenin üzerine fare işaret ve sonra aşağı veya yukarı kaydırmak için bu sizinle çalışmalıdır. Manuel olarak çalışıyorsa, aynı zamanda çalışmalıdır

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.