Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
How do I get something from the for-loop in the event handler?
This json array
var elements = [ { "id": "#id1", "name": "text1" }, { "id": "#id2", "name": "text2" } ];
is passed to that function
function setHandlers(elements) {
for (var i = 0; i < elements.length; i++) {
$(document).on("focusout", elements[i].id, function() {
alert(elements[i].id); // doesn't work because 'element' isn't
// defined.
});
}
}
How can I access elements without defining it outside the function?
EDIT: types should be elements
Your code should look like that:
function setHandlers(elements) {
for (var i = 0; i < elements.length; i++) {
(function(i){
$(document).on("focusout", elements[i].id, function() {
alert(elements[i].id);
});
})(i);
}
}
You need an anonymous function to keep the i value in every loop. I.e. putting it in separate context fix the problem.
The problem is because of the closure variable i. You can use it by using a local closure
function setHandlers(elements) {
$.each(types, function(idx, obj){
$(document).on("focusout", obj.id, function() {
alert(obj.id); // doesn't work because 'element' isn't
// defined.
});
})
}
Note: You are iterating types, is it a mistake?
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
I'm trying to get these functions defined to run some synchronous and asynchronous test cases on them with Mocha and Chai in JS, what am I doing wrong? Why is my editor marking certain lines?
module.exports = {
function myFunctiona () {
}
function myFunctionb () {
for (let i = 0; i < 10000; i++) {
new Date();
}
}
function myFunctionc(done) {
setTimeout(done, 0);
}
function myFunctiond (done) {
setTimeout(done, Math.round(Math.random() * 10));
}
}
This is a syntax error because you're defining an object with properties, but you don't have property keys. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Missing_colon_after_property_id for more information.
Typically, you'd define an object like the following
(note the commas after each property too):
var object = {
property1: 'thing',
property2: function() {
return 'thing2';
}
}
so to change your functions to properties, set the property key as the function name, and then assign a function to it like:
module.exports = {
myFunctiona: function () {
//nothing
},
myFunctionb: function () {
for (let i = 0; i < 10000; i++) {
new Date();
}
},
myFunctionc: function (done) {
setTimeout(done, 0);
},
myFunctiond: function (done) {
setTimeout(done, Math.round(Math.random() * 10));
}
};
This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 4 years ago.
I am trying to create event listeners for a pure JS dropdown menu. When I try to create the listeners using a for loop I get an error and it doesn't work, but when I create them manually using arrays they work perfectly. What am I missing?
var dropDown = document.getElementsByClassName('nav-sub__mobile-dropdown');
var subNavList = document.getElementsByClassName('nav-sub__list');
for ( i = 0; i < dropDown.length; i++) {
dropDown[i].addEventListener('click', function() {
subNavList[i].classList.toggle('nav-sub__list--active');
});
}
The above doesn't work, but if I create the event listeners manually using the arrays it does work.
dropDown[0].addEventListener('click', function() {
subNavList[0].classList.toggle('nav-sub__list--active');
});
dropDown[1].addEventListener('click', function() {
subNavList[1].classList.toggle('nav-sub__list--active');
});
dropDown[2].addEventListener('click', function() {
subNavList[2].classList.toggle('nav-sub__list--active');
});
When I use the for loop I get the following error code in my console.
Uncaught TypeError: Cannot read property 'classList' of undefined
UPDATE SOLVED PROBLEM
I was able to solve the problem using let thanks to Ben McCormick's comment here:
JavaScript closure inside loops – simple practical example
The solution was to simply use let in the for loop.
for (let i = 0; i < dropDown.length; i++) {
Because when the click function is called, the variable i has the last value it held, dropDown.length, not the loop value at the time addEventListener was called.
What you want is something like this:
for ( i = 0; i < dropDown.length; i++) {
function addListener(n) {
dropDown[n].addEventListener('click', function() {
subNavList[n].classList.toggle('nav-sub__list--active');
});
}
addListener(i);
}
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
I'm trying to convert a string into a function without using eval(), however whenever I pass the function name into the window object and check its type. Javascript does not seem to recognize it as a function. I always get this custom error message I've defined in the else statement: "Could not find function: 1->validateLogin".
My dom_ready prototype:
dom_ready: function (inputFunc) {
document.addEventListener("DOMContentLoaded", function () {
try {
inputFunc();
} catch (e) {
DN.errors.push(e.message);
}
});
},
function show_pass() {
...
}
function validateLogin(k) {
...
}
DN.DOM.dom_ready(function () {
var event_ids = [
["#login-form-dialog", "validateLogin", "submit", 1]
["#loginnotes", "validateLogin", "click", 1],
["#loginnotes2", "validateLogin", "click", 2],
["#show-pass", "show_pass", "click", ""],
]
for (var i = 0; i < event_ids.length - 1; i++) {
var fN = window[event_ids[i][1]];
if (typeof fN === 'function') {
$(event_ids[i][0]).on(event_ids[i][2], function () {
fN(event_ids[i][3]);
})
} else {
console.log("Could not find function: " + i + "->" + event_ids[i][1]);
}
}
});
The particular syntax error causing your problems was addressed in other answers. To find such syntax errors, look at the console for errors. Or, run your code through a linter. Otherwise, you will have to post to SO every time you forget a comma, which does not seem to be a very scalable approach.
More basically, do not pass around function references using strings giving their names, which you need to then look up on the window object. Instead, just pass the function reference itself (validateLogin). Unlike some other languages, in JS functions are first-class citizens which can be referred to and passed around as themselves. Your code would look like this:
DN.DOM.dom_ready(function () {
var event_ids = [
["#login-form-dialog", validateLogin, "submit", 1]
^^^^^^^^^^^^^
...
for (var i = 0; i < event_ids.length - 1; i++) {
var fN = event_ids[i][1];
Of course, you will have to make sure that validateLogin is visible at the time this ready function is executed.
However, you have a more basic problem which will prevent your code from running properly, in the following lines:
$(event_ids[i][0]).on(event_ids[i][2], function () {
fN(event_ids[i][3]);
})
Here, the anonymous function is a closure over the variable i, and at the time it is executed (when the event occurs), i will already be at its maximum value of 3. There are many questions and answers on this topic here on SO, but the easiest solution is to use for (let i, if you are working in an environment that supports let. Otherwise, see questions like this one.
You are missing a comma after the first item in event_ids:
var event_ids = [
["#login-form-dialog", "validateLogin", "submit", 1], // <-- missing comma
["#loginnotes", "validateLogin", "click", 1],
["#loginnotes2", "validateLogin", "click", 2],
["#show-pass", "show_pass", "click", ""],
]; // <-- also it is better practice to have semi-colon here
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
I have an Object
function Object(name, button) {
this.name = name;
this.button = button;
var alert = function () {
alert("x");
};
}
var ExampleOne = new Object('Example One', $('.exampleButton'));
How can I make the function inside the object fire on an event of Object[button]...
Using -
ExampleOne.button.click(function () {
ExampleOne.alert();
});
Doesn't work.
var alert = function is a local function and cannot be accessed outside that object. If you want it to be accessible with new instances, declare it with this:
function Object(name, button) {
this.name = name;
this.button = button;
this.alert = function () {
alert("x");
};
}
Fiddle: http://jsfiddle.net/qow3qu0m/2/
It's working for me. Check your code again. Maybe you forgot to include jQuery?
ExampleOne.button.click(function(e) {
alert('success!');
});
http://codepen.io/anon/pen/yyGpLz
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 9 years ago.
Improve this question
What does the third argument 'false' represent in the last line of the bellow code?
var parent = document.getElementById('parent'),
child = document.getElementById('child'),
op = document.getElementById('op'),
op2 = document.getElementById('op2');
parent.addEventListener('click', function () {
op.innerHTML += '<p>click registered</p>';
}, false);
function stopEvent (e) {
e.stopPropagation();
op2.innerHTML += '<p>propagation stopped</p>';
}
child.addEventListener('click', stopEvent, false);
if it is true it would be considered at the beginning of the all other added function (it is called captured), if not it would be just simply add to the end of list (called bubbled), let's say you have:
parent.addEventListener('click', function () { console.log("nocapture1"); }, false);
parent.addEventListener('click', function () { console.log("usecapture1"); }, true);
parent.addEventListener('click', function () { console.log("nocapture2"); }, false);
parent.addEventListener('click', function () { console.log("usecapture2"); }, false);
then once it is clicked, you would have them with this order in the console:
usecapture1
usecapture2
nocapture1
nocapture2
It specifies whether or not you want to capture the event. In this case, it isn't necessary because it defaults to false anyway. See the MDN documentation for element.addEventListener for more information.