กระโดดสมอโดยใช้จาวาสคริปต์


130

ฉันมีคำถามที่จะพบบ่อยมาก ปัญหาคือไม่มีที่ไหนสามารถหาวิธีแก้ปัญหาที่ชัดเจนได้

ฉันมีปัญหาสองประการเกี่ยวกับแองเคอร์

เป้าหมายหลักคือการได้รับ url ที่สะอาดโดยไม่ต้องแฮชใด ๆ ในขณะที่ใช้จุดยึดเพื่อข้ามไปยังหน้าเว็บ

ดังนั้นโครงสร้างของพุกคือ:

<ul>
    <li><a href="#one">One</a></li>
    <li><a href="#two">Two</a></li>
    <li><a href="#three">Three</a></li>
</ul>

<div class="wrap">
    <a name="one">text 1</a>
    <a name="two">text 2</a>
    <a name="three" class="box">text 3</a>
</div>

โอเคถ้าคุณจะคลิกลิงค์ใดลิงค์หนึ่ง url จะเปลี่ยนเป็นโดยอัตโนมัติ

www.domain.com/page#1

ในตอนท้ายควรเป็นเพียง:

www.domain.com/page

จนถึงตอนนี้ดีมาก ตอนนี้สิ่งที่สองคือเมื่อคุณค้นหาอินเทอร์เน็ตสำหรับปัญหานั้นคุณจะพบjavascriptวิธีแก้ปัญหา

ฉันพบฟังก์ชันนี้แล้ว:

function jumpto(anchor){
    window.location.href = "#"+anchor;
}

และเรียกใช้ฟังก์ชันนั้นด้วย:

<a onclick="jumpto('one');">One</a>

อะไรจะเหมือนเดิม มันจะเพิ่มแฮชใน url ฉันยังเพิ่ม

<a onclick="jumpto('one'); return false;">

ปราศจากความสำเร็จ. ดังนั้นหากมีใครสามารถบอกวิธีแก้ปัญหานี้ได้ฉันจะขอบคุณจริงๆ

ขอบคุณมาก.


ไม่แน่ใจเกี่ยวกับสิ่งนี้ แต่คุณสามารถลองเขียนคุณสมบัติแฮชด้วยตนเองหลังจากกระโดด ยกตัวอย่างเช่นการตั้งค่าหมดเวลาในการจัดการ onclick window.location.hash=''ซึ่งชุด
Jeff

คุณหมายความว่าคุณไม่ต้องการให้ # แสดงใน URL เมื่อข้ามไปยังส่วนอื่นในหน้าเว็บเดียวกันหรือไม่?
Roger Ng

2
ในกรณีนี้คุณจะต้องจัดการ scrollTop ของหน้าต่างโดยทั่วไปwindow.scrollToหรือโดยผู้ช่วย jQuery ที่เกี่ยวข้อง: stackoverflow.com/questions/6677035/jquery-scroll-to-elementหรือstackoverflow.com/questions/500336/…
Frank van Puffelen

@ Jeff - ถ้าคุณทำเช่นlocation.hash=''นี้#ยังคงมี
Derek 朕會功夫

อย่าทำอย่างนั้นได้โปรด แฮชเป็นสิ่งที่ดีเมื่อบันทึกหน้าในบุ๊กมาร์กของคุณ
Marco Sulla

คำตอบ:


205

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

นี่เป็นวิธีที่ง่ายกว่าในการทำเช่นนั้น:

function jump(h){
    var url = location.href;               //Save down the URL without hash.
    location.href = "#"+h;                 //Go to the target element.
    history.replaceState(null,null,url);   //Don't like hashes. Changing it back.
}

สิ่งนี้ใช้replaceStateเพื่อจัดการกับ url หากคุณต้องการการสนับสนุนสำหรับ IEคุณจะต้องทำวิธีที่ซับซ้อน :

function jump(h){
    var top = document.getElementById(h).offsetTop; //Getting Y of target element
    window.scrollTo(0, top);                        //Go there directly or some transition
}​

การสาธิต: http://jsfiddle.net/DerekL/rEpPA/
อีกอันที่มีการเปลี่ยนแปลง: http://jsfiddle.net/DerekL/x3edvp4t/

คุณยังสามารถใช้.scrollIntoView:

document.getElementById(h).scrollIntoView();   //Even IE6 supports this

(ฉันโกหกมันไม่ซับซ้อนเลย)


1
หนู !! ลิงก์เสีย :-( ฉันคิดว่า JS Fiddles อยู่ที่นั่นตลอดไป
Mawg บอกว่าคืนสถานะ Monica

1
@Mawg เห็นได้ชัดว่าพวกเขาได้ลบความสามารถในการใช้ add /showที่ท้าย url
Derek 朕會功夫

12
"แม้แต่ IE6 ก็รองรับ" เป็นความคิดเห็นที่ดีที่สุดที่ฉันเคยเห็น
Josh

3
@Black ไม่มีองค์ประกอบ“ jQuery” $(mySelector)[0].scrollIntoView()หากคุณต้องการที่จะได้รับองค์ประกอบแรกออกจากการสืบค้นของคุณให้ทำ
Derek 朕會功夫

4
1+ สำหรับscrollIntoView. 1- สำหรับการพูดถึงมันเป็นครั้งสุดท้าย
Yay295

12

ฉันคิดว่ามันเป็นวิธีที่ง่ายกว่ามาก:

window.location = (""+window.location).replace(/#[A-Za-z0-9_]*$/,'')+"#myAnchor"

วิธีนี้จะไม่โหลดเว็บไซต์ซ้ำและกำหนดโฟกัสที่จุดยึดที่จำเป็นสำหรับโปรแกรมอ่านหน้าจอ


และสิ่งที่ไม่ค่อยทำงานบน IE สิ่งนี้ใช้ได้กับ IE ทั้งหมด)
Adam111p

5
ฉันลงเอยด้วยwindow.location = window.location.origin + window.location.pathname + '#hash';
Alex

สิ่งนี้โหลดหน้านี้ซ้ำสำหรับฉัน คำตอบที่ยอมรับลงเอยด้วยการทำงาน แต่ฉันหวังว่ามันจะสั้นกว่านี้
HoldOffHunger

3

ตัวแทนไม่เพียงพอสำหรับความคิดเห็น

เมธอดที่ใช้ getElementById () ในคำตอบที่เลือกจะไม่ทำงานหากจุดยึดมีnameแต่ไม่ได้idตั้งค่า (ซึ่งไม่แนะนำ แต่จะเกิดขึ้นในป่า)

สิ่งที่ต้องคำนึงถึงหากคุณไม่สามารถควบคุมมาร์กอัปเอกสารได้ (เช่นการขยายหน้าเว็บ)

locationวิธีการที่อยู่ในคำตอบที่เลือกนอกจากนี้ยังสามารถง่ายกับlocation.replace:

function jump(hash) { location.replace("#" + hash) }

1

เพราะเมื่อคุณทำ

window.location.href = "#"+anchor;

คุณโหลดหน้าใหม่คุณสามารถทำได้:

<a href="#" onclick="jumpTo('one');">One</a>
<a href="#" id="one"></a>

<script>

    function getPosition(element){
        var e = document.getElementById(element);
        var left = 0;
        var top = 0;

        do{
            left += e.offsetLeft;
            top += e.offsetTop;
        }while(e = e.offsetParent);

        return [left, top];
    }

    function jumpTo(id){    
        window.scrollTo(getPosition(id));
    }

</script>

3
ฉันไม่คิดว่าการเพิ่มแฮชจะทำให้เป็นเพจใหม่
Derek 朕會功夫

5
มันไม่โหลดหน้าซ้ำ
Derek 朕會功夫

คุณคิดถูกแล้วที่ไม่โหลดหน้าซ้ำ ฉันลองในคอนโซลด้วย chrome และไอคอน Fav ถูกโหลดใหม่
Jonathan Vukovich-Tribouharet

ใน Firefox ล่าสุดการเปลี่ยนแปลงแฮชดูเหมือนจะบังคับให้โหลดซ้ำสำหรับ iFrames (ในแอตทริบิวต์ src) ฉันคิดว่านี่เป็นข้อบกพร่องของเบราว์เซอร์ แต่สิ่งที่ต้องระวัง
Beejor

1

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

ในไฟล์. html ฉันมี:

<button onclick="myFunction()">Load Prompt</button>
<span id="test100"><h4>Hello</h4></span>

ในไฟล์. js ฉันมี

function myFunction() {
    var input = prompt("list or new or quit");

    while(input !== "quit") {
        if(input ==="test100") {
            window.location.hash = 'test100';
            return;
// else if(input.indexOf("test100") >= 0) {
//   window.location.hash = 'test100';
//   return;
// }
        }
    }
}

เมื่อฉันเขียนtest100ลงในพรอมต์มันจะไปที่ที่ฉันวาง span id = "test100" ไว้ในไฟล์ html

ฉันใช้ Google Chrome

หมายเหตุ: แนวคิดนี้มาจากการเชื่อมโยงในเพจเดียวกันโดยใช้

<a href="#test100">Test link</a>

ซึ่งเมื่อคลิกจะส่งไปยังจุดยึด เพื่อให้ทำงานได้หลายครั้งจากประสบการณ์จำเป็นต้องโหลดหน้าซ้ำ

ให้เครดิตกับคนที่ stackoverflow (และอาจเป็น stackexchange ด้วย) จำไม่ได้ว่าฉันรวบรวมบิตและชิ้นส่วนทั้งหมดได้อย่างไร ☺

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