คุณสามารถใช้การนำทางแฮชโดยไม่ส่งผลต่อประวัติได้หรือไม่?


100

ฉันกลัวว่ามันอาจจะเป็นไปไม่ได้แต่จะมีวิธีเปลี่ยนค่าแฮชของ URL โดยไม่ทิ้งรายการไว้ในประวัติของเบราว์เซอร์และไม่ต้องโหลดซ้ำได้หรือไม่? หรือทำเทียบเท่า?

เท่าที่เฉพาะเจาะจงไปฉันกำลังพัฒนาการนำทางแฮชขั้นพื้นฐานตามแนวของ:

//hash nav -- works with js-tabs
var getHash = window.location.hash;
var hashPref = "tab-";
function useHash(newHash) {
    //set js-tab according to hash
    newHash = newHash.replace('#'+hashPref, '');
    $("#tabs li a[href='"+ newHash +"']").click();
}
function setHash(newHash) {
    //set hash according to js-tab
    window.location.hash = hashPref + newHash;

    //THIS IS WHERE I would like to REPLACE the location.hash
    //without a history entry

}
    // ... a lot of irrelavent tabs js and then....

    //make tabs work
    $("#tabs.js-tabs a").live("click", function() {
        var showMe = $(this).attr("href");
        $(showMe).show();
        setHash(showMe);
        return false;
    });
    //hash nav on ready .. if hash exists, execute
    if ( getHash ){
        useHash(getHash);
    }

เห็นได้ชัดว่าใช้ jQuery แนวคิดก็คือในอินสแตนซ์เฉพาะนี้ 1) การทำให้ผู้ใช้ย้อนกลับไปในทุกการเปลี่ยนแปลงแท็บอาจทำให้ 'ทำลายปุ่มย้อนกลับ' ได้อย่างมีประสิทธิภาพโดยการรวบรวมข้อมูลอ้างอิงที่ไม่จำเป็นและ 2) ไม่เก็บแท็บที่กำลังใช้งานอยู่หากพวกเขากดรีเฟรช ความรำคาญ


ทำไมคุณถึงต้องการเปลี่ยนแฮชถ้าคุณไม่ต้องการติดตามประวัติ : |
Ionuț Staicu

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

คำตอบ:


96

location.replace("#hash_value_here");ทำงานได้ดีสำหรับฉันจนกว่าฉันจะพบว่ามันไม่ทำงานบน IOS Chrome ในกรณีนี้ให้ใช้:

history.replaceState(undefined, undefined, "#hash_value")

history.replaceState ()ทำงานเหมือนกับ history.pushState () ทุกประการยกเว้นว่า replaceState () แก้ไขรายการประวัติปัจจุบันแทนที่จะสร้างรายการใหม่

อย่าลืมเก็บไว้#หรือส่วนสุดท้ายของ url จะถูกเปลี่ยนแปลง


3
วิธีที่จะไปสำหรับเบราว์เซอร์สมัยใหม่โดยสิ้นเชิง โปรดทราบว่ามีการจัดการประวัติเซสชันการสนับสนุนบางส่วน
แมตต์

ฉันสับสนว่าจะใช้สิ่งนี้ได้อย่างไร ฉันควรใช้window.location.hash = 'my-hash';ตามด้วยhistory.replaceState(undefined, undefined, "#my-hash")หรือไม่?
Bram Vanroy

2
@BramVanroy ไม่ใช้อย่างหลังก็เพียงพอแล้ว
Lucia

2
ถ้าคุณไม่ใช้: ตัวเลือกเป้าหมาย ... ฟังก์ชันประวัติจะไม่มีประโยชน์เนื่องจากส่วนหนึ่งของข้อมูลจำเพาะ (การโต้ตอบ css กับตัวเลือกประวัติ) ดูเหมือนจะไม่ได้กำหนดไว้ในขณะนี้และสไตล์จะไม่ได้รับการคำนวณใหม่ในการแทนที่ประวัติโดยเบราว์เซอร์ส่วนใหญ่ / ทั้งหมด
morphles

1
หมายเหตุ: ที่น่าสนใจhistory.replaceState(...)ไม่ได้ก่อให้เกิดwindow.onhashchangeเหตุการณ์ location.replaceทำ. แปลกใช่มั้ย?
แมตต์

101
location.replace("#hash_value_here"); 

ข้างต้นดูเหมือนจะทำในสิ่งที่คุณต้องการ


4
นี่ไง. และถ้าคุณมีเซ็กเมนต์ uri location.replace (window.location + "#hash") จะเก็บรักษาไว้
tedders

7
สองวิธีนี้สะอาดกว่ามากหวังว่ามันจะเป็นคำตอบที่ถูกต้อง
joeellis

14
window.location.replace(('' + window.location).split('#')[0] + '#' + hash);เพื่ออัปเดตแฮช
johnstorm

1
ฉันกำลังทดสอบใน Chrome 30 ภายใต้ Windows 8 หากฉันไปที่ประวัติ Chrome และเลือก "เพิ่มเติมจากไซต์นี้" ภายใต้ URL ทดสอบของฉันฉันจะเห็นแฮชทั้งหมดที่เพิ่มเข้ามาด้วยวิธีนี้
Alex Vang

2
ระวังว่า location.replace ('# hash_value_here') เปลี่ยนเฉพาะส่วนของแฮชและไม่ใช่พา ธ ดังนั้นจึงไม่ทริกเกอร์การโหลดหน้า .... ยกเว้นเมื่อเอกสารมีแท็กฐาน: <base href ="http://example.com/" /> หากมีแท็กฐาน จากนั้นเมื่อคุณใช้วิธีการแทนที่ด้วยเพียงแค่นำหน้า"#hash_value_here"มันจะเหมือนกับว่าคุณพูดว่า `` location.replace (' example.com/#hash_value_here' ) สิ่งนี้ดูเหมือนชัดเจนเมื่อคุณอ่านที่นี่ แต่เป็น gotcha เมื่อคุณอยู่ในหน้าที่มีส่วนของเส้นทางและไม่ทราบว่ามีการตั้งค่าฐาน
Tyler Kasten

6

แก้ไข:เป็นเวลาสองสามปีแล้วและเบราว์เซอร์มีการพัฒนา

คำตอบของ @ Luxiyalu คือหนทางที่จะไป

- คำตอบเก่า -

ฉันคิดว่ามันเป็นไปไม่ได้เช่นกัน (ในเวลานี้) แต่ทำไมคุณต้องเปลี่ยนค่าแฮชถ้าคุณจะไม่ใช้มัน?

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

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

ฉันหวังว่านี่จะช่วยคุณได้ อาจมีวิธีแก้ปัญหาที่ง่ายกว่านี้

UPDATE: แล้ว สิ่งนี้:

  1. ตั้งค่าแฮชแรกและตรวจสอบให้แน่ใจว่าได้บันทึกไว้ในประวัติเบราว์เซอร์
  2. เมื่อมีการเลือกแท็บใหม่ให้ทำwindow.history.back(1)ซึ่งจะทำให้ประวัติย้อนกลับไปจากแฮชเริ่มต้นของคุณ
  3. ตอนนี้คุณตั้งค่าแฮชใหม่แล้วดังนั้นการแท็บจะทำให้มีเพียงรายการเดียวในประวัติ

คุณอาจต้องใช้แฟล็กเพื่อดูว่ารายการปัจจุบันสามารถ "ลบ" ได้หรือไม่โดยการย้อนกลับหรือถ้าคุณข้ามขั้นตอนแรกไป และเพื่อให้แน่ใจว่าวิธีการโหลด "แฮช" ของคุณไม่ทำงานเมื่อคุณบังคับใช้history.back.


เป็นไปได้มากว่ามีบางอย่างพื้นฐานที่ฉันขาดหายไป (ความเหนื่อยเป็นข้อแก้ตัวที่ดีฉันจะไปด้วย) แต่คุณกำลังบอกว่าฉันสามารถตั้งค่าตัวแปรที่จะรักษาค่าที่เปลี่ยนแปลงเมื่อโหลดซ้ำได้หรือไม่ นอกจากคุกกี้? (คุกกี้ดูเหมือนจะมากเกินไป แต่ .. ) บางทีนั่นอาจจะยังไม่ชัดเจนนัก ฉันจะใช้ค่าแฮช - โดยเฉพาะอย่างยิ่งในการโหลดซ้ำ ขอบคุณที่ตอบกลับ!

เพื่อชี้แจงคำชี้แจงของฉัน: หากผู้ใช้กดโหลดซ้ำ นั่นคือสิ่งที่แฮชมีไว้สำหรับ ฉันยังคงพยายามหลีกเลี่ยงการโหลดซ้ำในการใช้งานปกติ (เปลี่ยน / คลิกแท็บ)

โอเคคุณจะใช้ค่าบางอย่างสำหรับข้อมูลหลังจากโหลดซ้ำ น่าเสียดายที่ค่าแฮชจะถูกเลือกโดยประวัติของเบราว์เซอร์บางตัว ขออภัยที่ต้องพูดแบบนี้ แต่จากประสบการณ์ของฉันคุกกี้คือทางออกที่ดีที่สุดของคุณ หากคุณต้องการบางสิ่งที่ประวัติเบราว์เซอร์ตรวจไม่พบ แต่ต้องเก็บไว้หลังจากโหลดซ้ำขออภัยคุกกี้ หากผู้ใช้คลิกลิงก์คุณสามารถตั้งค่าลิงก์ให้เป็นแบบสอบถาม ( ?mystate=greatness) ได้แม้ว่าจะไม่จำเป็นต้องเป็น ajax แต่คุณสามารถบันทึกข้อมูลเพื่อให้จาวาสคริปต์อ่านเมื่อเริ่มต้นคำขอได้
guzart

ใช่แฮชมีไว้สำหรับบันทึกข้อมูลของผู้ใช้หลังจากกดปุ่มรีโหลด แต่ปัญหาสำหรับคุณคือเบราว์เซอร์บางตัวจะบันทึกการเปลี่ยนแปลงเหล่านั้นในประวัตินั่นเป็นเพียงวิธีการทำงาน ... :(
guzart

ใช่คิดว่าคุณพูดถูก อืม. (ชอบที่จะพิสูจน์ว่าผิดด้วยวิธีการอื่นหรือบางสิ่งบางอย่าง)

-1

คุณสามารถสร้างตัวฟังเหตุการณ์เพื่อจับเหตุการณ์การคลิกบนไฮเปอร์ลิงก์ได้ตลอดเวลาและในฟังก์ชันเรียกกลับให้ใส่ e.preventDefault () ซึ่งจะป้องกันไม่ให้เบราว์เซอร์แทรกลงในประวัติ

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