问题
I want to delay the page-load time for a specific web page - in this case, Google - so that users can't see the web page until a count-down timer has completed.
This question was inspired xkcd, and a similar question is "Javascript page load delay of specific set of pages".
I've tried a modified version of Jonathan's Greasemonkey script (see below), but this script only delays the Google page load the first time Google is used in a particular tab.
If Google is opened in a new tab, or the user follows a link from Google then returns, the script kicks in again. But, if the user doesn't ever navigate away from Google (say, they find the answer they were looking for in the brief abstract under each search result, then just search for something else), they can search without any delay.
Is there a way to force the delay screen to appear after each search (as opposed to after each time the page is visited)? -- preferably using either Greasemonkey or a Chrome plug-in?
Script currently used:
(first sets blocked addresses to a value of "1" and all other addresses to a value of "0," then, if block>0, the script kicks in...)
(function(){
// Note: This doesn't actually stop the page from loading, but hides it, so you know its
// there, waiting; The dopamine of internet candy becomes a torture. Better to clean
// your room or open an irb prompt instead.
window.seconds = 30;
function resetCountDown()
{
seconds = 30;
}
// You can has cybersauce
window.clearDelay = function()
{
document.getElementById('eightSixTwoDelay').style.display = 'none';
}
var overlay = document.createElement('div');
overlay.id = 'eightSixTwoDelay';
overlay.style.backgroundColor = '#000';
overlay.style.color = '#FFF';
overlay.style.fontSize = '56px';
overlay.style.fontFamily = 'Helvetica, Arial, Sans';
overlay.style.fontWeight = 'bold';
overlay.style.textDecoration = 'none';
overlay.style.position = 'absolute';
overlay.style.top = '0px';
overlay.style.left = '0px';
overlay.style.width = '100%';
// clientHeight changes as content loads, and JS, like the PHX Valley Metro system, does not wait for you to run.
overlay.style.height = document.body.clientHeight + 'px'; //'100%';
overlay.style.paddingTop = '10px';
overlay.style.paddingLeft = '10px';
overlay.style.textAlign = 'left';
overlay.style.zIndex = '10000'; // OVER 9000
overlay.addEventListener("click", resetCountDown, true); // THERE IS NO ESCAPE
document.getElementsByTagName('body')[0].appendChild(overlay);
window.displayDelay = function()
{
if (seconds > -1)
{
document.getElementById('eightSixTwoDelay').innerHTML = 'Page ready in ' + seconds + ' seconds.';
seconds -= 1;
setTimeout(window.displayDelay, 1000);
}
else
{
clearDelay();
}
}
window.onload = displayDelay();
})();
}
回答1:
When a new search is entered, Google politely changes the URL, as well as AJAXing-in the new page. So, listen for the hashchange
event to determine when a new search was run.
Some random notes on that script:
- Use
@run-at document-start
so that the blanking starts as soon as possible. - The overlay should be
position: fixed;
. - Avoid setting global or
window.
scope variables, AMAP.
Here is a complete script that blanks the page on each new Google search:
// ==UserScript==
// @name _Delay a page display, a la XKCD
// @namespace _pc
// @match http://*.google.com/*
// @run-at document-start
// ==/UserScript==
/*--- Blank the screen as soon as the DOM is available, and also whenever
the URL (hashtag) changes -- which happens when "new" pages are loaded
via AJAX.
*/
window.addEventListener ("readystatechange", FireWhenReady, true);
window.addEventListener ("hashchange", blankScreenForA_While, true);
function FireWhenReady () {
this.fired = this.fired || false;
if ( document.readyState != "uninitialized"
&& document.readyState != "loading"
&& ! this.fired
) {
this.fired = true;
blankScreenForA_While ();
}
}
function blankScreenForA_While () {
/* Note: This doesn't actually stop the page from loading, but hides it,
so you know its there, waiting; The dopamine of internet candy becomes
a torture.
Better to clean your room or open an irb prompt instead.
*/
//--- Settings:
var pageDelaySeconds = 5;
var overlayID = "gmEightSixTwoDelay"
//--- One-time setup, for each new "page", START:
function resetCountDown () {
blankScreenForA_While.secondsRemaining = pageDelaySeconds;
}
resetCountDown ();
function createOverlay () {
var overlay = document.getElementById (overlayID);
if (overlay) {
overlay.style.display = 'block'; // Un-hide.
return;
}
overlay = document.createElement ('div');
overlay.id = overlayID;
overlay.style.cssText = " \
font: bold 56px Helvetica,Arial,Sans; \
text-decoration: none; \
position: fixed; \
top: 0; \
left: 0; \
width: 100%; \
height: 100%; \
z-index: 10000; /* OVER 9000 */ \
margin: 0; \
overflow: hidden; \
color: pink; \
background: lime; \
line-height: 1.5; \
padding: 1em; \
text-align: center; \
";
//--- Only use innerHTML the one time.
overlay.innerHTML = 'Go do something important!<br>'
+ 'Page ready in <span></span> seconds.'
;
// THERE IS NO ESCAPE.
overlay.addEventListener( "click", resetCountDown, true);
document.body.appendChild (overlay);
}
createOverlay ();
//--- One-time setup, for each new "page", :END
// You can has cybersauce
function clearDelay () {
document.getElementById (overlayID).style.display = 'none';
}
function displayDelay () {
if (blankScreenForA_While.secondsRemaining > -1) {
var displaySpan = document.querySelector (
"#" + overlayID + " span"
);
displaySpan.textContent = blankScreenForA_While.secondsRemaining;
blankScreenForA_While.secondsRemaining--;
setTimeout (displayDelay, 1000);
}
else {
clearDelay ();
}
}
displayDelay ();
}//-- End of: blankScreenForA_While()
来源:https://stackoverflow.com/questions/10776645/run-my-script-on-each-page-load-including-ajax-page-loads