This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 8 years ago.
I'm making a calendar script and it works ok with the Opera browser, but not with firefox. The trouble happens in the day selection. This particular snippet illustrates the problem. In this case, dayofweek[] contains 31 DIV tags each containing its own number that people can click on.
<script type="text/javascript">
var maxdays=31;
for (var n=1;n<=maxdays;n++){
dayofweek[n].onclick="selectday("+n+")";
}
function selectday(day){alert(day+" is selected");}
</script>
This script works (in opera) by printing a message that the correct number is selected. In Firefox, the onclick event never is executed even tho I made clicks..
The other method I tried is this:
<script type="text/javascript">
var maxdays=31;
for (var n=1;n<=maxdays;n++){
dayofweek[n].onclick=function(){selectday(n);}
}
function selectday(day){alert(day+" is selected");}
</script>
This time, both firefox and opera respond, but the problem is that "31 is selected" appears no matter which number I select.
Does anyone know what I can do to make all javascript enabled internet browsers cooperate with my code?
Javascript is not block scoped. Try this:
<script type="text/javascript">
var maxdays=31;
for (var n=1;n<=maxdays;n++){
dayofweek[n].onclick=selectdaywrapper(n);
}
function selectdaywrapper(day) {
function selectday(){
alert(day+" is selected");
}
return selectday;
}
</script>
The issue you are running into has to do with scoping and how variables are bound in js. The functions you are creating in the loops are binding to the loop variable, but are not evaluated till after the loop finishes, so all the onclick events are executing with the final value of n
Related
This question already has answers here:
How to run a function when the page is loaded?
(11 answers)
Closed 6 years ago.
I want to run this script on pageload or after all the elements are loaded.
JavaScript
<script type="text/javascript">
function backgroundload (){
$(".portfolio-background-color")
var color = /#[0-9\A-F]+/.exec($(this).html())[0];
$(this).css('background', color)
}
window.onload = backgroundload;
</script>
i'm new to js please check if my code is okay and is it the correct way to load the js
All Javascript runs on page load. If what you mean is that you want it to run after all the elements in the page have been initialized, there are several ways:
window.onload
document.onload
body.onload
$(document).ready
There are more in-depth explanations of the support for the first three, and the differences between them, here. Documentation for $(document).ready is here.
However, in my experience, the easiest way to ensure that a script runs after all synchronously-loaded content is simply to place the <script> element at the bottom of the <body>.
This question already has answers here:
JS function named `animate` doesn't work in Chrome, but works in IE
(3 answers)
Closed 1 year ago.
It's an issue with google chrome version 53.0.2785.101 (64-bit). I tried running a simple html file and it throws the error 'slot.testFun is not a function' when I used the word 'slot'.
<html>
<head>
<title>TEST</title>
</head>
<body>
Click Here
<script type="text/javascript">
var slot = {
testFun: function(){
console.log('clicked');
}
}
</script>
</body>
</html>
There are no conflicts with this variable in our code. It's just the browser, not allowing the variable name in this latest version.
If you use any other name except the word 'slot', it works fine.
This isn't an ECMAScript issue, it is a DOM issue.
The slot attribute has a corresponding slot property, and onclick attributes do stupid things with with so you are effectively calling this.slot.testFun() because it finds slot (which defaults to being an empty string) before it gets to the right scope.
slot is a new addition to the DOM and support for slot is new in Chrome 53. It does not appear in Chrome 52 and might not have made it even into the latest version of other browsers.
The solution: Avoid intrinsic event attributes. Bind event handlers with DOM instead. That protects you from his clash and future-proofs you from future additions to the DOM.
Click Here
<script type="text/javascript">
var slot = {
testFun: function(){
console.log('clicked');
}
}
document.querySelector("a").addEventListener("click", slot.testFun);
</script>
This question already has answers here:
Why does jsfiddle throw error that function is not defined? [duplicate]
(1 answer)
Why isn't my JavaScript working in JSFiddle?
(7 answers)
Closed 6 years ago.
I'm trying to run a basic JavaScript function from an external file but I'm getting inconsistent results. Basically, I can't get a button's "onclick" event to fire when I put the script in an external JS page. I can get it work in CodePen:
CodePen
nonsense code
but NOT in JSFiddle:
JS Fiddle Examlple
I can always get it work when the script is part of the HTML page but I don't want to do that. Can you help? Thanks!
jsfiddle puts the javascript code in its own context:
//<![CDATA[
window.onload=function(){
function clickFunction()
{
alert("this is working");
}
}//]]>
But codepen puts the js in the global scope.
This question already has answers here:
Why does jQuery or a DOM method such as getElementById not find the element?
(6 answers)
Closed 8 years ago.
<script type="text/javascript">
function translateIt() {
Microsoft.Translator.Widget.Translate("en", "es");
}
</script>
<button onclick="translateIt()">Translate</button>
<script type="text/javascript">
document.getElementById("btn").onclick = function () {
Microsoft.Translator.Widget.Translate("en", "es");
}
</script>
<button id="btn">Translate3</button>
This html block contains two buttons that should perform the exact same function. As such, the top button works but the bottom button doesn't. What is the difference between the 'onclick' implementation within html vs. within javascript?
The difference isn't with the click handler, the difference is the order of execution. In the first example you define something (the function) then reference it (in the HTML). In the second example you reference something (the HTML element) and then define it.
So in the second example the call to getElementById("btn") doesn't find anything, because at the time it executes that element doesn't exist yet.
HTML and JavaScript execute in the order in which they exist on the page as the page is being rendered. From the top of the document to the bottom.
If your second script example appears before the button, the getElementById will find no element.
By moving the script tag to after the element, it will work like normal.
<button id="btn">Translate3</button>
<script type="text/javascript">
document.getElementById("btn").onclick = function () {
Microsoft.Translator.Widget.Translate("en", "es");
}
</script>
This question already has answers here:
JavaScript not running on jsfiddle.net
(4 answers)
Closed 8 years ago.
this is probably stupidly easy but I'm very new to JavaScript and it's driving me nuts.
My question, why doesn't this work:
http://jsfiddle.net/Ye9tG/
<input type="button" id="butt" value="Button" onclick="getThought();"/>
It works fine if I add the onclick directly into the JavaScript:
document.getElementById("butt").onclick = getThought;
Thanks in advance.
Your getThoughts function isn't defined, because your JavaScript is set to execute onLoad. See the dropdown menu in the upper left of jsFiddle. Select "No wrap - in <head>" to resolve the issue: http://jsfiddle.net/Ye9tG/1/
Also, always take a look at your browser's console to check for errors. In this case, you'll see a Uncaught ReferenceError: getThought is not defined error when clicking the button.
In the top left corner of jsfiddle you'll see that your fiddle is set to run your js code "onLoad". What that really means is that jsfiddle creates this for you:
<script type='text/javascript'>//<![CDATA[
window.onload=function(){
// YOUR CODE HERE
}//]]>
</script>
As a result, your function is only accessible within that onload function. Change the value to "no wrap head" and you'll see that it works.
Your other option would be to make your function explicitly global:
window.getThought = function(){
// ...
http://jsfiddle.net/Ye9tG/5/