How to override stuff pausing when leaving the page - javascript

I'm not sure if this is allowed, but here goes.
I have a free account on chess.com, so whenever I want more puzzles, I have to watch ads. The ads pause every time I switch to a different window.
The real question I'm asking is how can I make it so it doesn't pause when I switch? I thought it would be simple.
I went into the console and did window.onblur = function(){} and document.body.onblur = function(){} but nothing changed.
Sorry, and thanks in advance.

You would probably only be able to do this in a scenario where the nullifying code runs before the site code. In other words, the code would probably need to be running inside a browser extension, and not in the browser console.
Probably it uses addEventListener. In a browser extension scenario you could run this to nullify the event listener. Crucially, extensions allow code to execute before the main site code, which would be needed here because you need to nerf addEventListener before the site attempts to execute it:
let oldAddEventListener = window.addEventListener
window.addEventListener = (...args) => {
if (args[0] === 'blur') return
oldAddEventListener(...args)
}
If it uses addEventListener (it probably does), then it might seem obvious to attempt to call removeEventListener as theoretically you could then do it in a normal browser console after it was registered. But that's difficult because you need the handler to remove it, and you won't have it in scope. So that prevents you from doing it after the fact it was registered.
Is there a way around this? Possibly. You could probably use window.fetch to get the page contents, modify it with the code, and pull it back into the DOM all over again. But that's extraordinarily involved and smells of "wrong tool for the job".
To be honest you could probably use cheap OS-level tricks to keep the window in top and in focus as you go about your business elsewhere.
I briefly also considered registering a new blur event on the window with capture set to true, but apparently this doesn't work on window events :(.
You probably don't want the burden of building your whole own extension but in chrome you could use TamperMonkey with a script. See this.

Related

Who makes Ajax call, web browser or JavaScript interpreter?

Need to understanding more about how the HTTP requests will get submitted using Ajax.
Definition of AJAX
AJAX stands for Asynchronous JavaScript and XML. In a nutshell, it is the use of the XMLHttpRequest object to communicate with server-side scripts. It can send as well as receive information in a variety of formats, including JSON, XML, HTML, and even text files. AJAX’s most appealing characteristic, however, is its "asynchronous" nature, which means it can do all of this without having to refresh the page. This lets you update portions of a page based upon user events.
XMLHttpRequest is object provided by Browser for AJAX.
AJAX is a JavaScript (set of) library(s) that is included in your application and executed by the interpreter of the browser.
JavaScript is usually considered to have a single thread of execution visible to scripts(*), so that when your inline script, event listener or timeout is entered, you remain completely in control until you return from the end of your block or function.
(*: ignoring the question of whether browsers really implement their JS engines using one OS-thread, or whether other limited threads-of-execution are introduced by WebWorkers.)
However, in reality this isn't quite true, in sneaky nasty ways.
The most common case is immediate events. Browsers will fire these right away when your code does something to cause them:
<textarea id="log" rows="20" cols="40"></textarea>
<input id="inp">
<script type="text/javascript">
var l= document.getElementById('log');
var i= document.getElementById('inp');
i.onblur= function() {
l.value+= 'blur\n';
};
setTimeout(function() {
l.value+= 'log in\n';
l.focus();
l.value+= 'log out\n';
}, 100);
i.focus();
</script>
Results in log in, blur, log out on all except IE. These events don't just fire because you called focus() directly, they could happen because you called alert(), or opened a pop-up window, or anything else that moves the focus.
This can also result in other events. For example add an i.onchange listener and type something in the input before the focus() call unfocuses it, and the log order is log in, change, blur, log out, except in Opera where it's log in, blur, log out, change and IE where it's (even less explicably) log in, change, log out, blur.
Similarly calling click() on an element that provides it calls the onclick handler immediately in all browsers (at least this is consistent!).
(I'm using the direct on... event handler properties here, but the same happens with addEventListener and attachEvent.)
There's also a bunch of circumstances in which events can fire whilst your code is threaded in, despite you having done nothing to provoke it. An example:
<textarea id="log" rows="20" cols="40"></textarea>
<button id="act">alert</button>
<script type="text/javascript">
var l= document.getElementById('log');
document.getElementById('act').onclick= function() {
l.value+= 'alert in\n';
alert('alert!');
l.value+= 'alert out\n';
};
window.onresize= function() {
l.value+= 'resize\n';
};
Hit alert and you'll get a modal dialogue box. No more script executes until you dismiss that dialogue, yes? Nope. Resize the main window and you will get alert in, resize, alert out in the textarea.
You might think it's impossible to resize a window whilst a modal dialogue box is up, but not so: in Linux, you can resize the window as much as you like; on Windows it's not so easy, but you can do it by changing the screen resolution from a larger to a smaller one where the window doesn't fit, causing it to get resized.
You might think, well, it's only resize (and probably a few more like scroll) that can fire when the user doesn't have active interaction with the browser because script is threaded. And for single windows you might be right. But that all goes to pot as soon as you're doing cross-window scripting. For all browsers other than Safari, which blocks all windows/tabs/frames when any one of them is busy, you can interact with a document from the code of another document, running in a separate thread of execution and causing any related event handlers to fire.
Places where events that you can cause to be generated can be raised whilst script is still threaded:
when the modal popups (alert, confirm, prompt) are open, in all browsers but Opera;
during showModalDialog on browsers that support it;
the “A script on this page may be busy...” dialogue box, even if you choose to let the script continue to run, allows events like resize and blur to fire and be handled even whilst the script is in the middle of a busy-loop, except in Opera.
a while ago for me, in IE with the Sun Java Plugin, calling any method on an applet could allow events to fire and script to be re-entered. This was always a timing-sensitive bug, and it's possible Sun have fixed it since (I certainly hope so).
probably more. It's been a while since I tested this and browsers have gained complexity since.
In summary, JavaScript appears to most users, most of the time, to have a strict event-driven single thread of execution. In reality, it has no such thing. It is not clear how much of this is simply a bug and how much deliberate design, but if you're writing complex applications, especially cross-window/frame-scripting ones, there is every chance it could bite you — and in intermittent, hard-to-debug ways.
If the worst comes to the worst, you can solve concurrency problems by indirecting all event responses. When an event comes in, drop it in a queue and deal with the queue in order later, in a setInterval function. If you are writing a framework that you intend to be used by complex applications, doing this could be a good move. postMessage will also hopefully soothe the pain of cross-document scripting in the future.
Answer is From this link:
Is JavaScript guaranteed to be single-threaded?

How can I debug "Back Navigation Caching" in IE?

I'm seeing an odd bug in IE that I'm not seeing in Chrome. Specifically, this involves some JS code not firing when a (Telerik) wizard is navigated back to it's first step.
When the user clicks their "Previous" button, some data isn't being properly loaded. Hitting F12 and bringing up the developer console has shown me the following Warning:
DOM7011: The code on this page disabled back and forward caching. For more information, see: http://go.microsoft.com/fwlink/?LinkID=291337
Ok, so I go to the link provided and I noticed the documentation states:
In order to be cached, webpages must meet these conditions:
...
- The F12 Developer tools window isn't open
This is a problem, because when I use the navigation buttons within my wizard WHILE the dev window is open, it behaves properly, just as it does in Chrome.
How can I debug my related Javascript so I can figure out what's going on? Also, I understand what caching is but I'm not exactly sure what this is about and I have no idea why Chrome behaves differently. Is there a way that I can force IE to behave like chrome and cut on (or off) whatever features that are causing this issue?
Yuck. Back to old school debugging for you.
Short of putting the whole browser into a Windows debugger, you can pretty much forget about setting breakpoints. All you can do is log.
If you are lucky and your problem isn't too deep, you can use a sprinkling of simple alert() statements to let you know the state of things at various stages in your code. One nice thing is that you can serialize objects now pretty nicely; for example, you can do JSON.stringify(this), which will probably give you a giant output, which you can copy and paste into your IDE and unpack. A major upside to doing this is that the alert will block, so you can take your time studying the output. A major downside to this is that race conditions are now much more likely.
Alternatively, you can add a <textarea> to the page and throw your JSON.stringify(this) results into that. Because this means extra DOM mutations, it also increases the odds of race conditions, but not by much. (If race conditions are a possibility, you can do this:
(function () {
var currentState = JSON.stringify(this);
setTimeout(function () {
document.querySelector('textarea').value = currentState;
}, 1000);
})()
Even though these are now asynchronous, if you use this multiple times in sequence, these will execute in that same sequence (unless you change the timeout period).
If you are doing actual page navigations (and not just changing the URL with pushState()), then actually reading those logs is going to be a problem. The solution is to put the page in a frame and write the content out to a sibling frame. As long as both frames are running on the same domain, you will have no problem pushing the data into the sibling frame. If you can't put them on the same domain, you are kind of screwed.

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;
});
});

DOMNodeInserted or hashchange

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/

Jquery Effect Onunload

I would like to use the jquery slideUp effect when the user navigates away from the page just to make the page look cool as it closes.
I assume that I should use the onunload event but how can I delay the page closing long enough for the effect to run to completion.
One of the options that came to mind is effectively hijacking the page closing function, storing it in some variable and then executing it once I had run my effect but I have no idea how I would do that.
Any suggestions or alternative ideas are more than welcome
what you're looking for is the onbeforeunload event.
just a warning though... it should be really quick... or your visitors are probably going to hate it no matter how cool it looks
as to preventing the page from navigating away before the animation is done, that's a bigger problem... any animation is going to rely on setTimeout/setInterval and the page won't wait for those to complete before leaving.
Doing anything but closing the window when the users ask to is breaking a contract with the user. The browser window is not yours, it's the users, and no matter how cool the effect, it will inevitably annoy most of your users.
The onbeforeunload event is very restricted in what it can do. It must return a string, which is then used to prompt the user for a confirmation about leaving the page. It won't work for cool animations.
As far as I know, the only way to stop a user from leaving a page is the onbeforeunload event, which isn't cancelable. Instead, you return a string from that method, the browser prompts the user with a Yes/No dialog, life goes on. 276660 has more info about this.
I don't think you're going to have much luck with this one.
why not, instead of making a "cool" effect when a user simple want to go away from your website (even if the user closes the browser/tab the unload event will be fired) and annoying the simple user with that ... preventing him/her to return again...
...do that "cool" effect when a user reaches your website for the first time? as a normal intro effect?
I did that as a simple idea, you can see it here: http://www.balexandre.com/jmfc
I would agree 100% with Jonathan Fingland's answer, and add this.
In IE, (I'm not sure what versions support this, I know IE6 did) you can use some propriety meta tags to achieve fades etc when leaving the page. However, this is limited in browsers (IE only), so you're stuck for cross browser use.
You may find loading new content via AJAX would give you better control of effects and transitions, as well as reducing the annoyance factor to the user which can result from trying to hijack the browser actions in such a manner.
I would look at using a form of slider as mentioned above (see for instance http://webdesignledger.com/tutorials/13-super-useful-jquery-content-slider-scripts-and-tutorials),
or simply loading content panes in response to user clicks.
The only way I've found for delaying the window to close, is using an alert. If this is an acceptable compromise for your case, it will really delay the window destruction in memory, and allow your page timers to execute (of course, if user does not close the alert popup earlier than your animations finalize).
I recently used this approach so i could call a flex method through FABridge (which would otherwise be destroyed before the flex method call finishes). I'd like to hear your comments on this.

Categories

Resources