मैं दस्तावेज़ को जंप किए बिना window.location.hash को कैसे अपडेट कर सकता हूं?


163

मेरी वेबसाइट पर एक स्लाइडिंग पैनल स्थापित है।

जब यह एनिमेशन समाप्त हो गया, तो मैंने हैश को इस तरह सेट किया

function() {
   window.location.hash = id;
}

(यह एक कॉलबैक है, और idपहले सौंपा गया है)।

यह अच्छा है, उपयोगकर्ता को पैनल को बुकमार्क करने की अनुमति देता है, और गैर जावास्क्रिप्ट संस्करण के लिए भी काम करता है।

हालाँकि, जब मैं हैश अपडेट करता हूं, तो ब्राउज़र स्थान पर कूद जाता है। मुझे लगता है कि यह अपेक्षित व्यवहार है।

मेरा सवाल है: मैं इसे कैसे रोक सकता हूं? यानी मैं विंडो के हैश को कैसे बदल सकता हूं, लेकिन अगर हैश मौजूद है तो ब्राउज़र को तत्व में स्क्रॉल नहीं करना चाहिए? किसी event.preventDefault()तरह की बात?

मैं jQuery 1.4 और स्क्रॉलटो प्लगइन का उपयोग कर रहा हूं ।

बहुत धन्यवाद!

अपडेट करें

यहाँ वह कोड है जो पैनल को बदलता है।

$('#something a').click(function(event) {
    event.preventDefault();
    var link = $(this);
    var id = link[0].hash;

    $('#slider').scrollTo(id, 800, {
        onAfter: function() {

            link.parents('li').siblings().removeClass('active');
            link.parent().addClass('active');
            window.location.hash = id;

            }
    });
});

2
मुझे लगता है कि आपने कोशिश की है event.preventDefault():)
मार्को

@ मर्को मुझे नहीं पता कि इसे कहां रखा जाए!
एलेक्स

क्या आप अपना शेष कोड पोस्ट कर सकते हैं?
मार्को

@ मार्को इवानोव्स्की मुझे नहीं लगता कि यह प्रासंगिक है, लेकिन मैं देखूंगा कि मैं क्या कर सकता हूं।
एलेक्स

3
@ मुझे नहीं लगता कि इसके लिए कोई जगह है, क्योंकि जैसे ही मैं हैश को अपडेट करता हूं।
एलेक्स

जवाबों:


261

पुराने ब्राउज़रों पर कमबैक के साथ आधुनिक ब्राउज़रों पर इतिहास एपीआई का उपयोग करके एक समाधान है:

if(history.pushState) {
    history.pushState(null, null, '#myhash');
}
else {
    location.hash = '#myhash';
}

श्रेय ली वेरो को जाता है


यह बेहतर उत्तर है, मेरी राय में।
ग्रेग अन्नडेल

10
ध्यान दें कि पुशस्टेट का ब्राउज़र इतिहास स्टैक में एक राज्य जोड़ने का साइड- (इंडेंट) प्रभाव है। दूसरे शब्दों में, जब उपयोगकर्ता बैक बटन पर क्लिक करता है, तब तक कुछ भी नहीं होगा जब तक कि आप एक पॉपस्टैट इवेंट श्रोता को नहीं जोड़ते।
डेविड कुक

32
@DavidCook - हम history.replaceStateएक popstateईवेंट श्रोता की आवश्यकता से बचने के लिए (जो, हैश परिवर्तन के लिए, अधिक समझ बना सकते हैं) का उपयोग कर सकते हैं ।
जैक

इसने मेरे लिए काम किया। मुझे इतिहास के बदलाव का असर पसंद है। मैं कैविएट जोड़ना चाहता हूं कि यह hashchangeघटना को ट्रिगर नहीं करेगा । वह कुछ ऐसा था जिसके लिए मुझे काम करना था।
जॉर्डन

चेतावनी! यह एक hashchangeघटना को ट्रिगर नहीं करेगा
santiago arizti

52

समस्या यह है कि आप window.location.hash सेट कर रहे हैं एलिमेंट की ID विशेषता के । यह ब्राउज़र के लिए उस तत्व पर कूदने का अपेक्षित व्यवहार है, भले ही आप "preventDefault ()" हों या नहीं।

इसके चारों ओर जाने का एक तरीका है कि हैश को एक मनमाने मूल्य के साथ उपसर्ग करें, जैसे:

window.location.hash = 'panel-' + id.replace('#', '');

फिर, आपको केवल पृष्ठ लोड पर उपसर्ग हैश की जांच करनी है। एक अतिरिक्त बोनस के रूप में, आप इसे तब तक स्क्रॉल कर सकते हैं जब आप अब हैश मान के नियंत्रण में हैं ...

$(function(){
    var h = window.location.hash.replace('panel-', '');
    if (h) {
        $('#slider').scrollTo(h, 800);
    }
});

यदि आपको हर समय काम करने की आवश्यकता है (और केवल प्रारंभिक पृष्ठ लोड पर नहीं), तो आप हैश मान में परिवर्तन की निगरानी करने के लिए एक फ़ंक्शन का उपयोग कर सकते हैं और सही तत्व पर कूद सकते हैं:

var foundHash;
setInterval(function() {
    var h = window.location.hash.replace('panel-', '');
    if (h && h !== foundHash) {
        $('#slider').scrollTo(h, 800);
        foundHash = h;
    }
}, 100);

2
यह एकमात्र समाधान है जो वास्तव में इस प्रश्न का उत्तर देता है - हैशिंग को बिना कूदने की अनुमति
एमोस्मोस

यह वास्तव में डिफ़ॉल्ट ब्राउज़र व्यवहार के अनुसार कूद से बचने के लिए हैश के लिए मनमाना मूल्य को जोड़ने और हटाने के बारे में बताते हुए सवाल का जवाब देता है।
लोटेकसून

1
अच्छा समाधान, लेकिन ओपी समाधान को कमजोर करता है क्योंकि यह बुकमार्किंग वर्गों के उपयोग को नकारता है
सैमस

27

सस्ता और गंदा समाधान .. बदसूरत # का प्रयोग करें! अंदाज।

इसे सेट करने के लिए:

window.location.hash = '#!' + id;

इसे पढ़ने के लिए:

id = window.location.hash.replace(/^#!/, '');

चूंकि यह पृष्ठ में मेल और लंगर या आईडी से मेल नहीं खाता है, इसलिए यह कूद नहीं जाएगा।


3
मुझे IE 7 और साइट के कुछ मोबाइल संस्करणों के साथ संगतता को संरक्षित करना था। यह समाधान मेरे लिए सबसे साफ था। आम तौर पर मैं सभी pushState समाधानों पर होता।
एरिक गुडविन

1
हैश को इसके साथ सेट करना: window.location.hash = '#/' + id;और उसके बाद इसे बदलना: window.location.hash.replace(/^#\//, '#');url को थोड़ा सा projects/#/tab1
हटा देगा

13

आपको वर्तमान स्क्रॉल स्थिति क्यों नहीं मिलती है, इसे एक चर में डालें और फिर हैश असाइन करें और पृष्ठ स्क्रॉल को वापस उस स्थान पर रखें जहां यह था:

var yScroll=document.body.scrollTop;
window.location.hash = id;
document.body.scrollTop=yScroll;

यह काम करना चाहिए


1
हम्म, यह कुछ समय के लिए मेरे लिए काम कर रहा था, लेकिन पिछले कुछ महीनों में यह फ़ायरफ़ॉक्स पर काम करना बंद कर दिया है ....
13'13

10

मैंने आधुनिक ब्राउज़रों के लिए अत्तिला फुलोप (ली वेरौ) समाधान के संयोजन और पुराने ब्राउज़रों के लिए गेविन ब्रॉक समाधान का उपयोग किया:

if (history.pushState) {
    // IE10, Firefox, Chrome, etc.
    window.history.pushState(null, null, '#' + id);
} else {
    // IE9, IE8, etc
    window.location.hash = '#!' + id;
}

जैसा कि गेविन ब्रॉक ने देखा, आईडी वापस लेने के लिए आपको स्ट्रिंग का इलाज करना होगा (जो इस मामले में हो सकता है और "नहीं!") निम्नानुसार है:

id = window.location.hash.replace(/^#!?/, '');

इससे पहले, मैंने user706270 द्वारा प्रस्तावित एक के समान एक समाधान की कोशिश की थी, लेकिन यह इंटरनेट एक्सप्लोरर के साथ अच्छी तरह से काम नहीं करता था: जैसा कि इसका जावास्क्रिप्ट इंजन बहुत तेज नहीं है, आप स्क्रॉल वृद्धि और कमी को नोटिस कर सकते हैं, जो एक बुरा दृश्य प्रभाव पैदा करता है।


2

इस समाधान ने मेरे लिए काम किया।

सेटिंग के साथ समस्या location.hash है कि यदि पृष्ठ पर पाया जाता है तो पेज उस आईडी पर कूद जाएगा।

इसके साथ समस्या window.history.pushStateयह है कि यह उपयोगकर्ता द्वारा प्रत्येक क्लिक के लिए इतिहास में एक प्रविष्टि जोड़ता है। फिर जब उपयोगकर्ता क्लिक करता हैback बटन पर , तो वे पिछले टैब पर जाते हैं। (यह वही हो सकता है या नहीं हो सकता है जो आप चाहते हैं। यह वह नहीं था जो मैं चाहता था)।

मेरे लिए, replaceStateयह बेहतर विकल्प था कि यह केवल वर्तमान इतिहास को बदल देता है, इसलिए जब उपयोगकर्ता backबटन पर क्लिक करता है , तो वे पिछले पृष्ठ पर जाते हैं।

$('#tab-selector').tabs({
  activate: function(e, ui) {
    window.history.replaceState(null, null, ui.newPanel.selector);
  }
});

की जाँच करें इतिहास एपीआई डॉक्स MDN पर।


1

मुझे यकीन नहीं है कि अगर आप मूल तत्व को बदल सकते हैं लेकिन डेटा-आईडी जैसी किसी और चीज़ के आईडी आईडी का उपयोग करने से कैसे स्विच करें? तो बस अपने हैश मूल्य के लिए डेटा आईडी का मूल्य पढ़ें और यह कूद नहीं होगा।


1

इस समाधान ने मेरे लिए काम किया

// store the currently selected tab in the hash value
    if(history.pushState) {
        window.history.pushState(null, null, '#' + id);
    }
    else {
        window.location.hash = id;
    }

// on load of the page: switch to the currently selected tab
var hash = window.location.hash;
$('#myTab a[href="' + hash + '"]').tab('show');

और मेरा पूरा js कोड है

$('#myTab a').click(function(e) {
  e.preventDefault();
  $(this).tab('show');
});

// store the currently selected tab in the hash value
$("ul.nav-tabs > li > a").on("shown.bs.tab", function(e) {
  var id = $(e.target).attr("href").substr(1);
    if(history.pushState) {
        window.history.pushState(null, null, '#' + id);
    }
    else {
        window.location.hash = id;
    }
   // window.location.hash = '#!' + id;
});

// on load of the page: switch to the currently selected tab
var hash = window.location.hash;
// console.log(hash);
$('#myTab a[href="' + hash + '"]').tab('show');

0

लार्वा फ्रेमवर्क का उपयोग करते समय, मेरे पास एक रूट-> बैक () फ़ंक्शन का उपयोग करने के साथ कुछ मुद्दे थे क्योंकि इसने मेरे हैश को मिटा दिया था। अपने हैश रखने के लिए, मैंने एक साधारण कार्य बनाया:

$(function() {   
    if (localStorage.getItem("hash")    ){
     location.hash = localStorage.getItem("hash");
    }
}); 

और मैंने इसे अपने अन्य जेएस फ़ंक्शन में इस तरह सेट किया:

localStorage.setItem("hash", myvalue);

आप किसी भी तरह से अपने स्थानीय भंडारण मूल्यों को नाम दे सकते हैं; मेरा नाम hash

इसलिए, यदि हैश PAGE1 पर सेट है और फिर आप PAGE2 पर जाएँ; जब आप PAGE2 पर वापस क्लिक करेंगे तो हैश को PAGE1 पर फिर से बनाया जाएगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.