I am trying to get some information from innerHTML from Youtube source page.
However, when I do this
var myStr = document.getElementById('player').innerHTML;
alert(myStr);
this only procs the alert if I visit the same Youtube page twice. If I navigate to a different video, no alert shows up, unless I refresh the page again.
I am also doing this:
if(document.readyState === 'loading') {
document.addEventListener("load", searchSomething, false);
} else {
searchSomething();
}
at the beginning of the Javscript just to make sure that I am getting the innerHTML after the whole page loads. What is the problem here? How do I fix this so that I do not have to refresh the page to proc the alert!
UPDATE ----------------------
I started to log every event that gets fired on Youtube.
However, Youtube does not fire any events including "load", "unload", "hashchange". It only fires Javascript events if you refresh the page!!!
How can this be possible?
If you use jquery it will be like this
$(document).ready(function() {
var myStr = document.getElementById('player').innerHTML;
alert(myStr);
}
Related
I have this code I want to execute everytime I watch a youtube video:
alert("Test alert");
var title = $(".style-scope ytd-video-primary-info-renderer").textContent.toUpperCase();
var blackword = "fortnite".toUpperCase();
if (title.includes(blackword)) {
alert("Video contains fortnite!");
window.location.href = "https://www.youtube.com";
}
When I visit www.youtube.com I get the test alert and nothing else happens which is fine because the script should execute only when the youtube title contains the word 'fortnite'.
I have two problems;
when I click on the video, even the test alert doesn't execute. But if I refresh the video window (with the URL something like https://www.youtube.com/watch?v=XYZ), test alert shows up, but other script doesn't execute. (When I input it manually in the console, it works..)
Does anybody seem to know what is the problem?
I am using chrome extension Custom Javascript.
I'm writing a Chrome extension that provides a content script to any page on GitHub (i.e. any URL matching https://github.com/*).
I'm simply trying to log something to the console each time a page on GitHub loads, like so:
window.onload = function() {
console.log("LOAD");
};
This listener function is executed the very first time a GitHub page is loaded, but if the user navigates to other pages on GitHub from there (by clicking on links or through other means), it doesn't fire. Why? :(
Steps to reproduce:
Open any repository's page on GitHub (example). You should see the message logged to the console.
Click on any link on that page. When the new page is loaded, no message is logged. :(
How do I solve this?
It seems that GitHub uses AJAX (along with history.pushState) to load some parts of the site, so onload will fire only when the page truly loads, but not when content is loaded via AJAX.
Since GitHub uses pushState to change the URL when AJAX content is done loading, you can detect when that happens, and execute your code.
There isn't actually a native event right now that fires when pushState is used, but there's this little hack:
(function(history){
var pushState = history.pushState;
history.pushState = function(state) {
if (typeof history.onpushstate == "function") {
history.onpushstate({state: state});
}
return pushState.apply(history, arguments);
}
})(window.history);
So, run that, and then, instead of window.onload, you can do:
history.onpushstate = function () {
console.log("LOAD");
};
Not ALL of GitHub page's load this way (AJAX + pushState), so you'd have to use both, window.onload and history.onpushstate.
Also, you should use window.addEventListener('load', fn); instead of window.onload, since you don't know if GitHub's code could be overwriting window.onload.
I just updated to chrome version 32.0.1700.76 m and I am now noticing that hashchange seem to act weird. sometimes it work, sometimes it doesn't.
I have the following code on my homepage and I haven't changed the code in a few months. worked fine a few days ago(before I updated to latest chrome version):
$(window).on('hashchange', function () {
var page = location.hash.slice(1);
$('[data-page]').addClass('hidden');
$('[data-page=' + page + ']').css('z-index', '0');
$('#1st-row').children().eq(0).css('z-index', '1');
$('#1st-row').children().eq(1).css('margin-left', '-200px');
$('[data-page=' + page + ']').removeClass('hidden');
$('#1st-row').children().eq(1).animate(
{ 'margin-left':'0px' }, 1000);
$(':checkbox').checkbox('check');
$('#debug').attr('value', 'true');
});
I figured something wasn't working as it should when I redesigned my site so i changed it a bit:
$(window).on('hashchange', function () {
var page = location.hash.slice(1);
$('[data-page=' + page + ']').slideDown();
});
but it's still not working.
I have to reload the page several times, go to the site again(ctrl+l -> enter), reload a few more times and then it magically works. it won't work a second time though... I have to refresh and reload the page/site a few more times before it decides to let hashchange work.
you can test it at lingonsorbet.se.
just add #advanced to the url and a box should appear to the right. works fine in firefox and ie.
am I doing something wrong or has anyone else run into this too?
hashchange is not fired on page load
The hashchange event is only triggered when you manually change the hash or when you click an in-page anchor link (Advanced). Reloading a page without changing the hash does not trigger hashchange.
You should refactor your hash-checking code into a new function and execute it
on the hashchange event
on page load.
Consider this code:
function changeLayoutByHash() {
var page = location.hash.slice(1);
$('[data-page=' + page + ']').slideDown();
// etc.
}
$(window).bind('hashchange', changeLayoutByHash );
$(window).ready( changeLayoutByHash );
As per your question, I don't see inconsistencies in the way Chrome handles this.
If you keep reloading example.com#advanced, hashchange will not be fired. Only when you change the hash to example.com#advance (delete a character), it's registered as a changed hash.
Debugging
To find out whether or not certain events are being fired, you can always write a little console.log('hashchange fired'); into your event handlers and then (with ChromeDev Tools open) see in the console what your program does.
Got an issue with safari loading old youtube videos when back button is clicked. I have tried adding onunload="" (mentioned here Preventing cache on back-button in Safari 5) to the body tag but it doesn't work in this case.
Is there any way to prevent safari loading from cache on a certain page?
Your problem is caused by back-forward cache. It is supposed to save complete state of page when user navigates away. When user navigates back with back button page can be loaded from cache very quickly. This is different from normal cache which only caches HTML code.
When page is loaded for bfcache onload event wont be triggered. Instead you can check the persisted property of the onpageshow event. It is set to false on initial page load. When page is loaded from bfcache it is set to true.
Kludgish solution is to force a reload when page is loaded from bfcache.
window.onpageshow = function(event) {
if (event.persisted) {
window.location.reload()
}
};
If you are using jQuery then do:
$(window).bind("pageshow", function(event) {
if (event.originalEvent.persisted) {
window.location.reload()
}
});
All of those answer are a bit of the hack. In modern browsers (safari) only on onpageshow solution work,
window.onpageshow = function (event) {
if (event.persisted) {
window.location.reload();
}
};
but on slow devices sometimes you will see for a split second previous cached view before it will be reloaded. Proper way to deal with this problem is to set properly Cache-Control on the server response to one bellow
'Cache-Control', 'no-cache, max-age=0, must-revalidate, no-store'
Yes the Safari browser does not handle back/foreward button cache the same like Firefox and Chrome does. Specially iframes like vimeo or youtube videos are cached hardly although there is a new iframe.src.
I found three ways to handle this. Choose the best for your case.
Solutions tested on Firefox 53 and Safari 10.1
1. Detect if user is using the back/foreward button, then reload whole page or reload only the cached iframes by replacing the src
if (!!window.performance && window.performance.navigation.type === 2) {
// value 2 means "The page was accessed by navigating into the history"
console.log('Reloading');
//window.location.reload(); // reload whole page
$('iframe').attr('src', function (i, val) { return val; }); // reload only iframes
}
2. reload whole page if page is cached
window.onpageshow = function (event) {
if (event.persisted) {
window.location.reload();
}
};
3. remove the page from history so users can't visit the page again by back/forward buttons
$(function () {
//replace() does not keep the originating page in the session history,
document.location.replace("/Exercises#nocache"); // clear the last entry in the history and redirect to new url
});
You can use an anchor, and watch the value of the document's location href;
Start off with http://acme.co/, append something to the location, like '#b';
So, now your URL is http://acme.co/#b, when a person hits the back button, it goes back to http://acme.co, and the interval check function sees the lack of the hash tag we set, clears the interval, and loads the referring URL with a time-stamp appended to it.
There are some side-effects, but I'll leave you to figure those out ;)
<script>
document.location.hash = "#b";
var referrer = document.referrer;
// setup an interval to watch for the removal of the hash tag
var hashcheck = setInterval(function(){
if(document.location.hash!="#b") {
// clear the interval
clearInterval(hashCheck);
var ticks = new Date().getTime();
// load the referring page with a timestamp at the end to avoid caching
document.location.href.replace(referrer+'?'+ticks);
}
},100);
</script>
This is untested but it should work with minimal tweaking.
The behavior is related to Safari's Back/Forward cache. You can learn about it on the relevant Apple documentation: http://web.archive.org/web/20070612072521/http://developer.apple.com/internet/safari/faq.html#anchor5
Apple's own fix suggestion is to add an empty iframe on your page:
<iframe style="height:0px;width:0px;visibility:hidden" src="about:blank">
this frame prevents back forward cache
</iframe>
(The previous accepted answer seems valid too, just wanted to chip in documentation and another potential fix)
I had the same issue with using 3 different anchor links to the next page. When coming back from the next page and choosing a different anchor the link did not change.
so I had
House 1
View House 2
View House 3
Changed to
House 1
View House 2
View House 3
Also used for safety:
// Javascript
window.onpageshow = function(event) {
if (event.persisted) {
window.location.reload()
}
};
// JQuery
$(window).bind("pageshow", function(event) {
if (event.originalEvent.persisted) {
window.location.reload()
}
});
None of the solutions found online to unload, reload and reload(true) singularily didn't work. Hope this helps someone with the same situation.
First of all insert field in your code:
<input id="reloadValue" type="hidden" name="reloadValue" value="" />
then run jQuery:
jQuery(document).ready(function()
{
var d = new Date();
d = d.getTime();
if (jQuery('#reloadValue').val().length == 0)
{
jQuery('#reloadValue').val(d);
jQuery('body').show();
}
else
{
jQuery('#reloadValue').val('');
location.reload();
}
});
There are many ways to disable the bfcache. The easiest one is to set an 'unload' handler. I think it was a huge mistake to make 'unload' and 'beforeunload' handlers disable the bfcache, but that's what they did (if you want to have one of those handlers and still make the bfcache work, you can remove the beforeunload handler inside the beforeunload handler).
window.addEventListener('unload', function() {})
Read more here:
https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/1.5/Using_Firefox_1.5_caching
When I use the back button on Firefox to reach a previously visited page, scripts on that page won't run again.
Is there any fix/workaround to have the scripts execute again when viewing the page the second time?
Please note that I have tested the same pages on Google Chrome and Internet Explorer and they work as intended.
Here are the files and the steps I used to test the problem:
(navigate to 0.html, click to get to 1.html, back button)
0.html
<html><body>
<script>
window.onload = function() { alert('window.onload alert'); };
alert('inline alert');
</script>
Click Me!
</body></html>
1.html
<html><body>
<p>Go BACK!</p>
</body></html>
Set an empty function to be called on window.onunload:
window.onunload = function(){};
e.g.
<html><body>
<script type="text/javascript">
window.onload = function() { alert('window.onload alert'); };
window.onunload = function(){};
alert('inline alert');
</script>
Click Me!
</body></html>
Source:
http://www.firefoxanswer.com/firefox/672-firefoxanswer.html (Archived Version)
When I use the back button on Firefox to reach a previously visited page, scripts on that page won't run again.
That's correct and that's a good thing.
When you hit a link in Firefox (and Safari, and Opera), it does not immediately destroy your page to go onto the next one. It keeps the page intact, merely hiding it from view. Should you hit the back button, it will then bring the old page back into view, without having to load the document again; this is much faster, resulting in smoother back/forward page transitions for the user.
This feature is called the bfcache.
Any content you added to the page during the user's previous load and use of it will still be there. Any event handlers you attached to page elements will still be attached. Any timeouts/intervals you set will still be active. So there's rarely any reason you need to know that you have been hidden and re-shown. It would be wrong to call onload or inline script code again, because any binding and content generation you did in that function would be executing a second time over the same content, with potentially disastrous results. (eg. document.write in inline script would totally destroy the page.)
The reason writing to window.onunload has an effect is that the browsers that implement bfcache have decided that — for compatibility with pages that really do need to know when they're being discarded — any page that declares an interest in knowing when onunload occurs will cause the bfcache to be disabled. That page will be loaded fresh when you go back to it, instead of fetched from the bfcache.
So if you set window.onunload= function() {};, what you're actually doing is deliberately breaking the bfcache. This will result in your pages being slow to navigate, and should not be used except as a last resort.
If you do need to know when the user leaves or comes back to your page, without messing up the bfcache, you can trap the onpageshow and onpagehide events instead:
window.onload=window.onpageshow= function() {
alert('Hello!');
};
You can check the persisted property of the pageshow event. It is set to false on initial page load. When page is loaded from cache it is set to true.
window.onpageshow = function(event) {
if (event.persisted) {
alert("From bfcache");
}
};
For some reason jQuery does not have this property in the event. You can find it from original event though.
$(window).bind("pageshow", function(event) {
if (event.originalEvent.persisted) {
alert("From bfcache");
}
});
In my case window.onunload with an empty function didn't help (I tried to set a value for dropdown when user uses backwards button). And window.onload didn't work for other reason - it was overridden by <body onload="...">.
So I tried this using jQuery and it worked like a charm:
$(window).on('pageshow', function() { alert("I'm happy"); });
Wire in an "onunload" event that does nothing:
<html><body>
<script type="text/javascript">
window.onload = function() { alert('window.onload alert'); };
window.onunload = function(){};
alert('inline alert');
</script>
Click Me!
</body></html>
As far as i know Firefox does not fire onLoad event on back.
It should trigger onFocus instead based from this link here.
A simple way to cause a page to execute JavaScript when the user navigates back to it using browser history is the OnPopState event. We use this to pause and replay the video on our home page (https://fynydd.com).
window.onpopstate = function() {
// Do stuff here...
};
for some cases like ajax operations url change listener can be used
$(window).on('hashchange', function() {
....
});