113

Tôi có một cuộn divvà tôi muốn có một liên kết khi tôi nhấp vào nó, nó sẽ buộc nó divphải cuộn để xem một phần tử bên trong. Tôi đã viết JavasSript của nó như thế này:

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

nhưng điều này cuộn tất cả các trang trong khi cuộn divchính nó. Làm thế nào để khắc phục điều đó?

Tôi muốn nói như thế

MyContainerDiv.getElementById(chr).scrollIntoView(true);
|
  • Scrolltop không luôn luôn trả về một giá trị có thể sử dụng. Tôi có xu hướng sử dụng một SetTimeouttrong $(document).ready({})hàm và đặt thành focus()phần tử bạn muốn cuộn. Làm việc cho tôi

    – Ngô Tường An 06:44:02 30/08/2016
280

Bạn cần lấy phần bù trên cùng của phần tử bạn muốn cuộn vào dạng xem, liên quan đến phần tử mẹ của nó (thùng chứa div cuộn):

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

Biến topPos hiện được đặt thành khoảng cách giữa đỉnh div cuộn và phần tử bạn muốn hiển thị (tính bằng pixel).

Bây giờ chúng tôi bảo div di chuyển đến vị trí đó bằng cách sử dụng scrollTop:

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

Nếu bạn đang sử dụng khung công tác nguyên mẫu, bạn sẽ làm điều tương tự như sau:

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

Một lần nữa, điều này sẽ cuộn div để phần tử bạn muốn thấy chính xác ở trên cùng (hoặc nếu không thể, hãy cuộn xuống càng xa càng tốt để nó hiển thị).

|
  • 1

    Điều này thực sự hữu ích! Nếu bạn muốn đặt cuộn nhiều lần, bạn cần phải bù theo vị trí cuộn hiện tại của mình. Đây là cách tôi đã làm trong jQuery: $ ('# scrolling_div'). ScrollTop ($ ('# scrolling_div'). ScrollTop () + $ ('# Element_within_div'). Position (). Top);

    – Hồ Thụy Vân 17:43:10 14/08/2014
  • 1

    không hoạt động nữa, offsetTop luôn bằng 0

    – Ngô Quang Bảo 15:14:17 03/04/2015
  • 1

    Coi chừng việc yêu cầu myElement.offsetTopsẽ kích hoạt chỉnh lại dòng (đập bố cục) có thể là nút cổ chai hiệu năng

    – Ngô Thu Thuận 19:34:32 09/08/2016
  • 1

    Hãy nhớ đặt cha mẹ cuộn với css: position: relativenếu không bạn sẽ mất rất nhiều thời gian để gỡ lỗi như tôi vừa làm.

    – Lý Hải Sơn 20:39:03 04/02/2017
  • 1

    Vẫn hoạt động vào năm 2017. Thông tin bổ sung: .offsetTop có thể trả về 0. Sau đó, bạn nên tham khảo phần tử cha và thử lại. Tôi đã làm điều đó cho các thẻ h4sau divđó articlegắn thẻ và chỉ articlelàm việc cho tôi.

    – Đỗ Như Hảo 11:28:20 07/11/2017
62

Bạn sẽ phải tìm vị trí của phần tử trong DIV mà bạn muốn cuộn và đặt thuộc tính scrollTop.

divElem.scrollTop = 0;

Cập nhật :

Mã mẫu để di chuyển lên hoặc xuống

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

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

Phương pháp 1 - Di chuyển mượt mà đến một phần tử bên trong một phần tử

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>

Phương pháp 2 - Sử dụng Element.scrollIntoView :

Lưu ý rằng hỗ trợ trình duyệt không tốt cho cái này

var box = document.querySelector('.box'),
    targetElm = document.querySelector('.boxChild');

document.querySelector('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>

Phương pháp 3 - Sử dụng hành vi cuộn CSS :

.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

    Lưu ý rằng cuộn hành vi không được hỗ trợ trong IE / Edge / Safari

    – Nguyễn Ngọc Yên 21:34:25 23/02/2019
  • 1

    @sheats - Nó nói chính xác rằng trong liên kết tài liệu MDN mà tôi đã đặt ở cỡ chữ lớn. Ngay cả khi nó không hoạt động cho các trình duyệt đó, điều đó không có nghĩa là bạn không nên sử dụng nó. Không có "quy tắc" nào, mọi thứ phải hoạt động giống nhau trên tất cả các trình duyệt. Nếu các trình duyệt hiện đại có thể làm phép thuật, hãy để chúng làm phép thuật.

    – Ngô Phương Tâm 21:36:28 23/02/2019
9

Mã phải là:

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

Bạn muốn cuộn sự khác biệt giữa vị trí trên cùng của con và vị trí trên cùng của div.

Truy cập vào các phần tử con bằng cách sử dụng:

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

vân vân và vân vân ....

|
  • 1

    Không nên đọc dòng thứ 2 var chElem = document.getElementById('element_within_div');và dòng thứ 3 có nên đọc var topPos = divElem.offsetTop;không?

    – Hoàng Ái Nhi 18:06:56 26/03/2016
7

Để cuộn một phần tử vào chế độ xem của div, chỉ khi cần, bạn có thể sử dụng scrollIfNeededchức năng này :

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

    Điều này thực sự hữu ích. Tôi vật lộn một chút vì tôi đã bỏ lỡ vị trí: tương đối trên container. Đó là rất quan trọng!

    – Hoàng Tú Uyên 13:59:18 18/05/2018
4

Nếu bạn đang sử dụng jQuery, bạn có thể cuộn với một hình ảnh động bằng cách sử dụng như sau:

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

Hoạt hình là tùy chọn: bạn cũng có thể lấy giá trị scrollTop được tính ở trên và đặt trực tiếp vào thuộc tính scrollTop của bộ chứa .

|
1

Có hai sự thật:

1) Thành phần scrollIntoView không được safari hỗ trợ.

2) jQuery framework jQuery có thể thực hiện công việc như thế này:

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

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

Đây là một giải pháp JavaScript thuần túy đơn giản hoạt động cho Số mục tiêu (giá trị scrollTop), phần tử DOM đích hoặc một số trường hợp Chuỗi đặc biệt:

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

Và đây là một số ví dụ về cách sử dụng:

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

hoặc là

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

hoặc là

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

trình duyệt sẽ tự động cuộn đến một phần tử được lấy nét, do đó, bạn cũng có thể làm điều đó để bọc phần tử mà bạn cần cuộn vào <a>...</a>và sau đó khi bạn cần cuộn, hãy đặt tiêu điểm vào đóa

|
0

Một ví dụ khác về việc sử dụng jQuery và hoạt hình.

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

Đây là những gì cuối cùng đã phục vụ tôi

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

Cuộn hoạt hình người dùng

Đây là một ví dụ về cách cuộn chương trình <div>theo chiều ngang mà không cần JQuery . Để cuộn theo chiều dọc, bạn sẽ thay thế ghi của JavaScript scrollLeftbằngscrollTop , để thay thế.

Câu đố

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

Tín dụng cho Dux .


Tự động cuộn

Ngoài ra, đây là các chức năng để cuộn <div>hoàn toàn sang trái và phải. Điều duy nhất chúng tôi thay đổi ở đây là chúng tôi kiểm tra xem liệu phần mở rộng đầy đủ của cuộn đã được sử dụng trước khi thực hiện cuộc gọi đệ quy để cuộn lại.

Câu đố

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

Câu trả lời của bạn (> 20 ký tự)

Bằng cách click "Đăng trả lời", bạn đồng ý với Điều khoản dịch vụ, Chính sách bảo mật and Chính sách cookie của chúng tôi.

Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ hoặc hỏi câu hỏi của bạn.