scrollIntoView Scrolls มากเกินไป


114

ฉันมีหน้าที่แถบเลื่อนที่มีแถวของตารางที่มี div อยู่ในนั้นถูกสร้างขึ้นแบบไดนามิกจากฐานข้อมูล แต่ละแถวของตารางจะทำหน้าที่เหมือนลิงก์ตามที่คุณเห็นในเพลย์ลิสต์ YouTube ถัดจากโปรแกรมเล่นวิดีโอ

เมื่อผู้ใช้เข้าชมเพจตัวเลือกที่เปิดอยู่ควรจะไปที่ด้านบนสุดของ div แบบเลื่อน ฟังก์ชันนี้ใช้งานได้ ปัญหาคือมันไปไกลเกินไป เช่นเดียวกับตัวเลือกที่เปิดอยู่สูงเกินไปประมาณ 10px ดังนั้นเมื่อมีการเยี่ยมชมหน้าเว็บ URL จะใช้เพื่อระบุว่าตัวเลือกใดถูกเลือกจากนั้นเลื่อนตัวเลือกนั้นไปที่ด้านบนสุดของ Div หมายเหตุ: นี่ไม่ใช่แถบเลื่อนสำหรับหน้าต่าง แต่เป็น div ที่มีแถบเลื่อน

ฉันใช้รหัสนี้เพื่อย้ายตัวเลือกที่เลือกไปที่ด้านบนสุดของ div:

var pathArray = window.location.pathname.split( '/' );

var el = document.getElementById(pathArray[5]);

el.scrollIntoView(true);

มันจะย้ายไปที่ด้านบนสุดของ div แต่ไกลเกินไปประมาณ 10 พิกเซล ใครทราบวิธีแก้ไข


49
การขาดการกำหนดค่าชดเชยscrollIntoViewเป็นเรื่องที่น่าหนักใจ
mystrdat

คำตอบ:


59

หากมีขนาดประมาณ 10px ฉันเดาว่าคุณสามารถปรับdivค่าออฟเซ็ตการเลื่อนที่มีด้วยตนเองได้ดังนี้

el.scrollIntoView(true);
document.getElementById("containingDiv").scrollTop -= 10;

2
สิ่งนี้จะมีเอฟเฟกต์เคลื่อนไหวเช่นเดียวกับscrollIntoViewหรือไม่
1252748

1
@thomas AFAIK scrollIntoViewฟังก์ชันDOM ธรรมดาไม่ทำให้เกิดภาพเคลื่อนไหว คุณกำลังพูดถึงปลั๊กอิน scrollIntoView jQuery หรือไม่?
Lucas Trzesniewski

1
คนทำงานคนนั้นยกเว้นว่ามันเป็นทิศทางที่ผิดดังนั้นสิ่งที่ฉันต้องทำก็คือเปลี่ยนจาก + = 10 เป็น - = 10 และตอนนี้มันกำลังโหลดถูกต้องขอบคุณมากสำหรับความช่วยเหลือ !!!!
Matthew Wilson

18
el.scrollIntoView({ behavior: 'smooth' });มันสามารถเคลื่อนไหวเพียงเพิ่ม การสนับสนุนไม่ดีนัก!
daveaspinall

1
@kernowcode ฉันคิดว่าคุณหมายถึงblock:'center'
Sanyam Jain

127

เลื่อนไปยังตำแหน่งที่เหมาะสมอย่างราบรื่น

รับพิกัดและการใช้งานที่ถูกต้อง ywindow.scrollTo({top: y, behavior: 'smooth'})

const id = 'profilePhoto';
const yOffset = -10; 
const element = document.getElementById(id);
const y = element.getBoundingClientRect().top + window.pageYOffset + yOffset;

window.scrollTo({top: y, behavior: 'smooth'});

2
นี่เป็นคำตอบที่ถูกต้องที่สุด - เราสามารถหาตำแหน่งของการเลื่อนได้อย่างง่ายดายด้วยjQuery('#el').offset().topแล้วจึงจะใช้ได้window.scrollTo
Alexander Goncharov

1
+1 สำหรับโซลูชันนี้ ช่วยให้ฉันเลื่อนไปยังองค์ประกอบได้อย่างถูกต้องเมื่อฉันวางคอนเทนเนอร์ที่สัมพันธ์กับออฟเซ็ตด้านบน
ลีกา

ใครก็ตามที่มาที่นี่โดยใช้ HashLink กับ React Router นี่คือสิ่งที่ได้ผลสำหรับฉัน ในเสาเลื่อนบน HashLink ของคุณ scroll={el => { const yCoordinate = el.getBoundingClientRect().top + window.pageYOffset; const yOffset = -80; window.scrollTo({ top: yCoordinate + yOffset, behavior: 'smooth' }); }}- โดยที่ออฟเซ็ตมีขนาดมากกว่าขนาดของส่วนหัว 10-15 พิกเซลเพียงเพื่อระยะห่างที่ดีขึ้น
Rob B

87

คุณสามารถทำได้ในสองขั้นตอน:

el.scrollIntoView(true);
window.scrollBy(0, -10); // Adjust scrolling with a negative value here

24
หากscrollIntoView()ยังไม่เสร็จสิ้นการเลื่อนก่อนที่จะscrollBy()รันการเลื่อนหลังจะยกเลิกการเลื่อนก่อนหน้านี้ อย่างน้อยบน Chrome 71
Dave Hughes

1
ในกรณีนี้ให้ใช้ setTimeout ดังที่เห็นในคำตอบด้านล่าง: stackoverflow.com/a/51935129/1856258 .. สำหรับฉันมันใช้งานได้โดยไม่ต้องหมดเวลา ขอบคุณ!
leole

มีวิธีฉีดตัวแก้ไขพิกเซลลงใน scrollIntoView โดยตรงเพื่อให้แอปพลิเคชันย้ายไปยังตำแหน่งที่เกี่ยวข้องโดยตรงหรือไม่ เช่นเดียวกับscrollIntoView({adjustment:y})ที่ผมคิดว่ามันควรจะเป็นไปได้ด้วยรหัสที่กำหนดเองที่ปลาย
Webwoman

83

จุดยึดตำแหน่งโดยวิธีสัมบูรณ์

อีกวิธีหนึ่งในการทำเช่นนี้คือการจัดตำแหน่งจุดยึดให้ตรงกับที่ที่คุณต้องการบนหน้าเว็บแทนที่จะอาศัยการเลื่อนด้วยการชดเชย ฉันพบว่ามันช่วยให้สามารถควบคุมแต่ละองค์ประกอบได้ดีขึ้น (เช่นหากคุณต้องการออฟเซ็ตที่แตกต่างกันสำหรับองค์ประกอบบางอย่าง) และยังอาจทนทานต่อการเปลี่ยนแปลง / ความแตกต่างของ API ของเบราว์เซอร์

<div id="title-element" style="position: relative;">
  <div id="anchor-name" style="position: absolute; top: -100px; left: 0"></div>
</div>

ตอนนี้ออฟเซ็ตถูกระบุเป็น -100px สัมพันธ์กับองค์ประกอบ สร้างฟังก์ชันเพื่อสร้างจุดยึดนี้สำหรับการใช้โค้ดซ้ำหรือถ้าคุณกำลังใช้เฟรมเวิร์ก JS ที่ทันสมัยเช่น React ให้ทำโดยการสร้างส่วนประกอบที่แสดงจุดยึดของคุณและส่งผ่านชื่อจุดยึดและการจัดแนวสำหรับแต่ละองค์ประกอบซึ่งอาจจะหรือ ไม่เหมือนกัน.

จากนั้นใช้:

const element = document.getElementById('anchor-name')
element.scrollIntoView({ behavior: 'smooth', block: 'start' });

สำหรับการเลื่อนที่ราบรื่นด้วยออฟเซ็ต 100px


12
นี่เป็นวิธีที่ดีที่สุดในการนำไปใช้อย่างราบรื่นและเรียบง่าย
จับ 22

2
วิธีที่ดีที่สุดและเป็นธรรมชาติที่สุดที่ฉันคิด
ДаниилПронин

1
มันง่ายและเนียนมาก คนอื่น ๆ หลายคนเพิ่ม JS ที่ไม่จำเป็น
RedSands

2
สิ่งนี้มีประโยชน์อย่างยิ่งเมื่อลิงก์ประเภท "หน้าบนสุด" อยู่ใต้แถบนำทางและคุณต้องการแสดงการนำทาง แต่ไม่ต้องการให้ลิงก์อื่นหักล้าง
โจมูน

คุณสามารถบรรลุสิ่งเดียวกันได้โดยใช้ระยะขอบด้านบนที่เป็นลบคุณหลีกเลี่ยงการตัดองค์ประกอบร่วมกับองค์ประกอบอื่นด้วยตำแหน่งที่สัมพันธ์กัน
Sergi

22

ฉันแก้ไขปัญหานี้โดยใช้

element.scrollIntoView({ behavior: 'smooth', block: 'center' });

สิ่งนี้ทำให้องค์ประกอบปรากฏในการcenterเลื่อนหลังดังนั้นฉันจึงไม่ต้องคำนวณyOffsetหลังจากเลื่อนดังนั้นผมจึงไม่ได้มีการคำนวณ

หวังว่ามันจะช่วย ...


1
คุณควรใช้scrollToไม่ได้อยู่elementแต่ในwindow
Arseniy-II

@ Arseniy-II ขอบคุณที่ชี้ให้เห็น !!. ฉันพลาดส่วนนั้น!
Imtiaz Shakil Siddique

บล็อกช่วยด้านบนหรือไม่?
Ashok kumar Ganesan

16

สิ่งนี้ใช้ได้กับฉันใน Chrome (ด้วยการเลื่อนที่ราบรื่นและไม่มีการแฮ็กเวลา)

เพียงแค่ย้ายองค์ประกอบเริ่มต้นการเลื่อนจากนั้นย้ายกลับ

จะไม่มี "popping" ที่มองเห็นได้หากองค์ประกอบอยู่บนหน้าจอแล้ว

pos = targetEle.style.position;
top = targetEle.style.top;
targetEle.style.position = 'relative';
targetEle.style.top = '-20px';
targetEle.scrollIntoView({behavior: 'smooth', block: 'start'});
targetEle.style.top = top;
targetEle.style.position = pos;

นี่คือทางออกที่ดีที่สุด ... ขอให้ทำเครื่องหมายว่าเป็นคำตอบ จะช่วยประหยัดเวลาได้สองสามชั่วโมง
Shivam

ทดสอบแล้วและใช้งานได้นอกกรอบ ไม่ใช่แฮ็คและใช้งานได้ดี! โหวตอันนี้!
Jens Törnell

7

จากคำตอบก่อนหน้านี้ฉันกำลังทำสิ่งนี้ในโครงการ Angular5

เริ่มต้นด้วย:

// el.scrollIntoView(true);
el.scrollIntoView({
   behavior: 'smooth',
   block: 'start'
});
window.scrollBy(0, -10); 

แต่สิ่งนี้ทำให้เกิดปัญหาบางอย่างและจำเป็นต้อง setTimeout สำหรับ scrollBy () ดังนี้:

//window.scrollBy(0,-10);
setTimeout(() => {
  window.scrollBy(0,-10)
  }, 500);

และทำงานได้อย่างสมบูรณ์แบบใน MSIE11 และ Chrome 68+ ฉันไม่ได้ทดสอบใน FF 500ms เป็นความล่าช้าที่สั้นที่สุดที่ฉันจะเสี่ยง การลดระดับลงบางครั้งล้มเหลวเนื่องจากการเลื่อนอย่างราบรื่นยังไม่เสร็จสมบูรณ์ ปรับเปลี่ยนตามความจำเป็นสำหรับโครงการของคุณเอง

+1 ถึงFred727 สำหรับโซลูชันที่เรียบง่าย แต่มีประสิทธิภาพนี้


7
สิ่งนี้ให้ความรู้สึกยุ่งยากเล็กน้อยในการเลื่อนไปที่องค์ประกอบอย่างราบรื่นจากนั้นเลื่อนขึ้นเล็กน้อยหลังจากนั้น
จับ 22

7

สมมติว่าคุณต้องการเลื่อนไปที่ div ที่อยู่ในระดับเดียวกันใน DOM และมีชื่อคลาส "scroll-with-offset" CSS นี้จะแก้ปัญหาได้:

.scroll-with-offset {    
  padding-top: 100px;
  margin-bottom: -100px;
}

ค่าชดเชยจากด้านบนของหน้าคือ 100px มันจะทำงานตามที่ตั้งใจไว้กับ block เท่านั้น: 'start':

element.scrollIntoView({ behavior: 'smooth', block: 'start' });

สิ่งที่เกิดขึ้นคือจุดสูงสุดของ div อยู่ที่ตำแหน่งปกติ แต่เนื้อหาภายในเริ่มต้น 100px ต่ำกว่าตำแหน่งปกติ นั่นคือสิ่งที่ padding-top: 100px มีไว้สำหรับ margin-bottom: -100px คือการหักล้างขอบพิเศษของ div ด้านล่าง เพื่อให้การแก้ปัญหาเสร็จสมบูรณ์ให้เพิ่ม CSS นี้เพื่อชดเชยระยะขอบ / paddings สำหรับ div ด้านบนสุดและล่างสุด:

.top-div {
  padding-top: 0;
}
.bottom-div {
  margin-bottom: 0;
}

6

โซลูชันนี้เป็นของ@ Arseniy-IIฉันเพิ่งทำให้มันง่ายขึ้นในฟังก์ชัน

function _scrollTo(selector, yOffset = 0){
  const el = document.querySelector(selector);
  const y = el.getBoundingClientRect().top + window.pageYOffset + yOffset;

  window.scrollTo({top: y, behavior: 'smooth'});
}

การใช้งาน (คุณสามารถเปิดคอนโซลได้ที่นี่ใน StackOverflow และทดสอบ):

_scrollTo('#question-header', 0);


4

ดังนั้นบางทีนี่อาจจะค่อนข้างเกะกะ แต่จนถึงตอนนี้ก็ดี ฉันทำงานในเชิงมุม 9

ไฟล์ .ts

scroll(el: HTMLElement) {
  el.scrollIntoView({ block: 'start',  behavior: 'smooth' });   
}

ไฟล์ .html

<button (click)="scroll(target)"></button>
<div  #target style="margin-top:-50px;padding-top: 50px;" ></div>

ฉันปรับชดเชยด้วยระยะขอบและช่องว่างด้านบน

Saludos!


3

ฉันมีสิ่งนี้และมันใช้งานได้ดีสำหรับฉัน:

// add a smooth scroll to element
scroll(el) {
el.scrollIntoView({
  behavior: 'smooth',
  block: 'start'});

setTimeout(() => {
window.scrollBy(0, -40);
}, 500);}

หวังว่าจะช่วยได้


3

อีกวิธีหนึ่งคือการใช้ "offsetTop" ดังนี้:

var elementPosition = document.getElementById('id').offsetTop;

window.scrollTo({
  top: elementPosition - 10, //add your necessary value
  behavior: "smooth"  //Smooth transition to roll
});

1

พบวิธีแก้ปัญหาเบื้องต้น สมมติว่าคุณต้องการเลื่อนไปที่ div ตัวอย่างเช่น Element ที่นี่และคุณต้องการเว้นระยะห่าง 20px ด้านบน ตั้งค่าการอ้างอิงเป็น div ที่สร้างไว้ด้านบน:

<div ref={yourRef} style={{position: 'relative', bottom: 20}}/> <Element />

เพื่อสร้างระยะห่างที่ต้องการ

หากคุณมีส่วนหัวให้สร้าง div ว่างไว้ด้านหลังส่วนหัวและกำหนดความสูงให้เท่ากับความสูงของส่วนหัวและอ้างอิง


0

แนวคิดหลักของฉันคือการสร้างtempDivเหนือมุมมองที่เราต้องการเลื่อนไป ทำงานได้ดีโดยไม่ล้าหลังในโครงการของฉัน

scrollToView = (element, offset) => {
    var rect = element.getBoundingClientRect();
    var targetY = rect.y + window.scrollY - offset;

    var tempDiv;
    tempDiv = document.getElementById("tempDiv");
    if (tempDiv) {
        tempDiv.style.top = targetY + "px";
    } else {
        tempDiv = document.createElement('div');
        tempDiv.id = "tempDiv";
        tempDiv.style.background = "#F00";
        tempDiv.style.width = "10px";
        tempDiv.style.height = "10px";
        tempDiv.style.position = "absolute";
        tempDiv.style.top = targetY + "px";
        document.body.appendChild(tempDiv);
    }

    tempDiv.scrollIntoView({ behavior: 'smooth', block: 'start' });
}

ตัวอย่างโดยใช้

onContactUsClick = () => {
    this.scrollToView(document.getElementById("contact-us"), 48);
}

หวังว่าจะช่วยได้


0

จากคำตอบของ Arseniy-II: ฉันมี Use-Case ที่เอนทิตีการเลื่อนไม่ใช่หน้าต่างเอง แต่เป็นเทมเพลตภายใน (ในกรณีนี้คือ div) ในสถานการณ์นี้เราจำเป็นต้องตั้งค่า ID สำหรับคอนเทนเนอร์การเลื่อนและรับผ่านgetElementByIdเพื่อใช้ฟังก์ชันการเลื่อน:

<div class="scroll-container" id="app-content">
  ...
</div>
const yOffsetForScroll = -100
const y = document.getElementById(this.idToScroll).getBoundingClientRect().top;
const main = document.getElementById('app-content');
main.scrollTo({
    top: y + main.scrollTop + yOffsetForScroll,
    behavior: 'smooth'
  });

ทิ้งไว้ที่นี่เผื่อมีคนเจอสถานการณ์คล้ายกัน!


0

นี่คือ 2 เซ็นต์ของฉัน

ฉันยังมีปัญหาของการเลื่อน scrollIntoView เล็กน้อยผ่านองค์ประกอบดังนั้นฉันจึงสร้างสคริปต์ (จาวาสคริปต์ดั้งเดิม) ที่นำองค์ประกอบไปยังปลายทางโดยวางตำแหน่งไว้ด้านบนเล็กน้อยด้วย css และเลื่อนไปที่องค์ประกอบนั้น หลังจากเลื่อนฉันจะลบองค์ประกอบที่สร้างขึ้นอีกครั้ง

HTML:

//anchor tag that appears multiple times on the page
<a href="#" class="anchors__link js-anchor" data-target="schedule">
    <div class="anchors__text">
        Scroll to the schedule
    </div>
</a>

//The node we want to scroll to, somewhere on the page
<div id="schedule">
    //html
</div>

ไฟล์ Javascript:

(() => {
    'use strict';

    const anchors = document.querySelectorAll('.js-anchor');

    //if there are no anchors found, don't run the script
    if (!anchors || anchors.length <= 0) return;

    anchors.forEach(anchor => {
        //get the target from the data attribute
        const target = anchor.dataset.target;

        //search for the destination element to scroll to
        const destination = document.querySelector(`#${target}`);
        //if the destination element does not exist, don't run the rest of the code
        if (!destination) return;

        anchor.addEventListener('click', (e) => {
            e.preventDefault();
            //create a new element and add the `anchors__generated` class to it
            const generatedAnchor = document.createElement('div');
            generatedAnchor.classList.add('anchors__generated');

            //get the first child of the destination element, insert the generated element before it. (so the scrollIntoView function scrolls to the top of the element instead of the bottom)
            const firstChild = destination.firstChild;
            destination.insertBefore(generatedAnchor, firstChild);

            //finally fire the scrollIntoView function and make it animate "smoothly"
            generatedAnchor.scrollIntoView({
                behavior: "smooth",
                block: "start",
                inline: "start"
            });

            //remove the generated element after 1ms. We need the timeout so the scrollIntoView function has something to scroll to.
            setTimeout(() => {
                destination.removeChild(generatedAnchor);
            }, 1);
        })
    })
})();

CSS:

.anchors__generated {
    position: relative;
    top: -100px;
}

หวังว่านี่จะช่วยทุกคน!


0

ฉันเพิ่มเคล็ดลับ css นี้สำหรับผู้ที่ไม่สามารถแก้ไขปัญหานี้ด้วยวิธีแก้ไขด้านบน:

#myDiv::before {
  display: block;
  content: " ";
  margin-top: -90px; // adjust this with your header height
  height: 90px; // adjust this with your header height
  visibility: hidden;
}

0

UPD: ฉันได้สร้างแพ็คเกจ npmที่ทำงานได้ดีกว่าโซลูชันต่อไปนี้และใช้งานง่ายกว่า

ฟังก์ชัน smoothScroll ของฉัน

ฉันได้ใช้โซลูชันที่ยอดเยี่ยมของ Steve Banton และเขียนฟังก์ชันที่ทำให้ใช้งานได้สะดวกยิ่งขึ้น มันจะง่ายกว่าที่จะใช้window.scroll()หรือแม้กระทั่งwindow.scrollBy()อย่างที่ฉันเคยลองมาก่อน แต่ทั้งสองมีปัญหา:

  • ทุกอย่างกลายเป็นขยะหลังจากใช้งานด้วยพฤติกรรมที่ราบรื่น
  • คุณไม่สามารถป้องกันได้ แต่อย่างใดและต้องรอจนกว่าจะถึงและเลื่อน ดังนั้นฉันหวังว่าฟังก์ชันของฉันจะเป็นประโยชน์สำหรับคุณ นอกจากนี้ยังมีโพลีฟิลน้ำหนักเบาที่ทำให้ใช้งานได้ใน Safari และแม้แต่ IE

นี่คือรหัส

เพียงแค่คัดลอกและทำให้ยุ่งเหยิงตามที่คุณต้องการ

import smoothscroll from 'smoothscroll-polyfill';

smoothscroll.polyfill();

const prepareSmoothScroll = linkEl => {
  const EXTRA_OFFSET = 0;

  const destinationEl = document.getElementById(linkEl.dataset.smoothScrollTo);
  const blockOption = linkEl.dataset.smoothScrollBlock || 'start';

  if ((blockOption === 'start' || blockOption === 'end') && EXTRA_OFFSET) {
    const anchorEl = document.createElement('div');

    destinationEl.setAttribute('style', 'position: relative;');
    anchorEl.setAttribute('style', `position: absolute; top: -${EXTRA_OFFSET}px; left: 0;`);

    destinationEl.appendChild(anchorEl);

    linkEl.addEventListener('click', () => {
      anchorEl.scrollIntoView({
        block: blockOption,
        behavior: 'smooth',
      });
    });
  }

  if (blockOption === 'center' || !EXTRA_OFFSET) {
    linkEl.addEventListener('click', () => {
      destinationEl.scrollIntoView({
        block: blockOption,
        behavior: 'smooth',
      });
    });
  }
};

export const activateSmoothScroll = () => {
  const linkEls = [...document.querySelectorAll('[data-smooth-scroll-to]')];

  linkEls.forEach(linkEl => prepareSmoothScroll(linkEl));
};

ในการสร้างองค์ประกอบลิงก์ให้เพิ่มแอตทริบิวต์ข้อมูลต่อไปนี้:

data-smooth-scroll-to="element-id"

นอกจากนี้คุณสามารถตั้งค่าแอตทริบิวต์อื่นเป็นส่วนเสริมได้

data-smooth-scroll-block="center"

แสดงถึงblockตัวเลือกของscrollIntoView()ฟังก์ชัน startโดยค่าเริ่มต้นมัน อ่านเพิ่มเติมเกี่ยวกับMDN MDN

สุดท้าย

ปรับฟังก์ชัน smoothScroll ตามความต้องการของคุณ

ตัวอย่างเช่นหากคุณมีส่วนหัวคงที่ (หรือฉันเรียกด้วยคำว่าmasthead) คุณสามารถทำสิ่งนี้ได้:

const mastheadEl = document.querySelector(someMastheadSelector);

// and add it's height to the EXTRA_OFFSET variable

const EXTRA_OFFSET = mastheadEl.offsetHeight - 3;

หากคุณไม่มีกรณีดังกล่าวก็ลบทิ้งทำไมไม่ :-D.


-1

วิธีง่ายๆในการเลื่อนองค์ประกอบที่ต้องการลง

const element = document.getElementById("element-with-scroll");
element.scrollTop = element.scrollHeight - 10;

-1

สำหรับองค์ประกอบในแถวตารางให้ใช้ JQuery เพื่อรับแถวเหนือรายการที่คุณต้องการแล้วเลื่อนไปที่แถวนั้นแทน

สมมติว่าฉันมีหลายแถวในตารางซึ่งบางส่วนควรได้รับการตรวจสอบโดยผู้ดูแลระบบ แต่ละแถวที่ต้องตรวจสอบมีทั้งลูกศรขึ้นและลงเพื่อนำคุณไปยังรายการก่อนหน้าหรือถัดไปเพื่อตรวจสอบ

นี่คือตัวอย่างที่สมบูรณ์ที่ควรเรียกใช้หากคุณสร้างเอกสาร HTML ใหม่ใน notepad และบันทึกไว้ มีรหัสพิเศษสำหรับตรวจสอบด้านบนและด้านล่างของรายการเพื่อตรวจสอบดังนั้นเราจึงไม่เกิดข้อผิดพลาดใด ๆ

<html>
<head>
    <title>Scrolling Into View</title>
    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script>
    <style>
        div.scroll { height: 6em; width: 20em; overflow: auto; }
        thead th   { position: sticky; top: -1px; background: #fff; }
        .up, .down { cursor: pointer; }
        .up:hover, .down:hover { color: blue; text-decoration:underline; }
    </style>
</head>
<body>
<div class='scroll'>
<table border='1'>
    <thead>
        <tr>
            <th>Review</th>
            <th>Data</th>
        </tr>
    </thead>
    <tbody>
        <tr id='row_1'>
            <th></th>
            <td>Row 1 (OK)</td>
        </tr>
        <tr id='row_2'>
            <th></th>
            <td>Row 2 (OK)</td>
        </tr>
        <tr id='row_3'>
            <th id='jump_1'><span class='up'>UP</span> <span class='down'>DN</span></th>
            <td>Row 3 (REVIEW)</td>
        </tr>
        <tr id='row_4'>
            <th></th>
            <td>Row 4 (OK)</td>
        </tr>
        <tr id='row_5'>
            <th id='jump_2'><span class='up'>UP</span> <span class='down'>DN</span></th>
            <td>Row 5 (REVIEW)</td>
        </tr>
        <tr id='row_6'>
            <th></th>
            <td>Row 6 (OK)</td>
        </tr>
        <tr id='row_7'>
            <th></th>
            <td>Row 7 (OK)</td>
        </tr>
        <tr id='row_8'>
            <th id='jump_3'><span class='up'>UP</span> <span class='down'>DN</span></th>
            <td>Row 8 (REVIEW)</td>
        </tr>
        <tr id='row_9'>
            <th></th>
            <td>Row 9 (OK)</td>
        </tr>
        <tr id='row_10'>
            <th></th>
            <td>Row 10 (OK)</td>
        </tr>
    </tbody>
</table>
</div>
<script>
$(document).ready( function() {
    $('.up').on('click', function() {
        var id = parseInt($(this).parent().attr('id').split('_')[1]);
        if (id>1) {
            var row_id = $('#jump_' + (id - 1)).parent().attr('id').split('_')[1];
            document.getElementById('row_' + (row_id-1)).scrollIntoView({behavior: 'smooth', block: 'start'});
        } else {
            alert('At first');
        }
    });

    $('.down').on('click', function() {
        var id = parseInt($(this).parent().attr('id').split('_')[1]);
        if ($('#jump_' + (id + 1)).length) {
            var row_id = $('#jump_' + (id + 1)).parent().attr('id').split('_')[1];
            document.getElementById('row_' + (row_id-1)).scrollIntoView({behavior: 'smooth', block: 'start'});
        } else {
            alert('At last');
        }
    });
});
</script>
</body>
</html>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.