Where does window.location.reload() get its value from? - javascript

Trying reload the current page without the fragment identifier (i.e. hash symbol #) and using the following bit of code to do so which functions correctly:
var path = window.location.href.replace(/(\#.*)/,'');
window.location = path;
I'm also aware that the above second line could read window.location.href = path; which brings me to the next part.
Before arriving at the above code we tried:
var path = window.location.href.replace(/(\#.*)/,'');
window.location.href = path;
window.location.reload();
However that didn't work for us as the href value wasn't seeming to be set and I feel that reload() was calling before or instead of the href = path bit.
This got me curious, where does the reload() function for window.location get its value from to reload the page?
If I click around a page jumping between fragment identifiers (perhaps a table of contents) then the address bar updates accordingly and when called, window.location.reload() will do so with the correct fragment. Yet if I manually type something in the address bar and then call the reload() function it will not load with my manual entry but rather the last 'computer defined' value.
My guess is the user agent (in this particular case Chrome 44) is listening and updating the value which each interaction with the DOM or within the window. I checked out the HTML5 spec and the MDN Location.reload() docs for information and either it wasn't there or I'm too dense to find/understand it.
Can anyone explain to me where reload() gets it's value and how it is updated through a users interaction with a page?
What is the exact difference between using window.location = path and window.location.href = path in this scenario?

The location (value) only changes after a successful navigation! In other words, the location instance represents the currently loaded page (including the fragment).
Assigning a new value to window.location.href (re)loads a page.
So when you call window.location.href = path; the browser wants to load the new URL (the one without the #). But if you immediately call window.location.reload(); it's like saying "No, wait! Reload the current page (the one with the #)".

If you want to remove the "#" part of the url you have to explicitly set:
window.location.hash = ""
and then call window.location.reload().
window.location = path is nothing more than syntactic sugar for window.location.href = path.

Related

How to invoke javascript function when # is present in URL

I am trying to call JavaScript function when # is present in URL. I know normal behavior is to navigate / scroll to the specific tag. But could not find how to invoke a JavaScript function.
The below example is close but not solving my problem.
What is the meaning of # in URL and how can I use that?
You might be able to leverage the hashchange event to trigger the function, assuming you don't just want to keep polling the location to see if it changes.
DOCS: https://developer.mozilla.org/en-US/docs/Web/API/Window/hashchange_event
This code snippet will add the listener to the current page, then manipulate the hash and fire the function, displaying the new hash value. You could call any function here.
window.addEventListener('hashchange', function() {
alert(location.hash);
});
window.location += "#test";
var hash = window.location.hash;
if(hash){
// do something
}
<script>
if (window.location.href.includes('#')) {
// run your code here
}
</script>
use a location.hash function will solve your problem
var hash = window.location.hash.replace(/#/g, '');
if(hash){
// found a hash
console.log("heyy I found a hash")'
}
else{
// did not find a hash
console.log("Uh oh")
/*
try using :
window.location = window.location + '#' + "some random variable"
to create a new URL and every time the page loads find the hash and
display the wanted data.
*/
}
PS: this only works if your URL is like example.com/#xyz
then it will give you xyz as a console output. This may sound
vague but if you do this you may get a Idea

How to make the user not duplicate browser tabs?

There was a task to make each web page of the project not repetitive. Those. the user should not, as a consequence of inattention within the same browser, open multiple duplicates of the same web page. Please suggest a specific solution.
The task can be solved very simply, if one condition is met — each page has its own unique identifier. I have this $(‘body’).attr (‘id’).
Let’s call the function noDuplicateTabs and call it every time the page starts.
We use localStorage:
let noDuplicateTabs = function (pageName) {
localStorage.getItem(pageName)
? window.close()
: localStorage.setItem(pageName, 'open');
window.onbeforeunload = function () {
localStorage.setItem(pageName, '');
};
}
Thus, we pass the name of the page in the function, check for the presence of a value using the localStorage key corresponding to the page name.
If a key with a non-empty value is found, then we close the page, if not, then write the value to it ‘open’.
We also use the onbeforeunload property of the window, which works before reloading or closing the page. In this case, we will erase the value.
Now there will be no duplicates within the same browser.

How can I detect back button in the browser?

I have a function named back() which will be used for ajax calls. Actually I have an array stack contains last 5 search results and that back function will switch to the previous result set (according to that array stack) and it even changes the URL using window.history.pushState() when you click on the back button.
That back button I was talking about, is an element inside the browser which revokes back() function. Now I want to revoke back() function also when user click on the back button of the browser. Something like this:
window.onhashchange = function() {
back(); // this function also changes the url
}
But sadly window.onhashchange will be revokes twice when I click on the back of the browser. Because window.onhashchange will be revoked when you change the URL using window.history.pushState().
Anyway, how can I detect what things changes the URL? Either my JS code or the back button of the browser?
You can use performance.navigation.type
At any given point, for example on document.onload, you can read the value of type and, if it's:
0 The page was accessed by following a link, a bookmark, a form submission, a script, or typing the URL in the address bar.
1 The page was accessed by clicking the Reload button or via the Location.reload() method.
2 The page was accessed by navigating into the history.
255 any other way.
Just beware that support is limited according to the compatibilty table.
However, from the looks of it, it seems the table is outdated. It says it is not supported on chrome and I just tested it and works as expected on my chrome version (67.0)
One of solution is to implement onunload event with localstorage option.
This is from my head maybe you will need correction but this is base !
var history = [];
window.onload = function(){
var handler;
if ( localStorage.getItem('history') == null ) {
// FIRST TIME
history[0] = window.location.href;
localStorage.setItem("history", JSON.stringify(history));
}
else {
handler = localStorage.getItem('history');
handler = JSON.parse(handler);
history = handler;
// Just compare now
if (history[history.length-1] == window.location.href) {
// no change
} else {
history.push(window.location.href);
}
}
}
window.onunload = function(){
localStorage.setItem('history', JSON.stringify(history));
}
Note :
Since 25 May 2011, the HTML5 specification states that calls to
window.alert(), window.confirm(), and window.prompt() methods may be
ignored during this event. See the HTML5 specification for more
details.

Modify document.location so a new tab/window is opened instead of navigation in current tab

I want to write a bookmarklet that will modify any webpage so that when the JavaScript code on that page does something like document.location = 'http://site.tld' or document.location.href = 'http://site.tld' the page will open a new tab or window instead of changing location; same as if code was window.open('http://site.tld');
Can I modify the prototype somehow to achieve this goal? (I use this word carelessly because although I've read about modifying prototypes a few times, I've never actually done it.) Or is there some other way?
You didn't say which browser you're using, but the only way I can think of to accomplish this is using Firefox's Object.watch.
document.watch('location', function(prop, oldval, newval) {
window.open(newval);
return '#';
});
This will intervene on any attempt to set document.location, open a window with the same argument instead, and then change the assignment to '#' instead (which will do nothing, usually).
In bookmarklet form, and expanded to cover both document.location and window.location:
javascript:(function(){var handle=function(prop, oldval, newval){window.open(newval); return '#';};document.watch('location',handle);window.watch('location',handle);})();
But even this won't work against assignment to document.location.href; the location object is some special thing that Object.watch refuses to work on.
If that's not enough, you could use onbeforeunload to prompt you when you try to navigate away and cancel it (if that's your goal here).
Best I've got, sorry!
I was going to suggest using the ES5 Object.defineProperty, but as it should be, document.location is a "configurable: false" object, meaning that it can't be changed. For the curious, if you would be able to change it the code would be like this:
Object.defineProperty(document.location, 'href', {
get: function() { return this.href },
set: function(value) { this.href = value; window.open(value); return false} //Not sure about this part, but anyways...
});
Edit: Answering your question, i don't think that this is achievable via a bookmarlet.
I tried different methods but it's almost impossible to trace the href of the target window.
Using
window.onbeforeunload = function(e) {
window.open(document.location.href);
};
will open your current window in another tab and the target in current window. The problem is that onbeforeunload is triggered not only on changing the location of the window, even on closing window or refreshing it. Depends where you want to use it.
PS:
window.onunload = function() {
document.location = document.location;
}
if you test this, when you change the page location, you will be able to see the new url in the address bar for a moment then you will be redirected to your current page. I didn't managed to get the new target. Good luck!
You could only do something with the prototype if it were a function call rather than an assignment. For example in the case of document.write
document.write = function(txt) {
alert("txt");
};
document.write("test");
FWIW: This works on the latest firefox to search for the selected text in a new tab:
javascript:Qr=document.getSelection();if(!Qr){void(Qr=prompt('Keywords...',''))};if(Qr)window.open("http://google.com/search?query="+escape(Qr));void(0)

How to run a javascript function using the # in the url?

hi this all started when i ran a function (lets call it loadround) that altered the innerHTML of an iframe. now once loadframe was loaded there were links in the iframe that once clicked would change the iframe page. the only problem is when i click the back button the loadround page was gone. i've thought about this numerous times to no avail. so i tried this code.
loadround
then
function loadround(a,b){
window.location.hash = "#loadround('"+a+"','"+b+"')";
var code = "<(h2)>"+a+"</(h2)><(h2)>"+b+"</(h2)>"
var iFrame = document.getElementById('iframe');
var iFrameBody;
iFrameBody = iFrame.contentDocument.getElementsByTagName('body')[0]
iFrameBody.innerHTML = code;
}
(the brackets in the h2 are intentional)
then i would try to reload the function by possibly an onload function but for now i was testing with a simple href as followed.
function check(){
var func = location.hash.replace(/#/, '')
void(func);
}
check
unfortunately the check code doesn't work and im almost certain there is an easier way of doing this. i tried changing the src of the iframe instead of the innerhtml and there was the same problem. thanks in advance
The modern browsers are starting to support the event window.onhashchange
In the meantime you can use the workaround proposed by Lekensteyn or maybe you can find something useful here: JavaScript/jQuery - onhashchange event workaround
You are misunderstanding the function void, which just make sure the return value is undefined. That prevents the browser from navigating away when you put it in a link. You can test that yourself by pasting the next addresses in your browser:
javascript:1 // note: return value 1, browser will print "1" on screen
javascript:void(1) // note: undefined return value, browser won't navigate away
It's strongly discouraged to execute the hash part as Javascript, as it's vulnerable to XSS without proper validating it. You should watch the hash part, and on modification, do something.
An example; watch every 50 milliseconds for modifications in the hash part, and insert in a element with ID targetElement an heading with the hash part. If the hash part is not valid, replace the current entry with home.
var oldHash = '';
function watchHash(){
// strip the first character (#) from location.hash
var newHash = location.hash.substr(1);
if (oldHash != newHash) {
// assume that the parameter are alphanumeric characters or digits
var validated = newHash.match(/^(\w+)$/);
// make sure the hash is valid
if (validated) {
// usually, you would do a HTTP request and use the parameter
var code = "<h1>" + validated[1] + "</h1>";
var element = document.getElementById("targetElement");
element.innerHTML = code;
} else {
// invalid hash, redirect to #home, without creating a new history entry
location.replace("#home");
}
// and set the new state
oldHash = newHash;
}
}
// periodically (every 50 ms) watch for modification in the hash part
setInterval(watchHash, 50);
HTML code:
Home
About Me
Contact
<div id="targetElement">
<!-- HTML will be inserted here -->
</div>

Categories