จะเลื่อนไปที่ด้านบนของหน้าด้วย JavaScript / jQuery ได้อย่างไร?


159

มีวิธีควบคุมการเลื่อนเบราว์เซอร์ด้วย JavaScript / jQuery หรือไม่?

เมื่อฉันเลื่อนหน้าเว็บลงครึ่งหนึ่งจากนั้นให้เรียกโหลดอีกครั้งฉันต้องการให้หน้ากระดาษไปด้านบน แต่กลับพยายามค้นหาตำแหน่งการเลื่อนครั้งสุดท้ายแทน ดังนั้นฉันจึงทำสิ่งนี้:

$('document').ready(function() {
   $(window).scrollTop(0);
});

แต่ไม่มีโชค

แก้ไข :

ดังนั้นคำตอบของคุณทั้งสองทำงานเมื่อฉันเรียกพวกเขาหลังจากหน้าโหลด - ขอบคุณ อย่างไรก็ตามหากฉันเพิ่งรีเฟรชหน้าเว็บดูเหมือนว่าเบราว์เซอร์จะคำนวณและเลื่อนไปยังตำแหน่งเลื่อนเก่าหลังจาก.readyเหตุการณ์ (ฉันทดสอบฟังก์ชั่น body onload () ด้วย)

ดังนั้นการติดตามคือมีวิธีป้องกันเบราว์เซอร์ที่เลื่อนไปยังตำแหน่งที่ผ่านมาหรือเลื่อนอีกครั้งไปด้านบนหลังจากที่มันทำมันได้หรือไม่


1
จะเกิดอะไรขึ้นเมื่อคุณทำจาก $ (หน้าต่าง) .load ()
mpdonadio

2
@ MPD- ความคิดที่ยอดเยี่ยม! ... แต่ลองทำดูแล้วการปรับตัวของสโครลก็ยังคงเกิดขึ้น ขอบคุณสำหรับเคล็ดลับ แต่จริง ๆ แล้วมันจะช่วยให้มีคำถามอื่น ๆ ของฉัน: stackoverflow.com/questions/4210829/... ถ้าคุณต้องการที่จะตอบว่าฉันจะให้คุณอัพ
Yarin

@Yarin ขออภัยคุณต้องรอ 9 ปีสำหรับสิ่งนี้ คุณต้องตั้งค่า history.scrollRestoration ก่อนที่จะพยายามเลื่อน ดูคำตอบของฉัน
RayLoveless

คำตอบ:


16

ว้าวฉันอายุ 9 ปีสำหรับคำถามนี้ ไปเลย:

เพิ่มรหัสนี้ไปยัง onload ของคุณ

// This prevents the page from scrolling down to where it was previously.
if ('scrollRestoration' in history) {
    history.scrollRestoration = 'manual';
}
// This is needed if the user scrolls down during page load and you want to make sure the page is scrolled to the top once it's fully loaded. This has Cross-browser support.
window.scrollTo(0,0);

history.scrollRestoration การสนับสนุนเบราว์เซอร์:

Chrome: รองรับ (ตั้งแต่ 46)

Firefox: รองรับ (ตั้งแต่ 46)

IE / Edge: ไม่รองรับ (ยัง .. )

Opera: รองรับ (ตั้งแต่ 33)

Safari: รองรับ

สำหรับ IE / Edge หากคุณต้องการเลื่อนอีกครั้งไปด้านบนหลังจากมันเลื่อนลงอัตโนมัติสิ่งนี้ใช้ได้สำหรับฉัน:

var isIE11 = !!window.MSInputMethodContext && !!document.documentMode;
var isEdge = /Edge/.test(navigator.userAgent);
if(isIE11 || isEdge) {
    setTimeout(function(){ window.scrollTo(0, 0); }, 300);  // adjust time according to your page. The better solution would be to possibly tie into some event and trigger once the autoscrolling goes to the top.
} 

ขอบคุณ @RayLoveless - น่าเสียดายที่เบราว์เซอร์ MS ไม่รองรับ (เพราะแน่นอน) ดูcaniuse.com/#feat=mdn-api_history_scrollrestorationและdeveloper.mozilla.org/de/docs/Web/API/…
Yarin

@Yarin จุดดี ฉันอัพเดทโพสต์แล้ว นั่นตอบคำถามของคุณหรือไม่
RayLoveless

312

Cross-browser, pure JavaScript solution:

document.body.scrollTop = document.documentElement.scrollTop = 0;

3
เนื่องจากคุณใช้ jQuery คุณสามารถลอง:$(window).one("scroll",function() { /* the code from my answer here */ });
Niet the Dark Absol

ในการทำให้การทำงานข้ามเบราว์เซอร์ IE / Chrome / FF ของฉันฉันต้องรวมคำตอบ Niet Dark Absolute และ user113716 คำตอบ (โดยใช้การหมดเวลา)
Panini Luncher

ไม่ทำงานบน CentOS 6.7 โดยใช้ FF 45.1.0 ฉันห่อมันไว้ในเอกสารพร้อมแล้วเพื่อความแน่ใจ
Brandon Elliott

เพียงแค่ต้องการชี้ให้เห็นว่าจากการทดสอบของฉัน (ในรุ่นโครเมี่ยม / 2018 รุ่นใหม่) ที่โซลูชันนี้ทำงานได้อย่างน่าเชื่อถือมากขึ้น
mattLummus

สิ่งนี้ไม่ "ป้องกันเบราว์เซอร์ที่เลื่อนไปยังตำแหน่งที่ผ่านมา" ดูคำตอบของฉัน
RayLoveless

85

คุณเกือบจะได้มัน - คุณจำเป็นต้องตั้งค่าscrollTopในbodyไม่window:

$(function() {
   $('body').scrollTop(0);
});

แก้ไข:

บางทีคุณสามารถเพิ่มสมอเปล่าลงไปด้านบนของหน้า:

$(function() {
   $('<a name="top"/>').insertBefore($('body').children().eq(0));
   window.location.hash = 'top';
});

3
ลองใช้วันนี้และใช้งานไม่ได้กับ FF16 การใช้ JS บริสุทธิ์เห็นด้านล่างในหน้านี้แทน: document.body.scrollTop = document.documentElement.scrollTop = 0;
Gigi2m02

2
โค้ดด้านบนจะทำงานอย่างถูกต้องในเบราว์เซอร์สมัยใหม่เช่น FF, Chrome แต่จะไม่ทำงานใน IE8 และด้านล่างพยายามเพิ่มทั้งสอง'html','body'เนื่องจากเบราว์เซอร์สมัยใหม่จะเลื่อนตามเนื้อหา แต่ IE8 และด้านล่างจะเลื่อนด้วย'html', 'body'
Rajesh

17

มีวิธีป้องกันเบราว์เซอร์ที่เลื่อนไปยังตำแหน่งที่ผ่านมาหรือเลื่อนอีกครั้งไปด้านบนหลังจากที่มันทำมันได้หรือไม่

โซลูชัน jquery ต่อไปนี้ใช้ได้สำหรับฉัน:

$(window).unload(function() {
    $('body').scrollTop(0);
});

แท้จริงแล้วเลื่อนไปด้านบนก่อนรีเฟรช
Morgan T.

ไม่ข้ามเบราว์เซอร์ทั้งหมด แต่ยังคงใช้งานได้เป็นส่วนใหญ่ เมื่อบวกกับคำตอบอื่น ๆ แล้วนี่เป็นการเพิ่มที่ดี
Brad Decker

16

ต่อไปนี้เป็นเวอร์ชันการเลื่อน JavaScript ที่เคลื่อนไหวแบบเคลื่อนไหวสำหรับ no-jQuery'ers: D

var stepTime = 20;
var docBody = document.body;
var focElem = document.documentElement;

var scrollAnimationStep = function (initPos, stepAmount) {
    var newPos = initPos - stepAmount > 0 ? initPos - stepAmount : 0;

    docBody.scrollTop = focElem.scrollTop = newPos;

    newPos && setTimeout(function () {
        scrollAnimationStep(newPos, stepAmount);
    }, stepTime);
}

var scrollTopAnimated = function (speed) {
    var topOffset = docBody.scrollTop || focElem.scrollTop;
    var stepAmount = topOffset;

    speed && (stepAmount = (topOffset * stepTime)/speed);

    scrollAnimationStep(topOffset, stepAmount);
};

แล้ว:

<button onclick="scrollTopAnimated(1000)">Scroll Top</button>

1
เย็น. แม้ว่าผมจะชอบแทนrequestAnimationStep setTimeoutนอกจากนี้ยังไม่ตอบคำถามของ OP
Quentin Roy

ดำเนินการนี้ในเชิงมุม ทำงานเหมือนจับใจ ขอบคุณ
Ahmad

12

UPDATE

การไปที่ด้านบนสุดของหน้าเว็บด้วยเอฟเฟกต์เลื่อนเป็นเรื่องง่ายขึ้นเล็กน้อยใน javascript ตอนนี้ด้วย:

https://developer.mozilla.org/en-US/docs/Web/API/Window/scroll

window.scroll({
 top: 0, 
 left: 0, 
 behavior: 'smooth' 
});

ข้อควรระวัง

เราได้ใช้สิ่งนี้ในโครงการล่าสุดของเรา แต่ฉันเพิ่งตรวจสอบ mozilla doc ทันทีในขณะที่อัปเดตคำตอบของฉันและฉันเชื่อว่ามันได้รับการปรับปรุง ตอนนี้วิธีการที่เป็นwindow.scroll(x-coord, y-coord)และไม่ได้พูดถึงหรือแสดงตัวอย่างที่ใช้objectพารามิเตอร์ที่คุณสามารถตั้งค่าการbehavior smoothฉันพยายามรหัสและยังคงทำงานใน Chrome และ Firefox และพารามิเตอร์วัตถุที่ยังคงอยู่ในสเปค

ดังนั้นควรใช้ด้วยความระมัดระวังหรือคุณสามารถใช้Polyfillนี้ได้ นอกเหนือจากการเลื่อนไปที่ด้านบนแล้ว polyfill นี้ยังจัดการกับวิธีการอื่น: window.scrollBy, element.scrollIntoViewและอื่น ๆ


คำตอบเดิม ๆ

นี่คือjavascriptการดำเนินการวานิลลาของเรา มันมีง่ายบรรเทาผลกระทบเพื่อให้ผู้ใช้ไม่ได้รับตกใจหลังจากคลิกไปด้านบนปุ่ม

มันเล็กมากและเล็กลงเมื่อย่อขนาด ผู้ที่กำลังมองหาทางเลือกอื่นสำหรับวิธีการ jquery แต่ต้องการผลลัพธ์เดียวกันสามารถลองได้

JS

document.querySelector("#to-top").addEventListener("click", function(){

    var toTopInterval = setInterval(function(){

        var supportedScrollTop = document.body.scrollTop > 0 ? document.body : document.documentElement;

        if (supportedScrollTop.scrollTop > 0) {
            supportedScrollTop.scrollTop = supportedScrollTop.scrollTop - 50;
        }

        if (supportedScrollTop.scrollTop < 1) {
            clearInterval(toTopInterval);
        }

    }, 10);

},false);

HTML

<button id="to-top">To Top</button>

ไชโย!


8

สิ่งนี้ใช้ได้กับฉัน:

window.onload = function() {
    // short timeout
    setTimeout(function() {
        $(document.body).scrollTop(0);
    }, 15);
};

ใช้สั้น ๆsetTimeoutภายในonloadเพื่อเปิดโอกาสให้เบราว์เซอร์ทำการเลื่อน


ในการทำให้การทำงานข้ามเบราว์เซอร์ IE / Chrome / FF ของฉันฉันต้องรวมคำตอบ Niet Dark Absolute และ user113716 คำตอบ (โดยใช้การหมดเวลา)
Panini Luncher

@Panini: คำแนะนำของคุณใช้ได้กับฉันบน Chrome / FF แต่ไม่ใช่ IE11
EML

8

คุณสามารถใช้กับ jQuery

jQuery(window).load(function(){

    jQuery("html,body").animate({scrollTop: 100}, 1000);

});

นี่คือสิ่งที่ฉันพบในที่สุดเมื่อใช้งาน CentOS 6.7 โดยใช้ FF 45.1.0 รุ่นที่แตกต่างกันเล็กน้อยของฉัน (ห่อในฟังก์ชั่นโหลดหน้าต่าง) คือ: $ ("html, body") ภาพเคลื่อนไหว ({scrollTop: 0}, 1);
Brandon Elliott

6

ใช้ฟังก์ชั่นต่อไปนี้

window.scrollTo(xpos, ypos)

ต้องมี xpos ที่นี่ พิกัดที่เลื่อนไปตามแกน x (แนวนอน) เป็นพิกเซล

ypos ยังเป็นสิ่งจำเป็น พิกัดที่จะเลื่อนไปตามแนวแกน y (แนวตั้ง) เป็นพิกเซล


5
$(function() {
    // the element inside of which we want to scroll
        var $elem = $('#content');

        // show the buttons
    $('#nav_up').fadeIn('slow');
    $('#nav_down').fadeIn('slow');  

        // whenever we scroll fade out both buttons
    $(window).bind('scrollstart', function(){
        $('#nav_up,#nav_down').stop().animate({'opacity':'0.2'});
    });
        // ... and whenever we stop scrolling fade in both buttons
    $(window).bind('scrollstop', function(){
        $('#nav_up,#nav_down').stop().animate({'opacity':'1'});
    });

        // clicking the "down" button will make the page scroll to the $elem's height
    $('#nav_down').click(
        function (e) {
            $('html, body').animate({scrollTop: $elem.height()}, 800);
        }
    );
        // clicking the "up" button will make the page scroll to the top of the page
    $('#nav_up').click(
        function (e) {
            $('html, body').animate({scrollTop: '0px'}, 800);
        }
    );
 });

ใช้สิ่งนี้


ดี! ทำงานได้ดีกับภาพเคลื่อนไหว!
Sakthivel

4

รหัสต่อไปนี้ใช้งานได้ใน Firefox, Chrome และSafariแต่ฉันไม่สามารถทดสอบได้ใน Internet Explorer ใครบางคนสามารถทดสอบและแก้ไขคำตอบหรือแสดงความคิดเห็นได้

$(document).scrollTop(0);

4

โซลูชัน Javascript แบบเคลื่อนไหวของฉันบริสุทธิ์

function gototop() {
    if (window.scrollY>0) {
        window.scrollTo(0,window.scrollY-20)
        setTimeout("gototop()",10)
    }
}

คำอธิบาย:

window.scrollY เป็นตัวแปรที่ดูแลโดยเบราว์เซอร์ของจำนวนพิกเซลจากด้านบนที่หน้าต่างถูกเลื่อนโดย

window.scrollTo(x,y) เป็นฟังก์ชั่นที่เลื่อนหน้าต่างจำนวนเฉพาะของพิกเซลบนแกน x และแกน Y

ดังนั้นwindow.scrollTo(0,window.scrollY-20)เลื่อนหน้า 20 พิกเซลไปทางด้านบน

การsetTimeoutเรียกฟังก์ชั่นอีกครั้งใน 10 มิลลิวินาทีเพื่อให้เราสามารถย้ายได้อีก 20 พิกเซล (เคลื่อนไหว) และifคำสั่งตรวจสอบว่าเรายังคงต้องเลื่อน


3

ทำไมคุณไม่ใช้องค์ประกอบอ้างอิงบางตัวที่จุดเริ่มต้นของไฟล์ html เช่น

<div id="top"></div>

จากนั้นเมื่อโหลดหน้าเว็บ

$(document).ready(function(){

    top.location.href = '#top';

});

หากเบราว์เซอร์เลื่อนหลังจากที่ไฟไหม้ฟังก์ชันนี้คุณก็ทำ

$(window).load(function(){

    top.location.href = '#top';

});

3
นี้ทำงานให้ฉัน แต่มันเพิ่ม #top ใน URL ที่คุณสามารถกรุณาช่วยบอกฉันว่าฉันสามารถหลีกเลี่ยงปัญหานี้ แต่ในเวลาเดียวกันไม่กระทบกับการทำงาน
อับบาส

3

เลื่อนข้ามเบราว์เซอร์ไปด้านบน:

        if($('body').scrollTop()>0){
            $('body').scrollTop(0);         //Chrome,Safari
        }else{
            if($('html').scrollTop()>0){    //IE, FF
                $('html').scrollTop(0);
            }
        } 

เบราว์เซอร์เลื่อนไปยังองค์ประกอบที่มี id = div_id นี้:

        if($('body').scrollTop()>$('#div_id').offset().top){
            $('body').scrollTop($('#div_id').offset().top);         //Chrome,Safari
        }else{
            if($('html').scrollTop()>$('#div_id').offset().top){    //IE, FF
                $('html').scrollTop($('#div_id').offset().top);
            }
        } 

2

ในการตอบของคุณแก้ไขในคำถามที่คุณสามารถลงทะเบียนonscrollจัดการเช่นดังนั้น:

document.documentElement.onscroll = document.body.onscroll = function() {
    this.scrollTop = 0;
    this.onscroll = null;
}

นี้จะทำให้มันเพื่อให้ความพยายามครั้งแรกที่เลื่อน (ซึ่งมีแนวโน้มที่หนึ่งโดยอัตโนมัติของเบราว์เซอร์) จะถูกยกเลิกได้อย่างมีประสิทธิภาพ


วิธีแก้ปัญหาที่ดี - ฉันจะลองดู
Yarin

2

หากคุณอยู่ในโหมด quircks (ขอบคุณ @Niet the Dark Absolute):

document.body.scrollTop = document.documentElement.scrollTop = 0;

หากคุณอยู่ในโหมดเข้มงวด:

document.documentElement.scrollTop = 0;

ไม่จำเป็นต้องใช้ jQuery ที่นี่



2

ในกรณีของร่างกายไม่ทำงาน:

$('body').scrollTop(0);

แต่ HTML ใช้งานได้:

$('html').scrollTop(0);

1
เพิ่มทั้ง'html','body'เบราว์เซอร์สมัยใหม่ FF, Chrome จะเลื่อนตามเนื้อหา แต่ IE8 และด้านล่างจะเลื่อนด้วย'html','body'
Rajesh

2

การรวมกันของทั้งสองช่วยฉันได้ ไม่มีคำตอบอื่นใดที่ช่วยฉันตั้งแต่ฉันมี sidenav ที่ไม่ได้เลื่อน

 setTimeout(function () {
        window.scroll({
                        top: 0,
                        left: 0,
                        behavior: 'smooth'
                    });

    document.body.scrollTop = document.documentElement.scrollTop = 0;

}, 15);

1
var totop = $('#totop');
totop.click(function(){
 $('html, body').stop(true,true).animate({scrollTop:0}, 1000);
 return false;
});

$(window).scroll(function(){
 if ($(this).scrollTop() > 100){ 
  totop.fadeIn();
 }else{
  totop.fadeOut();
 }
});

<img id="totop" src="img/arrow_up.png" title="Click to go Up" style="display:none;position:fixed;bottom:10px;right:10px;cursor:pointer;cursor:hand;"/>


1

หากใครใช้การออกแบบเชิงมุมและวัสดุด้วย sidenav สิ่งนี้จะส่งคุณไปที่ด้านบนของหน้า:

let ele = document.getElementsByClassName('md-sidenav-content');
    let eleArray = <Element[]>Array.prototype.slice.call(ele);
    eleArray.map( val => {
        val.scrollTop = document.documentElement.scrollTop = 0;
    });

0

Seeint กัญชาควรทำงาน หากคุณมีส่วนหัวคุณสามารถใช้

window.location.href = "#headerid";

มิฉะนั้น # เพียงอย่างเดียวจะทำงาน

window.location.href = "#";

และเมื่อมันถูกเขียนลงใน URL มันจะยังคงอยู่หากคุณรีเฟรช

ในความเป็นจริงคุณไม่จำเป็นต้องใช้ JavaScript เพื่อทำเช่นนั้นหากคุณต้องการที่จะทำในเหตุการณ์ onclick คุณควรใส่ลิงค์ที่จะจัดองค์ประกอบให้คุณและให้ # เป็น href


Btw, window.location ไม่ได้เป็นส่วนหนึ่งของแผนผังดังนั้นตอนนี้มีการใช้เพื่อรอการโหลด
xavierm02

0

แรกเพิ่มแท็กสมอว่างเปล่ายังสถานที่ที่คุณต้องการไป

<a href="#topAnchor"></a> 

ตอนนี้เพิ่มฟังก์ชั่นในส่วนหัว

 function GoToTop() {
            var urllocation = location.href;
            if (urllocation.indexOf("#topAnchor") > -1) {
                window.location.hash = "topAnchor";
            } else {
                return false;
            }
        }

ในที่สุดก็เพิ่มเหตุการณ์ onload ไปที่แท็กร่างกาย

<body onload="GoToTop()">

0

เวอร์ชันทั่วไปที่ใช้งานได้กับค่า X และ Y ใด ๆ และเหมือนกับ window.scrollTo api เพียงแค่เพิ่ม scrollDuration

* เวอร์ชันทั่วไปที่ตรงกับหน้าต่างเลื่อนไปยังเบราว์เซอร์ API API

function smoothScrollTo(x, y, scrollDuration) {
    x = Math.abs(x || 0);
    y = Math.abs(y || 0);
    scrollDuration = scrollDuration || 1500;

    var currentScrollY = window.scrollY,
        currentScrollX = window.scrollX,
        dirY = y > currentScrollY ? 1 : -1,
        dirX = x > currentScrollX ? 1 : -1,
        tick = 16.6667, // 1000 / 60
        scrollStep = Math.PI / ( scrollDuration / tick ),
        cosParameterY = currentScrollY / 2,
        cosParameterX = currentScrollX / 2,
        scrollCount = 0,
        scrollMargin;

    function step() {        
        scrollCount = scrollCount + 1;  

        if ( window.scrollX !== x ) {
            scrollMargin = cosParameterX + dirX * cosParameterX * Math.cos( scrollCount * scrollStep );
            window.scrollTo( 0, ( currentScrollX - scrollMargin ) );
        } 

        if ( window.scrollY !== y ) {
            scrollMargin = cosParameterY + dirY * cosParameterY * Math.cos( scrollCount * scrollStep );
            window.scrollTo( 0, ( currentScrollY - scrollMargin ) );
        } 

        if (window.scrollX !== x || window.scrollY !== y) {
            requestAnimationFrame(step);
        }
    }

    step();
}

0

ฉันจำได้ว่าเคยเห็นโพสต์นี้ที่อื่น (ฉันหาที่ไหนไม่ได้) แต่ก็ใช้ได้ดี:

setTimeout(() => {
    window.scrollTo(0, 0);
}, 0);

มันแปลก แต่วิธีการทำงานนั้นอิงกับวิธีการทำงานของสแต็กคิวของ JavaScript คำอธิบายแบบเต็มสามารถดูได้ที่นี่ในหัวข้อ Zero Delays

แนวคิดพื้นฐานคือเวลาที่setTimeoutไม่ได้ระบุจำนวนเวลาที่ตั้งไว้จริงจะรอ แต่จำนวนเวลาขั้นต่ำที่จะรอ ดังนั้นเมื่อคุณบอกให้รอ 0ms เบราว์เซอร์จะดำเนินการกระบวนการเข้าคิวอื่น ๆ ทั้งหมด (เช่นเลื่อนหน้าต่างไปยังตำแหน่งที่คุณอยู่ล่าสุด) จากนั้นเรียกใช้การเรียกกลับ


-1
 <script>
  sessionStorage.scrollDirection = 1;//create a session variable 
  var pageScroll = function() {
  window.scrollBy ({
   top: sessionStorage.scrollDirection,
   left: 0,
   behavior: 'smooth'
   });
   if($(window).scrollTop() + $(window).height() > $(document).height() - 1)
  {    
    sessionStorage.scrollDirection= Number(sessionStorage.scrollDirection )-300;
    setTimeout(pageScroll,50);//
   }
   else{
   sessionStorage.scrollDirection=Number(sessionStorage.scrollDirection )+1
   setTimeout(pageScroll,300); 
  }
};
pageScroll();
</script>

1
ยินดีต้อนรับสู่ stackoverflow นอกจากรหัสที่คุณให้มาแล้วพยายามอธิบายสาเหตุและวิธีการนี้ในการแก้ไขปัญหา
jtate
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.