I was curious if there was a way to detect the user pressing the "stop navigation" button in the browser using javascript (or, even better, jQuery.) For example, if you click a link for a webpage that takes a while to load, you may want to show a spinning loader. But what if the user cancels navigation to the page? Is there anyway to detect that to get rid of the spinning loader that you put?
EDIT: I did a bit more research, and there seems to be an onStop event in javascript but, wouldn't you know it, it only works in internet explorer. If anyone has any other ideas to implement a cross browser solution like onStop, that'd be wonderful, but if not, I'll answer my own question in a few days to close this.
EDIT 2: https://stackoverflow.com/a/16216193 says it's not possible. As do a few other answers.
Alright so, as promised, I'm going to answer my own question.
I've thought about this quite a bit - and I've come up with a solution. I wasn't able to make it work in code (I didn't try too hard), but it should work in theory.
So I thought about the criteria of deciding when a webpage should decide stop was called. I came up with this:
If the script hasn't died after a reasonable amount of time, it can be assumed navigation has been canceled.
Then a jQuery event can be fired on the body or something like that. But what constitutes "a resonable amount of time?" I figured it would be partially based on page render time (fetching images, etc.) to get an idea of how fast the user's internet is. That can be gotten by doing:
var start = new Date();
var time;
$("body").load(function () {
time = new Date() - start;
...
});
Multiply that by a coefficient (maybe 3 or something) and get an approxamate transfer time. (This would have to be adjusted to account for how long it would take for the server to generate the next page, dependent on how dynamic it is.) Then, using this new found time*3 you'd write something like this:
$("a").click(function() { //Anything that could go to another page should filter through here
setInterval(function() {$(document).trigger("navstopped");},time*3);
}
$(document).on("navstopped") {
//Do stuff now that we assume navigation stopped.
}
Assume. That's really all we're doing here. We may have an inconsistent internet connection, fast one minute, slow the next. Server load could be inconsistent too. Maybe it's serving up images like a ninja for this page, but it's hit with a bunch of requests the next, making it generate/serve the next page a bit slower. So we're just assuming that something interrupted the navigation some how, but we are not certain.
Now, of course, this could be used in conjunction with IE's onStop event, but this was really the only cross browser solution I could think of. I wasn't able to get it to work, but maybe some jQuery god may be able to in the future.
Edit before post: Even before I posted this, I had another idea. More browsers support onAbort. If we have a picture that never loads, and the user presses stop, will onAbort be fired? Even if another webpage is loading? It requires testing but that may work too. I like my first idea better though. Although unstable, it is more stable than this cockamamie idea and I realize this could be bad practice.
i want some code to move the cursor position in an IFrame via Javascript or jquery.
Really it will help me a lot.
Not possible. To answer why that's impossible, imagine:
I include an iframe to some very important business (let's suppose for a moment this business does not have frame-busting code)
When the user reaches my page, it begins manually controlling the cursor's position to highlight the "Delete Account" button, and simulates a click.
User's account is deleted on a completely different site, through none of their input.
Javascript allows you many UI-coding capabilities, but ultimately the user is in control. Even events like the "onpageunload" are very much restricted in what they can do, and browsers will often include 'escape' options even there. Furthermore, even in the instance that you CAN find a way around these chains, it will frustrate and quite possibly even panic many of your users. I try to warn people that any instance in which you're "re-coding the browser" may lead to all sorts of unpredictable issues, and may even prevent handicapped accessibility to your site.
It might help us to know if there's some specific reason you'd like to do this - possibly the solution is not what you think it is. For instance, if you are trying to make an FPS using WebGL, I seem to remember Chrome including some function to allow for mouse control inside of a window (possibly taking a browser confirmation dialog)
You should check out
http://jqueryui.com/draggable/
You "could" put make the content in the iframe draggable, if you host the src for your frame.
If you don't host the src for your Iframe, you "could" put have an inner iframe that is draggable, and an outer iframe that displays the inner frame.
It is a very messy solution, I hope there is something better for you.
I'd like to add an onbeforeunload javascript, asking the user to bookmark the page (there's a small button in the header for that purpose).
The problem is, no matter if they'd like to bookmark it, it's pointless and annoying after running once.
So, what's a generic solution to stop a javascript from running more than once?
Thanks,
Emilia.
EDIT:
Yes, I guess an onload event would be more appropriate?
I don't really want to add "big red buttons"...
Any basic example how a IP validation + script would look like?
I would say it's already a bad idea to use a pop up when the user wants to exit the page even if it is only once, it's annoying and obtrusive. I suggest you place a big button on site itself if you want to call the visitor to an action, bookmarking in this case.
If you still want to though, you should use IP validation and not cookies, cookies are temporal, they can be removed by the user, and visitors will not like to be presented the same suggestion over and over.
Is it possible that the html page loaded, cannot be refreshed or reloaded by the user
Thanks..
No, and you shouldn't try to do this...it breaks all the users expectations of what a webpage does.
Whether it's code or behavior, when you're having trouble doing something, it's usually because it hasn't been done or hasn't been made easy...stop to ask why that is, and often you'll find there's a good reason.
The onbeforeunload event could be used to detect a situation like this.
I think this is what SO uses when you write an answer and then want to leave before you post it; it asks you if you are sure.
Is that what you want to use it for or what?
I run into a common problem when trying to do AJAX development. Where possible, I like to try and just update data in an existing layout, and not the layout itself. For example, take the div below:
<div id="content-5">Here is some content</div>
I would get the updated value for content-5 from the server and just replace the contents of content-5 with the value. This makes a lot of sense for simple data replacements where the value is always going to be displayed in its pure form.
Sometimes the content is more complicated, and I have to actually get more than just raw data... maybe there is some logic to determine how a value is displayed and perhaps the style needs to be different depending on the data inside. In that case, I generally produce the HTML on the server side and inject the HTML into the element instead of just raw data.
Example: A status field from the controller comes back as "complete", but from the design doc, "complete" is supposed to show the user the text "Available" and it needs to be styled in a way different from other statuses.
Doing this in Javascript would require some in-depth view knowledge that the template layer probably already handles. The end result would be the same (code snippet below), but the difference is that there could possibly be some code duplication and a far more complicated Javascript layer.
<div id="content-5"><span class="success">Available</span></div>
Without fail, the requirement comes up that the system will need to handle "new" contents as well. The easiest solution to implement is to just get all of the content's at the same time so that I do not need to handle the extra complexity of injecting a new element instead of just replacing existing content.
So, I create a new template, wrap the contents in another element with an ID, and bulk replace all of the content divs at the same time any time there is a change.
<div id="allContent">
<div id="content-1">Some content A</div>
<div id="content-2">Some content B</div>
<div id="content-3">Some content C</div>
<div id="content-4">Some content D</div>
<div id="content-5">Some content E</div>
</div>
At some point, I have to wonder: Where is the line? At some point it feels like I'll eventually just be replacing the whole page with an AJAX request. Would this really be a problem?
I realize this may be pretty subjective, but what are some good strategies for determining to which level you should be replacing content with AJAX? Replacing just the data seems to be my preferred method when possible as it makes the AJAX controllers very simple. Replacing larger chunks of HTML from a template seems to be the easiest for handling more complicating layout and design issues and also feels like it could be more easily maintained. Are there other options I have not considered?
I expect there will be some discussion about manipulating the DOM programatically, but I personally really dislike this. The code ends up looking pretty horrible and really starts to integrate too much layout and design into the JS layer for my liking. Since I generally work with template libraries of some sort (whether raw PHP, PHP templates like Smarty or JSP in Java) it seems to make more sense to leave as much visual design there as possible.
EDIT
Based on the first few answers, it seems like this is being read as trying to keep the user on the same page but navigating around around the site or otherwise changing the page in a radical way with each update. The question is more about how to determine where the layout work for AJAX calls should happen and whether or not it is an acceptable practice to change large chunks of code with an AJAX request, knowing that replacement code may look nearly identical to what had been there before.
I think the most important requirement is the refresh requirement. If after several AJAX updates I hit refresh, the page I was just looking at should be the page that arrives. If the page reverts to a previous state for any reason then the URL is wrong. If for any reason your AJAX data is going to make the URL in the browser invalid then you should not be using AJAX to fetch that data.
There are exceptions, of course for data the is even newer than the last AJAX request. But that's obviously not what I'm talking about. A live chat screen could receive an update between the last AJAX request and the refresh. No big deal. I'm talking about the logical content and the URL describing it should always be in sync.
Complete personal opinion ex nihil, my rule of thumb is to change no more than 1 "panel" unit or 33% of the page whichever is less.
The basis for this is that the user should be able to clearly recognise the previous page state is related to the new state - how would you feel if you were suddenly teleported into the building to your right? Be gentle with your poor user.
There are also serious technical questions about the benefits of moving and inserting basically a page worth of data, which I think is a bit of an AJAX anti-pattern. What benefit does AJAX provide if you're going to do that?
Your specific question seems dependant on the supposition that the response coming back from your AJAX request isn't "just" data. This feels wrong to me from a separation of concerns point of view: I would expect a page to have all the layout information it requires already, the AJAX response itself to provide nothing more than dumb data/markup, and the JS event handler which created the request to sew the two together, MVC style. In that respect I think, yes, you're doing too much.
(by panel, I mean one logical design element - a menu, a ribbon, an item metadata panel, etc..)
edit: now that I think about it, I think SO's user profile page breaks my rule of thumb with those tab clicks
Depending on whether you want people to be able to to link to / bookmark etc the current page, you might want to navigate the user's browser.
This isn't a concern for some apps like GMail etc, and they won't ever refresh the page.
For myself, I tend to think it's a good practice to navigate the browser when navigating to a logically different place. eg. a person's profile vs. a list of their messages.
Sorry if this is vague, it's rather subjective :-)
A good guideline for something like this is to ask yourself, "Is this dynamic application 'content', or is it content-content?" Your use case sounds like application content that will change with each user. This is probably the best place for Ajax, but with everything, it's always nice not to just have one hammer. You don't want to do too much on one page. For instance, if one part breaks, the entire thing might, thereby frustrating the user.
Anywhere you're looking at actual page content or anything where the information is static, I strongly suggest avoiding the use of JavaScript, as it runs the risk of being invisible to search engines. Make sure anything linking to information like this is crawlable. The first step towards this is dynamic generation on the server side rather than browser side.
If you're using Smarty templates to produce a page, just fragment a template into various meaningful sections - news.tpl, email.tpl, weather.tpl - and have a master.tpl producing the structure of the page and calling child templates.
Then, if you're for example using an AJAX call triggered by a timeout to refresh the news, you can just call the server, cram the necessary data into news.tpl, and return the results into the news div you set up with master.tpl. This way your news layout is always following the pattern of news.tpl. (If you used JavaScript to manipulate formatting bits or set up event handling on document load, you'll need to attach that post-processing to fire after the AJAX call.)
You haven't really gotten specific about the types of things you're trying to replace here, and my initial reaction is that, if a single event is triggering multiple sections of the page to update at once, that's a sign that maybe you should be coallating those sections into a single display.
How much formatting gets done on the server end versus how much gets done on the client end with JavaScript? I'd say server-side formatting if possible, that way you have code that reflects discussions you've made about display layout and logic. Client-side formatting can be used for more interface-based issues - sorting rows in a table and alternating row colors with :odd and :even selectors, showing and hiding divs to create a "tabbed display" without hitting the server since the data won't change just from selecting a new tab, that sort of thing.
Finally, AJAX is one-way. If your web page is a view on a database, this isn't as much of a problem, but using AJAX manipulation to take the place of normal navigation is a terrible idea.
If you were habitually replacing the entire contents of a page using AJAX calls, I would agree that you have a problem. However, it appears to me that you are attempting to carefully think through the implications of your design and attempting, where possible, to avoid what annakata has called this "AJAX anti-pattern."
My rule is a bit simpler: as long as a substantial amount of context (e.g. menu on the left, header, various controls, page title, etc.) remains on a page, I am Ok with replacing almost anything with an AJAX call. That being said, I've never struggled with a page that has as much AJAX-generated code as you are.
I do have one question though: isn't it possible to encode state so that you can just replace some of the Divs in your example rather than all of them? If not, have you thought about doing so?