DOMNodeInserted or hashchange - javascript

I am trying to write a JavaScript script that is "overlayed" on top of a Facebook page. It uses DOMContentLoaded to detect when content is loaded, then adds some extra stuff in. However, because Facebook doesn't actually "reload" the page when going to a new page (it just uses AJAX), the DOMContentLoaded handler doesn't run again, even though there is new stuff to look through.
Anyway, to detect the change, I thought about using onhashchange since Facebook used to change the page's hash, but in Firefox 4 (I need to support Firefox 3 and later with this, but no other browsers), Facebook doesn't change the hash anymore and in pre-Firefox 3.6 there is no onhashchange.
I thought about using DOMNodeInserted, but would that really slow down the page? (I really can't have any slowdowns in this script.)

you might want to monitor the windows.history object, see the following answer, on how facebook uses it to update pages:
"Redirect" page without refresh (Facebook photos style)

For lightweight pages it generally doesn't have noticable effect. However, on bulky pages (I tried this on gmail) it makes that really really slow that I cannot even compose a message smoothly. And that event was added to a very simple span element which just had a single link in that. The events like DOMNodeInserted and DOMSubTreeModified are real show stoppers.
UPDATE: For all those trying to find an answer to this, note that these methods DOMNodeInserted (or DOMSubtreeModified) really had performance problems, so according to new ECMA specs it is a much faster listener : MutationObserver for doing the same thing (and more).
https://hacks.mozilla.org/2012/05/dom-mutationobserver-reacting-to-dom-changes-without-killing-browser-performance/

Related

Alternative to DOMSubTreeModified event in JavaScript

I am developing a custom translation extension for GMail in chrome and need to trigger the content script when the user clicks on an email in his inbox.
Since GMail uses AJAX, I decided to use the DOMSubTreeModified event. My extension works, but it seems via console logging that the function that sits the translate keeps getting executed constantly, even though the email text remains the same.
DOMContentLoaded does not trigger. Can anyone suggest any alternative I can use? I guess a timer or something in GMail constantly updates the page and makes minor adjustments. I had even narrowed the element on which the event is generated.
It appears that you should be using gmail-specific events to know when a new email is loaded, not generic DOM events. This add-on is not official Google code, but if you look at how it works, you could probably discover how to observe all sorts of gmail events or you could just use it to solve your problems.

window.open affect web page

I have a link that opens a new window using window.open. The pop up works fine, however the normal web page stops loading objects (images, scripts, ajax scripts) and sometimes the page doesn't load at all.
Here is my code:
MyWindow=window.open('player.php','Player','width=500','height=300'); return false;
Is there anything I am doing wrong?
Thanks,
Peter
First of all, please be more specific: tell us more about your browser and which version, and possible your OS. It could be more related to the browser than to the web content.
Then on to the possible problem; you start with saying "I have a link that ...".
To me that sound like you use <a href="javascript:DoSomething()">. Or perhaps <a href="#" onclick="DoSomething()">.
I tried both in some modern browsers: Chrome v37, IE v11. Both browsers did not produce what you describe:
- Chrome v37 will happily keep on loading, even if I immediately click a "window.open()"-link on top of a (huge) webpage;
- IE v11 will someshow show "false", which is strange, but still not what you got.
In some cases I also got to deal with the popup blocker.
A general tip might be to NOT USE <a href> for things like this. Behaviour seems inconsistent across browsers, also these days there are better alternatives, such as <span onclick="">...</span> and <button onclick="">...<button> or by using JQuery or other frameworks (which I do not know much about).
Although this many not be a conclusive answer, maybe this can help you experiment on your own, and think about possible causes or alternative ways of doing things.
The behaviour you describe should definitely NOT normally happen. This is confirmed by robbmj's JSFiddle, that fails to reproduce the problem. That's evidence that something is going on in the main page that is not plain vanilla page loading, or your "link opening" has something unusual to it. Apart from the syntax error (you use four parameters, not three).
Since you do not supply information on either of these points (how do you load the main page? How do you trigger the popup-opening code?), we do not even know if the problem
might be browser-related; I'd start and try to test things in IE, Chrome and Mozilla to see
whether anything changes; this might provide some useful insights.
One possibility
A very strong possibility is that your inadvertent fourth parameter goes into the window.open() "replace" parameter, which is a boolean, and triggers undefined behaviour or simply an error that stops everything. You should have things somewhat working in IE and not working at all in Firefox.
You should also be able to see whether this is the case by using Firefox and the Firebug extension, or the Web Developer Console in Chrome.
Another possibility
A more esoteric possibility is that the way you define the link might make the browser believe you've actually moved on to another page, so that there's no point in continuing loading the current page. Depending on the browser, this might have to do with how the link is defined and could be remedied by defining it some other way.
For example it could conceivably happen if you had
...
which I suspect is what led user Tomzan to ask, "is the link something like javascript:...?"
So if this is the case, try with this instead (this works for me in IE9/Chrome/FF):
link
function openPopup() {
MyWindow = window.open('player.php', 'Player', 'width=500, height=300');
// Also try the following. You won't probably like the results (it should send the
// popup window behind), but if it works, it proves we're dealing with a browser
// issue there.
// Blur and refocus
// MyWindow.blur();
// window.focus();
// Just focus
// window.focus();
return false;
}
Workaround
A possibly acceptable workaround could be to disable the link altogether (or hide it via CSS), and only reactivate/show it upon main document being ready. This sidesteps the problem, even if user experience could be somewhat worse due to a longer wait.
But if it's so likely that a user clicks on the link before waiting for the whole page to load, I'd also consider not automatically loading the rest of the page at all, and reorganize information to provide a more streamlined navigation. Or maybe distribute it on two sequential pages. Again, unfortunately you did not supply enough information to do more than guess.
As you probably know, JavaScript is single threaded. Every event is queued until there is idle time for it to be executed.
In the case of window.open, both windows must share a single context to keep it thread-safe because the opened window can access to it's parent using window.opener.
I don't know how browsers implements it, but we can guess two possibilities:
Idle time is shared between the two windows. It means if the popup does many blocking statements, it can freeze the main window's events.
Only one of the two windows can be active, which depends on which one has the focus. In that case, all events may be paused in the main window when you're using the popup.
If you want a more precise answer, I need more details about your code.
document.addEventListener("DOMContentLoaded", function () {
//whatever the code
MyWindow=window.open('player.php','Player','width=500','height=300'); return false;
}, false);
Try to wrap the code in SetTimeout
setTimeout(function () {
window.open( .. )
}, 0);
Your document should be loaded first, then popup should be open, So write your javascript code in the scope of $(document).ready().
enter code here
$(document).ready(function(){
$("#clickme").click(function(e){
MyWindow=window.open('player.php','Player','width=500','height=300'); return false;
});
});

jQuery / Javascript event to detect page change cancellation

A bit of a curve ball request that might well not have a solution, but worth asking...
We have a heavy AJAX-based website and we rely on modal/loading screens fairly heavily to indicate when something important is happening. All works well.
We also have some operations that trigger full page changes which can take a couple seconds. I'd like to impose the same modal/loading screen when those changes kick off, however- if a user cancels the page load I'd like to detect it and take the loading modal down. Else it'd just sit there forever.
I can watch for the Escape key being used but is there a way to detect the cancellation in a more generic way that'd also work when initiated by the browser's cancel controls?
Thanks
P.S. To be clear, I'm talking normal page changes in this case. Mentioning the AJAX used elsewhere was just to explain why I want the loading screen now; for consistency. Otherwise I think we'd all agree it's abnormal to have loading screens just to navigate around a site.
RESULT
Evidently not possible.
As niklas found:
But now I see what you're tying to do and i found this https://stackoverflow.com/a/1776490/3877639. I don't like your odds I'm afraid.
Started answering, then I saw Carlos answer and thought I might have misinterpret your question. I'll leave my first answer in the bottom, just in case it might be of some use to you either way.
You wish to detect the page load being canceled. But if the page load is canceled, won't the ajax call fail? Couldn't you listen for that some how and then take down the modal/loading screen?
Don't know if you use jQuery's .ajax(), but then it's easy doing stuff if there's any errors.
What you are looking for is the onunload event. However, the browser support is not so good (as you can see in the link).
There's also the onbeforeunload event that has better browser support, but it triggers a browser dialog you can't override. Just send a text to. Then the user can choose to stay on the page or leave it/close it.
Basically you can abort the XMLHttpRequest the ajax call returns with jQuery.
See this

Debugging Jquery on page load only

Okay so I'm familiar with a few techniques for debugging events attached to elements. Events like click, mousedown, focus, etc.
Those are easy, but what I am trying to do is log the sequence of events triggered by jquery plugins (like sliders, form plugins, etc) when the document loads. There is some native markup what gets mutated when the page loads and new elements are introduced and some old ones changed or deleted.
Now I tried chrome tools and firefox and setting breakpoints to break on subtree modification on certain elements I'm sure are being changed but that only works after the page is finished loading.
What method would you guys suggest for debugging this kind of situation?
There is no code involved, its just an abstract, general situation.
After the page has finished loading, click on the "pause" button in Chrome Developer Tools, refresh the page, and it will pause right away -- you would be able to step through until the point you want prior to load. Make sure JQuery file, plugins, etc. are on the Development, unminified versions for this to work.

Make back button clics / hash changes fire an event

I've made a single-page web presentation that changes it's content based on user events like clics, previous viewed content, source refers...
During usability tests I've detected that some users tend to use the back button and that leads them to the previous page, which is not what they want. They want to go back to the previous content.
As we are in the final stages of the production the easiest for me would be to create an event that fires with clics in the back button. The second easiest way would be to detect changes in the window.location.hash and fire an event.
I don't know how to do either.
It is necessary that this feature works in IE8+ FF4 and it's not that important on older browsers, as long as it doesn't compromise other features already implemented.
The page uses jQuery.
Use this http://benalman.com/projects/jquery-hashchange-plugin/ or http://benalman.com/projects/jquery-bbq-plugin/ this.

Categories

Resources