Reputation: 1496
I have a function I want to run when the homepage of a website is first loaded. However, I don't want that function to run if, instead of getting to the homepage by accessing it directly, I get there because I clicked on a link on the site that directs me there.
For this, I direct every link that gets you to the homepage to home.html#loaded
instead of home.html
. I also created the function below to be the one onload
executes:
function onloadPreventer(fun) {
if (window.location.hash != "#loaded") {
//alert(window.location.hash);
window.location = window.location + "#loaded";
//alert(window.location.hash);
fun;
};
};
This function should only execute the function fun
if there is no #loaded
after home.html
. However, it always executes fun
.
However, the weird part is that it does not add #loaded
once again:
When I first go to home.html
(without hash) -- and if I comment out the alert
statements -- it first gives me nothing, then gives me #loaded
and then runs fun
. All as it should.
If I go to home
from another page, I'm already first loading home.html#loaded
. The page alerts nothing, onloadPreventer
does not add another #loaded
at the end of the current location, but fun
runs anyway.
The above function is called from inside the <body>
tag, through an onload
event:
<body onload="onloadPreventer(anotherFunction(arg))">
Unlike what the comments below suggest, fun
does run. My problem is that even if the page has the hash #loaded
, the rest of the code inside the if
statement does not run, but fun
still does.
What's wrong with this code?
And is there another way (possibly simpler) to accomplish what I am trying to accomplish?
Upvotes: 3
Views: 12342
Reputation: 288120
It seems you are confused with functions:
function foo(){ /* ... */ } /* does NOT call foo */
function bar(){ /* ... */ } /* does NOT call bar */
foo; /* does NOT call foo */
foo(arg); /* DOES call foo with arg as argument */
foo(bar); /* does NOT call bar, and DOES call foo with bar as argument */
foo(bar(arg)); /* DOES call bar with argument arg, and DOES call foo
with the returned value of bar as argument */
Then, you are calling a function if, and only if, you use parentheses.
(Alternatively, you can make browser to call functions for you, e.g. making them event handlers, or delayed functions with setTimeout
or setInterval
. In those cases you don't use parentheses.)
In your case, you can use
function onloadPreventer(fun) {
if (location.hash !== (location.hash = "#loaded")) {
fun(); // DOES call fun
}
}
But fun
must be a function, not the returned value by a function:
<body onload="onloadPreventer(
function(){anotherFunction(arg);} /* does NOT call anotherFunction */
)">
But better separate scripts from content:
function fun() {
anotherFunction(arg);
}
document.body.onload = function onloadPreventer() {
if (location.hash !== (location.hash = "#loaded")) {
fun(); // DOES call fun
}
};
Upvotes: 3
Reputation: 12161
This works like a charm:
$(window).load(function(){
var load = "#loaded";
if (window.location.hash != load) {
window.location = window.location + load;
document.write(load);
};
})
Your problem is in here: onload="onloadPreventer(anotherFunction(arg))
The "anotherFunction" is running because of the () after it.
You can use onload="onloadPreventer(anotherFunction)
or use event listeners since we are no longer in the dark ages!
Upvotes: 1
Reputation: 1114
This works in my tests:
I have two rudimentary pages:
<html><head>
<script type="text/javascript">
var callWhenNoHash = function() {
console.log('called');
};
window.onload = function() {
if (window.location.hash != '#hash') {
callWhenNoHash();
}
};
</script></head>
<body><a href="test2.html">test2</a></body>
</html>
and:
<html><head></head><body>
<a href="test1.html#hash">test2</a>
</body></html>
everything works as expected.
Upvotes: 1