I've got a simple function that does basically nothing but alert me of the validity:
function alertV(elem) {
alert("here");
alert(elem.checkValidity());
alert("really");
}
The code for hooking this up:
var elements = document.forms["form"].getElementsByTagName("input");
for (i = 0; i < elements.length; i++) {
elements[i].onkeyup = function () { alertV(elements[i]) };
}
Here shows up fine, but checkValidity() isn't doing anything and is even causing the really call to be ignored. Am I passing in the arguments wrong? I essentially just want this, which works:
<input type="text" onkeyup="alertV(this);">
Try using a closure:
elements[i].onkeyup = (function (a)
{
return function ()
{
alertV(elements[a])
}
})(i);
Related
Ok I think I know the answer to this, looking to confirm. So I have a selector that's only used once, but it's used inside a function that's called several times. From a performance perspective, since that selector is re-searched-for each time the function is called, it's probably (albeit marginally) better to cache the selector?
In other words, the below...
function testFunction() {
alert($("#input").val())
}
$("#a").click(function() {
testFunction()
})
$("#b").click(function() {
testFunction()
})
$("#c").click(function() {
testFunction()
})
...is not as performant as the below
input = $("#input")
function testFunction() {
alert(input.val())
}
$("#a").click(function() {
testFunction()
})
$("#b").click(function() {
testFunction()
})
$("#c").click(function() {
testFunction()
})
Evidently, jQuery() call completes in less total time than variable reference to jQuery object. Last run logged
jQuery(): 16.580ms
cached jQuery() object: 22.885ms
(function() {
function testFunction() {
$("#input").val()
}
console.time("jQuery()");
for (let i = 0; i < 10000; i++) {
testFunction()
}
console.timeEnd("jQuery()");
})();
(function() {
let input = $("input");
function testFunction() {
input.val()
}
console.time("cached jQuery() object");
for (let i = 0; i < 10000; i++) {
testFunction()
}
console.timeEnd("cached jQuery() object");
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<input>
Yes you are right the second one is more efficient than the first one because
In the first one to select the input filled first it going to find the input
field then it select that input field,And this will happen each time of function call.
But in second case the selector is select once when the page is loaded the it refers that selector through the variable and will not go to find that input field in each call.That why 2nd one is more efficiency.
<input value='Value' id='input'><br>
<span id='tt'>dssd</span><br>
<span id='t1'></span><br>
<span id='t2'></span>
And Jquery:-
function testFunction1() {
var t=$("#input").val()
$("#tt").html(t);
}
console.time("jQuery() object");
var t1=performance.now();
for (var i = 0; i < 50000; i++) {
testFunction1()
}
console.timeEnd("jQuery() object");
var t2=performance.now();
t2=t2-t1;
$("#t1").html('Without selector variable:- '+t2);
var input = $("input");
function testFunction2() {
var t=input.val();
$("#tt").html(t);
}
t1=performance.now();
console.time("cached jQuery() object");
for (var i = 0; i < 50000; i++) {
testFunction2()
}
t2=performance.now();
console.timeEnd("cached jQuery() object");
t2=t2-t1;
$("#t2").html('With selector variable:- '+t2);
Just Check here:-click here
I'm trying to call a function that's returned from a function. Here's what I mean:
myFunction.something; // (Wrong)
function myFunction() {
return {
something: function() {
...
}
};
}
When I try calling myFunction.something nothing happens. How can I call a returned function outside of its function?
JSFiddle
var index = 0;
var animID = requestAnimationFrame(myFunction.something);
function myFunction() {
return {
something: function() {
index++;
console.log(index);
if (index === 5) cancelAnimationFrame(animID);
else animID = requestAnimationFrame(myFunction.something);
}
};
}
I would first of all recommend using descriptive variable names; utils rather than myFunction, and incrementFrame rather than something, for example. I would second of all recommend reconsidering your approach to code organization and simply putting all of your helper functions directly in an object, then referencing that object:
var index = 0;
var animID = requestAnimationFrame(utils.incrementFrame);
var utils = {
incrementFrame: function() {
index++;
console.log(index);
if (index === 5) cancelAnimationFrame(animID);
else animID = requestAnimationFrame(utils.incrementFrame);
}
}
There are a few differences between these approaches, some of them frustratingly subtle. The primary reason I recommend using an object for organization rather than a function which returns an object is because you don't need to use a function for organization; you are unnecessarily complicating your code.
myfunction is not the object that you get from calling myfunction(), it's the function itself and does not have a .something method.
You could call it again (as in myfunction().something()), but a better approach would be to store a reference to the object you've already created:
function myFunction() {
var index = 0;
var o = {
something: function() {
index++;
console.log(index);
if (index < 5) requestAnimationFrame(o.something);
// btw you don't need to cancel anything once you reach 5, it's enough to continue not
}
};
return o;
}
myFunction().something();
Alternatively you might want to drop the function altogether, or use the module pattern (with an IIFE), as you seem to use it like a singleton anyway.
Try this:
myFunction().something()
myFunction() calls the myFunction function
them we use the dot notation on the returned value (which is an object) to find the something member of it
that member is a function too, so add another set of brackets () to call it
Call function after writing it
var index = 0;
function myFunction() {
return {
something: function() {
index++;
console.log(index);
if (index === 5) cancelAnimationFrame(animID);
else animID = requestAnimationFrame(myFunction().something);
}
};
}
var animID = requestAnimationFrame(myFunction().something);
When I passed my function in addEventListener() method, it don't work right. Event don't register, and my function don't call.
code
<div id="box-wrap">
<ul id="colorize">
</ul>
</div>
JavaScript
function colorize(){
var ul = document.getElementById('colorize');
for(var i = 0; i < 36; i++){
ul.appendChild(document.createElement('li'));
}
function randomColor(li){
li.style.background= "#"+(Math.random()*0xFFFFFF<<0).toString(16);
}
var liElements = ul.children;
for (i = 0; i < liElements.length; i++){
liElements[i].addEventListener('mouseover',randomColor(liElements[i]),false);
}
}
What is wrong?
The 2nd argument to addEventListener must be a function, you're giving it undefined (the output of randomColor(..)
Call it like this:
liElements[i].addEventListener('mouseover', function () {
randomColor(liElements[i]);
} ,false);
And now you'll run into a closure problem (i has the wrong value), fix like so:
(function (bound_i) {
liElements[bound_i].addEventListener('mouseover', function () {
randomColor(liElements[bound_i]);
} ,false);
} (i)); // <-- immediate invocation (IIFE)
Try instead of
liElements[i].addEventListener('mouseover',randomColor(liElements[i]),false);
using bind (be ware that this does only work in modern browsers), but the link has a fall back implementation for it)
liElements[i].addEventListener('mouseover',randomColor.bind(this, liElements[i]),false);
I have to call another function before the original onclick event fires, I've tried a lot of different paths before I've come to following solution:
function bindEnableFieldToAllLinks() {
var links = document.getElementsByTagName('a');
for (var i = 0; i < links.length; i++) {
var link = links[i];
var onclick = link.getAttribute('onclick');
link.onclick = new Function("if(linkClickHandler()){"+onclick+"}");
console.log(link.getAttribute('onclick'));
}
}
This does the trick in Firefox and Chrome but IE8 is acting strange, it seems that the function that's in the onclick variable isn't executed.
I've already added console.log messages that get fired after the if statement is true and if I print out the onclick attribute I get following:
LOG: function anonymous() {
if(linkClickHandler()){function onclick()
{
if(typeof jsfcljs == 'function'){jsfcljs(document.getElementById('hoedanigheidForm'), {'hoedanigheidForm:j_id_jsp_443872799_27':'hoedanigheidForm:j_id_jsp_443872799_27'},'');}return false
}}
}
So it seems that the function is on the onclick of the link and the old onclick function is on it as well.
Can anyone help me out with this please?
Say you have an onclick attribute on a HTMLElement..
<span id="foo" onclick="bar"></span>
Now,
var node = document.getElementById('foo');
node.getAttribute('onclick'); // String "bar"
node.onclick; // function onclick(event) {bar}
The latter looks more useful to what you're trying to achieve as using it still has it's original scope and you don't have to re-evaluate code with Function.
function bindEnableFieldToAllLinks() {
var links = document.getElementsByTagName('a'),
i;
for (i = 0; i < links.length; i++) function (link, click) { // scope these
link.onclick = function () { // this function literal has access to
if (linkClickHandler()) // variables in scope so you can re-
return click.apply(this, arguments); // invoke in context
};
}(links[i], links[i].onclick); // pass link and function to scope
}
Further, setting a named function inside an onclick attribute (i.e. as a String) doesn't achieve anything; the function doesn't invoke or even enter the global namespace because it gets wrapped.
Setting an anonymous one is worse and will throw a SyntaxError when onclick tries to execute.
This will do what you want, executing what is inside linkClickHandler first, and then executing the onclick event. I put in a basic cross browser event subscribing function for your reuse.
bindEnableFieldToAllLinks();
function bindEnableFieldToAllLinks() {
var links = document.getElementsByTagName('a');
for (var i = 0; i < links.length; i++) {
var link = links[i];
var onclick = link.getAttribute('onclick');
onEvent(link, 'click', function() {
linkClickHandler(onclick);
});
link.onclick = undefined;
}
}
function onEvent(obj, name, func) {
if (obj.attachEvent) obj.attachEvent('on' + name, func);
else if (obj.addEventListener) obj.addEventListener(name, func);
}
function linkClickHandler(funcText) {
alert('before');
var f = Function(funcText);
f();
return true;
}
jsFiddle
I have this code which calls a function test() on body onload
<body onLoad="test();">
The Test function has 2 more functions drawLayers() ,StopAll().
function test() {
function drawLayers() {
timers = [];
timers.push(setTimeout(drawMoon,800));
timers.push(setTimeout(drawCircle1,2300));
timers.push(setTimeout(drawCircle2,2700));
timers.push(setTimeout(drawCircle3,3100));
timers.push(setTimeout(drawCircle4,3500));
timers.push(setTimeout(drawCircle5,3900));
timers.push(setTimeout(drawtext2,4300));
timers.push(setTimeout(drawtext,4700));
timers.push(setTimeout(drawtext3,5100));
timers.push(setTimeout(drawtext4,5500));
timers.push(setTimeout(drawtext5,5900));
timers.push(setTimeout(drawtext6,6300));
timers.push(setTimeout(drawtext7,6700));
timers.push(setTimeout(drawtext8,7100));
timers.push(setTimeout(drawtext9,7500));
timers.push(setTimeout(drawtext10,7900));
}
function StopAll() {
alert('fsdfsdf');
for (var i = 0; i < timers.length; i++)
window.clearTimeout(timers[i]);
}
}
What i want to do is Call the StopAL() function on click of a button, the html code looks like below
<a href="javascript:void(0);" onClick="StopAll();">
Its throwing error, "StopAll is not defined"
How do i call the StopALL() function?
The scope of those nested functions is restricted to the test function only. You cannot invoke them from the outside. If you need to do that you could externalize it from the test function.
This is a 'closure' problem. The function StopAll is within the scope of the test function, and therefore is undefined in the global scope in which you are trying to call it.
Closures are a tricky subject to grasp initially. There's a good explanation here:
How do JavaScript closures work?
(by the way StopAll should really be called stopAll because capitalised functions are generally reserved for use with the new keyword.)
test = function (){
this.drawLayers = function() {
this.timers = [];
this.timers.push(setTimeout(drawMoon,800));
}
this.StopAll = function() {
alert('fsdfsdf');
var t = timers.length
for (var i = 0; i < t; i++)
window.clearTimeout(this.timers[i]);
}
}
var testObj = new test();
testObj.StopAll()
function test() {
function drawLayers() {
timers = [];
timers.push(setTimeout(drawMoon,800));
timers.push(setTimeout(drawCircle1,2300));
timers.push(setTimeout(drawCircle2,2700));
}
var StopAll=function() {
alert('fsdfsdf');
for (var i = 0; i < timers.length; i++)
window.clearTimeout(timers[i]);
}
return StopAll;
}
var obj= new test();
//to call StopAll function
obj();
(function test($) {
function drawLayers() {
}
//expose this to outside world ,public function
$.StopAll = function() {
alert('fsdfsdf');
}
})(window);
StopAll();
You'd better not use html attributes to bind event handler, you can do the same with the following code:
window.onload = function(){
document.getElementById("myLink").onclick = function(){
StopAll();
}
}
// Your functions
This way you'll ensure your dom is loaded and ready to call event handlers.
You can move the function StopAll() outside the test function and call it as specified. If suppose you need to access that function even in the test(), you can do like this
function test() {
.....
drawLayers();
StopAll() ;
}
function StopAll() {
alert('fsdfsdf');
for (var i = 0; i < timers.length; i++)
window.clearTimeout(timers[i]);
}
Declaration of function can be given outside and called any where you want