Is there a way to respond to the back button being hit (or backspace being pressed) in javascript when only the location hash changes? That is to say when the browser is not communicating with the server or reloading the page.
Use the hashchange event:
window.addEventListener("hashchange", function(e) {
// ...
})
If you need to support older browsers, check out the hashChange Event section in Modernizr's HTML5 Cross Browser Polyfills wiki page.
I did a fun hack to solve this issue to my satisfaction. I've got an AJAX site that loads content dynamically, then modifies the window.location.hash, and I had code to run upon $(document).ready() to parse the hash and load the appropriate section. The thing is that I was perfectly happy with my section loading code for navigation, but wanted to add a way to intercept the browser back and forward buttons, which change the window location, but not interfere with my current page loading routines where I manipulate the window.location, and polling the window.location at constant intervals was out of the question.
What I ended up doing was creating an object as such:
var pageload = {
ignorehashchange: false,
loadUrl: function(){
if (pageload.ignorehashchange == false){
//code to parse window.location.hash and load content
};
}
};
Then, I added a line to my site script to run the pageload.loadUrl function upon the hashchange event, as such:
window.addEventListener("hashchange", pageload.loadUrl, false);
Then, any time I want to modify the window.location.hash without triggering this page loading routine, I simply add the following line before each window.location.hash = line:
pageload.ignorehashchange = true;
and then the following line after each hash modification line:
setTimeout(function(){pageload.ignorehashchange = false;}, 100);
So now my section loading routines are usually running, but if the user hits the 'back' or 'forward' buttons, the new location is parsed and the appropriate section loaded.
Check out history.js. There is a html 5 statechange event and you can listen to it.
onLocationChange may also be useful. Not sure if this is a Mozilla-only thing though, appears that it might be.
Did you took a look at this? http://developer.yahoo.com/yui/history/
Related
I wonder if i've unset($_SESSION['enough']); and want to free it up on closing the page.
[ suppose visitor is viewing page of the website pages in new tab ]
i'm using this code
<script language="javascript">
window.onbeforeunload = function() {
console.log('event');
return false;
}
</script>
i wonder how can i apply to fire this code unset($_SESSION['login_id']); , it might look ridicules but this is the basic idea and i'm gonna give example what can be used for
For example : media website would like members not to watching more than one video in same time so the watching page drop session and free it on closing it so can watch more! js indeed is essential for website using jwplayer so no chance of talking about members with disabled js.
In order to load the killsession.php that runs the unset() command, you can run that page with ajax with async:false
Have a look at
Ajax request with JQuery on page unload
jQuery.ajax({url:"http://localhost/killsession.php", async:false})
You can use jQuery to fire on unload with the unload function (http://api.jquery.com/unload/).
$( window ).unload(function() {
// On the unload, we can fire a request back to the server
// .get(), .post(), and .ajax() may be useful.
});
I need to detect the first time a page loads in jQuery so that I can perform some actions only when the page loads the first time a user navigates to that page. Similar to server side code page.ispostbasck. I have tested $(document).ready and it fires every time the page loads so this will not provide what I need. I have also tried the jQuery Load function - it also fires every page load. So by page load an example is that I have an HTML input tag on the page of type button and it does not fire a postback (like an asp.net button) but it does reload the page and fires $(document).ready
Thanks
You will have to use cookie to store first load information:
if (! $.cookie("cookieName")){
// do your stuff
// set cookie now
$.cookie("cookieName", "firstSet", {"expires" : 7})
}
Note: Above example uses jQuery Cookie plugin.
An event doesn't exist that fires only when the page is loaded for the first time.
You should use jQuery's .ready() event, and then persist the fact that you've handled a first time page load using your method of choice (i.e. cookie, session variable, local storage, etc.).
Note: This method will never be fool proof unless you can store this information at the user level in a DB. Otherwise, as soon as the user clears their cookies, or whatever method you choose, the "first time loaded" code will fire again.
I just ran into this problem and this is how I handled it. Keep track of the first time the page loads by using a variable initialLoad:
var initialLoad = true;
$(document).ready(function() {
...
...
...
initialLoad = false;
});
Then in other functions, you can do this:
if (initialLoad) {
//Do work that is done when the page was first refreshed/loaded.
} else {
//Do work when it's not the initial load.
}
This works well for me. If the user is already on the page and some jQuery functions run, I now know if that user just loaded the page or if they were already on the page.
The easy solution is to use jQuery ‘Once’ plugin
$(element).once('class-name', function() {
// your javascript code
});
So I'd like my page to load content if a window's hash has changed.
Using Mootools, this is pretty easy:
$extend(Element.NativeEvents, {
hashchange: 1
});
and then:
window.addEvent('hashchange', function() {});
However, the hashchange event is firing when the page is being loaded, even though the specification require it not to fire until the page load is complete!
Unless I am loading the page for the first time, with no hash, then all works as expected.
I think the problem here is the fact that the browser considers the page load "complete", and then runs the rest of the JavaScript, which includes hash detection to load the requisite page.
For example, if I typed in http://foo.bar/, all would work fine. However, http://foo.bar/#test would, ideally, load the initial page, detect the hash, and load the "test" content.
Unfortunately, the browser loads the initial page, considers it "domready", and THEN loads the "test" content, which would then fire onHashChange. Oops?
This causes an infinite loop, unless I specifically ask the browser NOT to update the hash if an onHashChange event is firing. That's easy:
var noHashChange;
noHashChange = true;
var hashes = window.location.hash.substr(1).split("/"); // Deciphers the hash, in this case, hashes[0] is "test"
selectContent(hashes[0]); // Here, selectContent would read noHashChange, and wouldn't update the hash
noHashChange = false;
So now, updating the hash AFTER the page has loaded will work properly. Except it still goes nuts on an initial page load and fetches the content about 3 or 4 times, because it keeps detecting the hash has changed. Messy.
I think it may have something to do with how I am setting the hash, but I can't think of a better way to do so except:
window.location.hash = foobar;
... inside of a function that is run whenever new content is selected.
Therein lies the problem, yes? The page is loaded, THEN the content is loaded (if there is content)...
I hope I've been coherent...
Perhaps you could check the hash first to eliminate the recursion:
if(window.location.hash != foobar){ window.location.hash = foobar;}
Why is the onHashChange handler changing the hash anyways? If there's some default that it's selecting first before loading the content, then perhaps that could go in a seperate function.
(I say this because it looks like you've some sort of directory structure-esque convention to your location.hash'es, perhaps you're selecting a specific leaf of a tree when the root is selected or something?)
you could implement an observer for the hash object that will trigger a function when the has object has changed.it does nothing to do with the actual loading of the page.
the best way to do this is via Object.prototype.watch
see other pages on same topic : On - window.location.hash - Change?
have a look at MooTools History it implements the onhashchange if the new html5 history api isn't available, no need to reinvent the wheel :)
I'm trying to make my site respond correctly to the back button. I've saved that hash of what I want it to do, but I don't know the hook for jQuery to be able to tell when the hash changes. It's not .ready(), because the page doesn't reload. What do I use?
Edit for a bit of clarity:
I'm using an iframe, so I can't tell when someone clicks a link. It's on the same subdomain, so i'm able to see it's filepath, and am saving it so you can bookmark. Unfortunately by saving it as a hash, my back button now fails to reload, which fails to reload the iframe, so my back button is essentially broken. If there was a way to tell when the URI changes, I could check it against the iframe address and change it if they don't match.
All I need is a way to check if the URI has changed. Is there a .change() for the URI? Something along those lines?
You can try History Event plugin.
After the document is ready, you examine the hash and alter the page appropriately.
I don't know the hook for jQuery to be able to tell when the hash changes
You can intercept your hash anchors' click events and respond appropriately as opposed to waiting for a "the hash has changed" event (which doesn't exist).
Some approaches create a "the hash has changed" event by inspecting window.location.hash on a timer.
Ben 'the cowboy' Alman wrote a cross platform plugin for hash changes
http://benalman.com/news/2010/07/jquery-hashchange-event-v13/
I dont know if your using it inside of the iframe or what, but if you were to use it outside the iframe it would be like
$(function(){
$(window).hashchange(function(){
//Insert event to be triggered on has change.
changeIframeContent(window.location.hash);
})
})
You should have a look at the solution of Ben Nadel which is in binding events to non-DOM objects.
There is'nt a buitin way to watch for hash changes, in firefox you could use watch method, but as far as I know it isnt default, so you can hack it writing something like (see below)
function setWatchHashChanges(functionObject)
{
if(window.location.watch)
{
window.location.watch('hash', function(e){functionObject(e);return e;});
} else {
if(!setWatchHasnChanges.hash)
{
setWatchHasnChanges.hash = window.locaton.hash;
} else {
setInterval(function(){
if(setWatchHasnChanges.hash!== window.locaton.hash)
{
setWatchHasnChanges.hash = window.locaton.hash;
functionObject(setWatchHasnChanges.hash);
}
}, 100);
}
}
Here is the situation :
If I am in page-1 now I am clicking a link from page-1 to navigate to page-2. Before page-2 is loaded I am hitting escape so that still I am staying in page-1.
At that point I want to track that event.
Is there any JavaScript event so that I can track the above scenario?
More Info :
To avoid concurrent request to the "page-2", when the user clicks a link from page-1 I am redirecting to page-2 and disabling the link (to avoid multiple request to "page-2). At this point when we hit Esc and abort loading page-2, I need to enable the link again in page-1.
I tried using this code:
<html>
<head>
<script>
document.onkeypress = KeyPressed;
function KeyPressed(e)
{
if (!e) e = window.event; //IE Compatibility
alert(e.keyCode);
}
</script>
</head>
<body>
Stack Overflow
</body>
</html>
It detects any key pressed while you're on the page. Once you click on the SO link and hit escape, nothing happens. The browser is already receiving a response from the SO server and is starting to process it, this page has already been "left", despite appearances when you see "Waiting for http://stackoverflow.com" in your browser's status bar.
Your idea of handling this event is plain wrong. Blocking the button is required to make the user unable to do double post data. However, the request is sent instantaneously(!) after the click on the link.
So, if you click the link once, stop the page, then click second time - it will submit it twice, and that is not what is intended to happen.
Two events are triggered when the page unloads.
window.onUnload
window.onBeforeUnload
You can use these events to cancel the unload of the page, however after that, there page is considered done.
What you can do is make the page wait 5 secs or so before going to the new page:
eg:
window.onunload = (function() {
var time = new Date();
var cancel = false;
window.onkeypress = function (e) {
if ((e || window.event).keyCode == 27) cancel = true;
};
while(time > new Date() - 5000) {
if (cancel) return false;
}
});
In fact that may cause some browsers to hang since you're taking up all process time given to the JS script. ie: in the while block.
You could probably avoid that by doing a blocking function call, that isn't so process intensive, like one that is bound by network latency. eg: XMLHttpRequest() etc. I don't think calls that are queued such as setTimeout() will work here, as they don't block.
Since the <a href> tag tells the browser to move to another page, it's up to it to decide if it will still have your script running. If I were it, I wouldn't listen.
If you want to override that, I guess you should tell the browser not to listen to that particular onClick event, and put a callback in place that loads the target page in the background. This assures your page is still active. After the target page has loaded (by your script), you could kindly ask the browser to update itself with the received content.
So that's the theory. I have no idea if the DOM lets you just override the content of a loaded page, but I guess it does.