In JavaScript, I have an element (which is an input tag).
This code :
element.addEventListener("focus", function () {
this.parentNode.parentNode.style.outline = this.parentNode.parentNode.dataset.ans_outline;
});
When the input is focused, outline is changed immediately.
My question is : how could I delay this event ?
I've tried :
element.addEventListener("focus", function () {
setTimeout(function(node) {
node.parentNode.parentNode.style.outline = node.parentNode.parentNode.dataset.ans_outline;
}(this), 1000)
});
.. But it doesn't work :(
try this:
element.addEventListener("focus", function () {
var node = this;
setTimeout(function() {
node.parentNode.parentNode.style.outline = node.parentNode.parentNode.dataset.ans_outline;
}, 1000)
});
First argument of setTimeout function is function you want to execute (do not call this function directly).
You can store reference to this in node variable and then use it inside your timed out function (see closures)
Remove the reference to the this and give it this way:
element.addEventListener("focus", function () {
$this = this;
setTimeout(function() {
$this.parentNode.parentNode.style.outline = $this.parentNode.parentNode.dataset.ans_outline;
}, 1000)
});
Related
I am trying to add the input data into an array delayed for 2 seconds after the last keystroke. However, when I run this I get the following error: Uncaught TypeError: this._validateInput is not a function
How can I properly scope this._validateInput() to run on delay?
I tried let func = this._validateInput();, but that seems to run the function every time that func is set.
Also, the on-change input handler only fires when the input loses focus.
Looking for away to solve this...
<paper-input id="itemId" on-input="_autoAddToArray"></paper-input>
...
_validateInput () {
console.log('validate input');
}
_autoAddToArray () {
let timeout = null;
clearTimeout(timeout);
timeout = setTimeout(function () {
this._validateInput();
}, 2000);
}
Either use a lambda:
setTimeout(
() => this._validateInput(),
2000
);
or bind the function
setTimeout(this._validateInput.bind(this), 2000);
Either solution should work
The lambda works because it doesn't have its own scope.
The binding works because it applies the scope "before" running it so to speak
The this keyword always refers to the this of the current scope, which changes any time you wrap something in function() { ... }
You need to assign your this in the outer scope to a variable.
var self = this;
timeout = setTimeout(function () {
self._validateInput();
}, 2000);
Reference: setTimeout scope issue
<paper-input id="itemId" on-input="_autoAddToArray"></paper-input>
...
_autoAddToArray () {
let timeout = null;
clearTimeout(timeout);
let that = this;
timeout = setTimeout(function () {
that._validateInput();
}, 2000);
}
_validateInput () {
if(this.$.itemId.value) {
// do something
}
}
I have an object that I have a few functions inside that I am using setTimout inside. I'm trying to clear the timeout using clearTimeout.. but I'm not hitting it right.
var ExpireSession = {
killSession: function () {
var TESTVAR2 = setTimeout(function () {
window.location.href = "error/expired.aspx";
}, 15000);
},
stopTimers: function (){
clearTimeout(ExpireSession.killSession.TESTVAR2)
}
}
Before 15 seconds I am triggering: ExpireSession.stopTimers(); but it does not stop it. Any ideaas what I am doing wrong here?
var TESTVAR2 is a variable that is local to the function it is declared within. It is not a property of an object.
If you want to access it as a property of an object, then you must define it as such:
ExpireSession.killSession.TESTVAR2 = setTimeout(function () {
(You might be able to make use of this depending on how you call the function).
Because JavaScript has functional scope, TESTVAR2 will only be defined within killSession. To reference it, you can set it as a property of ExpireSession:
killSession: function () {
this._TESTVAR2 = setTimeout(function () {
window.location.href = "error/expired.aspx";
}, 15000);
},
stopTimers: function () {
clearTimout(this._TESTVAR2);
}
This question already has answers here:
How can I pass a parameter to a setTimeout() callback?
(29 answers)
Pass correct "this" context to setTimeout callback?
(6 answers)
Closed 9 years ago.
I am trying to show a div of information on a bar graph if the user hovers over the bar for a second. The answers on this site have gotten me to this point
var timer;
$(".session_hover").on({
'mouseover': function () {
timer = setTimeout(function () {
$(this).children('.session_info').css({'top':175,'right':20}).fadeIn('fast');
}, 1000);
},
'mouseout' : function () {
clearTimeout(timer);
}
});
The above code works when I replace $(this) with $(".session_hover") but then, of course it triggers all the other $(".session_hover") on the page.
How can I pass $(this) into my setTimeout function so that it only applies to the child element of the div I am hovering over?
Thanks for your help!
Try creating a closure around a variable to capture $(this), and then use it in your function:
'mouseover': function () {
var $this = $(this);
timer = setTimeout(function () {
$this.children('.session_info').css({'top':175,'right':20}).fadeIn('fast');
}, 1000);
},
Note that in modern browsers, you can also provide this as a parameter to setTimeout, like this:
'mouseover': function () {
timer = setTimeout(function (t) {
$(t).children('.session_info').css({'top':175,'right':20}).fadeIn('fast');
}, 1000, this);
},
However, if you want this to work in IE < 9, you need to use one of the polyfill techniques described in this MDN article.
Like this:
var timer;
$(".session_hover").on({
var self = this;
'mouseover': function () {
timer = setTimeout(function () {
$(self).children('.session_info').css({'top':175,'right':20}).fadeIn('fast');
}, 1000);
},
'mouseout' : function () {
clearTimeout(timer);
}
});
You need to hold a reference to this outside the setTimeout.
var timer;
$(".session_hover").on({
'mouseover': function () {
var ctx = this;
timer = setTimeout(function () {
$(ctx).children('.session_info').css({'top':175,'right':20}).fadeIn('fast');
}, 1000);
},
'mouseout' : function () {
clearTimeout(timer);
}
});
Another alternative is to use bind which is part of ECMAScript 5 (IE9+).
var timer;
$(".session_hover").on({
'mouseover': function () {
timer = setTimeout((function () {
$(this).children('.session_info').css({'top':175,'right':20}).fadeIn('fast');
}).bind(this), 1000);
},
'mouseout' : function () {
clearTimeout(timer);
}
});
Here's a demo using Bind
I have assigned 5000 ms to Settimeout but it is executing before assigned time interval.Can any body explain why it is happening.
<script type="text/javascript">
var getcallback = {
closure: function (callback, functionparam) {
return callback.call(functionparam);
}
}
var cleartimeout;
var startSlideShow = {
timerid: 5000,
startAnimation: function () {
cleartimeout = setTimeout(getcallback.closure(function () {
alert("this is a basic example of chaining methods");
this.startAnimation();
},this), this.timerid);
},
stopAnimation:function(){
}
}
startSlideShow.startAnimation();
</script>
Because getcallback.closure() is executing the function right away, you are not storing a reference to a function to call at a later time.
As soon as you call startAnimation, you're calling getcallback.closure, which immediately calls the callback function. To use setTimeout correctly, you need to either have closure return a function, or not use such a strange thing, and instead just use an anonymous function.
Something along the lines of:
var getcallback = {
closure: function (callback, functionparam) {
return function() {
callback.call(functionparam);
};
}
}
...
Or, to be cleaner, just:
var cleartimeout;
var startSlideShow = {
timerid: 5000,
startAnimation: function () {
cleartimeout = setTimeout(function () {
alert("this is a basic example of chaining methods");
this.startAnimation();
}, this.timerid);
},
stopAnimation:function(){
}
}
startSlideShow.startAnimation();
I'm trying to get a reference to cell and it appears null. If I'm understanding it correctly, I should be able to reference the variable. Correct?
$('td[someAttr]').mouseenter(function(cell) {
var timeoutId = setTimeout(function() {
// what should variable cell be?
}, 1000);
});
OR
$('td[someAttr]').mouseenter(function(cell) {
var timeoutId = setTimeout(function() {
// what should variable cell be?
}, 1000, cell);
});
UPDATE: This was obvious but the reason I asked this was because cell.pageX would be undefined if you had:
$('td[someAttr]').mouseenter(function() {
var cell = this; //
var timeoutId = setTimeout(function() {
alert(cell.pageX); // cell.pageX will return null
}, 1000);
});
However, if you had:
$('td[someAttr]').mouseenter(function(cell) {
alert(cell.pageX); // works fine as cell.pageX will have correct value.
});
The context of the event handler is set to the element that triggered the event. You can get at it this way:
$('td[someAttr]').mouseenter(function() {
var cell = this;
var timeoutId = setTimeout(function() {
alert(cell.tagName);
}, 1000);
});
You may also want to wrap it as a jQuery object as well: var cell = $(this);
UPDATE: The first argument is the event object, not the element. The element is set as the context of the callback (i.e. this) and you can get access to the event object in exactly the way that you were in your example:
$('td[someAttr]').mouseenter(function(event) {
var cell = this;
var timeoutId = setTimeout(function() {
alert(cell.tagName + ' ' + event.pageX);
}, 1000);
});
Note that the "cell" element is also accessible as "event.target".