So I have this javascript on a project I'm working on:
<script type="text/javascript">
document.getElementById('contact').onmouseover = function ()
{
var w = 130;
function step()
{
if (w < 250)
{
middle.style.width = (w++) + "px";
setTimeout(step, 5);
}
}
setTimeout(step, 1500);
};
</script>
I want this to run only once. After it detects a mouseover, I want it to run the function and then never run again until the page refreshes. How would I acplish this?
So I have this javascript on a project I'm working on:
<script type="text/javascript">
document.getElementById('contact').onmouseover = function ()
{
var w = 130;
function step()
{
if (w < 250)
{
middle.style.width = (w++) + "px";
setTimeout(step, 5);
}
}
setTimeout(step, 1500);
};
</script>
I want this to run only once. After it detects a mouseover, I want it to run the function and then never run again until the page refreshes. How would I acplish this?
Share Improve this question edited Jul 21, 2014 at 21:06 Code Maverick 20.4k12 gold badges65 silver badges115 bronze badges asked Jul 21, 2014 at 21:01 BillBill 918 bronze badges 5-
3
Use
addEventListener
(orattachEvent
) to add it, and thenremoveEventListener
(ordetachEvent
) to detach it – Ian Commented Jul 21, 2014 at 21:04 - @T.J.Crowder - The reason I am hesitant to suggest using the event listener is because to have it work with ie8 (which still unfortunately has a user base) you need to use a poly fill when it isn't available. Any suggestions on what to do with that? Should the answer always also include the polyfill? Is ie8's user base really to be ignored entirely? – Travis J Commented Jul 21, 2014 at 21:10
- 1 @T.J.Crowder I was thinking about it, and then I saw someone else already answered with the same suggestion, and they're currently improving their answer :) – Ian Commented Jul 21, 2014 at 21:11
-
3
@TravisJ: Well, I would probably point them at this answer, which has a thorough polyfill for it. But as it's my answer, that could seem to be self-serving... :-) (Actually, let me CW it...done, now it's a CW.) And no, I don't think we can ignore IE8, I would always mention
attachEvent
(in fact, I edited it into the firstaddEventListener
answer here). – T.J. Crowder Commented Jul 21, 2014 at 21:16 - @TravisJ I'd say that depends heavily on the target user base. Certain crowds are much less likely to be using IE than others (such as gamers for one). – mechalynx Commented Jul 21, 2014 at 21:21
5 Answers
Reset to default 4I'd either use jQuery's one
method or if you want to use 'plain' JavaScript you could just remove the event after the function has been triggered. Here's an example:
// Create a named function for the mouseover event
function myFunc() {
// Remove the `myFunc` function event listener once `myFunc` is run
document.getElementById('contact').removeEventListener('mouseover', myFunc, false);
var w = 130;
function step() {
if (w < 250) {
middle.style.width = (w++) + "px";
setTimeout(step, 5);
}
}
setTimeout(step, 1500);
};
// Add an event listener to run the `myFunc` function on mouseover
document.getElementById('contact').addEventListener('mouseover', myFunc, false);
Note that if you have to support IE8 (or even earlier), you need to use ...attachEvent("onmouseover", myFunc)
and detachEvent("onmouseover", myFunc);
instead; you can tell by checking if the element has addEventListener
:
var elm = document.getElementById('contact')
if (elm.addEventListener) {
// Use addEventListener
}
else {
// Use attachEvent
}
(Perhaps hidden away in a utility function.)
All you need to do is remove the event listener from within the listener (so that it will stop listening to the event). However, in order to remove the listener, you need a reference to it, so you can't do it with a predefined listener directly attached to mouseover
. Instead, use addEventListener
to attach the listener, keep the returned reference and then use removeEventListener
to remove the listener from within the callback.
var contact = document.getElementById('contact');
contact.addEventListener('mouseover', tehlistener);
function tehlistener() {
// yada yada do whatever
// ...
// I think it's ok to use `this` here, but since this is so specific
// its better to be specific about which listener you want removed
contact.removeEventListener('mouseover', tehlistener);
};
Here's a link to the lovely MDN article on addEventListener.
If you are interested in using JQuery, there is a nice function called "one" that may be exactly what you need.
http://api.jquery./one/
Edit: Adding more code to show more of the solution:
$( "#contact" ).one( "mouseover", function() {
var w = 130;
function step()
{
if (w < 250)
{
middle.style.width = (w++) + "px";
setTimeout(step, 5);
}
}
setTimeout(step, 1500);
});
You could just overwrite the event handler
<script type="text/javascript">
document.getElementById('contact').onmouseover = function() {
var w = 130;
function step() {
if (w < 250) {
middle.style.width = (w++) + "px";
setTimeout(step, 5);
}
}
setTimeout(step, 1500);
this.onmouseover = null;//overwrite event handler with a blank callback
};
</script>
You can use a once
function.
function once(fn){
var called = false;
return function(){
if (called) {
return;
}
called = true;
return fn.apply(this, arguments);
}
}
Example:
something.onmouseover = once(function(){
// this will happen only once
});