简体   繁体   中英

Prevent default behavior when setting location.hash

When I do this,

location.hash = "test"

the url is updated and the page homes in on the element with that id.

Is there a way to stop the page from homing in to that element?

Solution

You cannot prevent this behaviour, but you can fool it by temporarily hiding the target, eg. like that (it has nothing to do with jQuery):

// obtain "target" DOM (not jQuery) element and do this:
var original_id = target.id; // save original ID
target.id = null; // set target's ID
location.hash = 'test'; // issue location.hash change
target.id = original_id; // set ID to original value

Generalized solution

Or more general example:

// make target_hash set to a hash you want to not lead you to page section and:
var element = document.getElementById(target_hash); // find element by ID
var original_id = element.id; // save original ID
location.hash = target_hash; // previously defined by you (eg. 'test')
element.id = original_id; // reset ID

Demo / proof

The live example can be as follows, in the event handler attached through jQuery (demo here: http://jsfiddle.net/DaZfH/ ):

some_link.on('click', function(event){
    event.preventDefault();
    var target = document.getElementById('target');
    var original_id = target.id;
    target.id = null; // unset ID
    location.hash = 'target';
    target.id = original_id;
});

Disclaimer

But indeed others are right: moving you to the correct place in the document is the correct behaviour. If you are doing things like I mentioned, then your solution is pretty hakish and there is definitely a better way to do that.

Is there a way to stop the page from homing in to that element

Yes. Although the hashchange event is not cancelable, you can reset its unwanted behavior like this.

 var popY, popX; //When location.hash is changed, popstate is the first event to fire //Use this event to record current state window.addEventListener('popstate', popstateHandler); function popstateHandler() { popY = window.scrollY; popX = window.scrollX; } //Reset scroll position with recorded values when hashchange fires (after page is scrolled) window.addEventListener('hashchange', hashchangeHandler); function hashchangeHandler() { window.scrollTo(popX, popY); }

That's the basis of it. You might want to do some proofing for IE, and implement your reasons for doing this: Animate scroll, active something etc..

Polyfill for scrollY, scrollX:

 if(!('scrollY' in window)) { Object.defineProperty(window, 'scrollY', { get: function () { return window.pageYOffset } }); Object.defineProperty(window, 'scrollX', { get: function () { return window.pageXOffset } }) }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM