How can I create a loop out of this function:
window.onload = function makeHalo() {
document.getElementById("d1").onmouseover = function() {
this.id ="d1On";
this.className="hover";
document.getElementById("menu1").style.color="#6DC5E6";
};
document.getElementById("menu1").onmouseover = function() {
this.style.color="#6DC5E6";
document.getElementById("d1").className="hover";
document.getElementById("d1").id="d1On";
};
document.getElementById("d1").onmouseout = function() {
this.id ="d1";
this.className="";
document.getElementById("menu1").style.color="#FFFFFF";
};
document.getElementById("menu1").onmouseout = function() {
this.style.color="#FFFFFF";
document.getElementById("d1On").className="";
document.getElementById("d1On").id="d1";
};
document.getElementById("d2").onmouseover = function() {
this.id ="d2On";
this.className="hover";
document.getElementById("menu2").style.color="#6DC5E6";
};
document.getElementById("menu2").onmouseover = function() {
this.style.color="#6DC5E6";
document.getElementById("d2").className="hover";
document.getElementById("d2").id="d2On";
};
document.getElementById("d2").onmouseout = function() {
this.id ="d2";
this.className="";
document.getElementById("menu2").style.color="#FFFFFF";
};
document.getElementById("menu2").onmouseout = function() {
this.style.color="#FFFFFF";
document.getElementById("d2On").className="";
document.getElementById("d2On").id="d2";
};
}
The function pretty much learns the ID of an image when its hovered, changes the ID of that element, adds a class to the element, and changes the color of another element
The second part learns the ID of a list item when its hovered, changes its color, and changes the ID of the other image element and adds a class to that element as well.
The onmouseout simply resets everything.
On the actual HTML page, it is a menu page with lists. Below there a continent map, which is a background image. When you hover over a list item, it swaps out a point on a map with another picture for an indicator. You can also hover the points on the map to change the color of the links on the lists.
I tried doing something like this, but the loop only goes to the last iteration for some of the elements. The links change color fine, but it will only swap the picture for "d43" regardless of what link I hover over.
window.onload = function makeHalo() {
var i = 1;
for (i=1; i<44; i++) {
var menu = "menu"+i;
var d = "d"+i;
var On = "d"+i+"On";
document.getElementById(d).onmouseover = function() {
this.id = On;
this.className="hover";
document.getElementById(menu).style.color="#6DC5E6";
};
document.getElementById(menu).onmouseover = function() {
this.style.color="#6DC5E6";
document.getElementById(d).className="hover";
document.getElementById(d).id=On;
};
document.getElementById(d).onmouseout = function() {
this.id = d;
this.className="";
document.getElementById(menu).style.color="#FFFFFF";
};
document.getElementById(menu).onmouseout = function() {
this.style.color="#FFFFFF";
document.getElementById(On).className="";
document.getElementById(On).id=d;
};
}
}
Any help will be greatly appreciated.
The primary technical issue you're facing is that you're creating closures in a loop. Each one of those callbacks closes over the same i variable, whose value will be the same for each of the callbacks (its value after the final iteration). This is fixed by wrapping the body of the loop in its own function that receives i as an argument, thus creating a local copy on each iteration.
There are a number of style and performance issues, as well:
The bodies of those callbacks are in many cases exactly the same (the mouseover and mouseout pairs end up dong the same work in each block).
You're retrieving the same elements by ID repeatedly. This is unnecessary; you should save a reference.
You're identifying the state of an element by changing its ID. This isn't generally how you want to handle this. An ID shouldn't change.
I would write it more like this (addressing the closure issue and the first two bullet items above (not addressing the ID problem)):
for (var i = 1; i <= 2; i++) {
(function(i) {
var d = document.getElementById("d" + i);
var menu = document.getElementById("menu" + i);
d.onmouseover = menu.onmouseover = function() {
d.id = "d" + i + "On";
d.className = "hover";
menu.style.color = "#6DC5E6";
};
d.onmouseout = menu.onmouseout = function() {
d.id = "d" + i;
d.className = "";
menu.style.color = "#FFFFFF";
};
})(i);
}
This handles just two elements; simply change the loop max to make it work for more.
You can see a working demo here:
http://jsfiddle.net/ezYtq/
Is your last div in your HTML "d43" or is it "d44"? Your loop will run through d1 through d43 because you have i<44 which means when i is 44 it will exit the loop so it will stop at d43.
If you want it to get to d44, then either change the condition to: i <= 44
or change it to i < 45
By the way is there is reason you are not using jQuery it's design to make things like this much easier, in several ways. Maybe you listed what you were actually trying to accomplish with this code for example whether it's a menu system or something we might be able to suggest better approaches.
No need for JavaScript here... just use the CSS :hover pseudo-class.
But, to answer your question:
Do not change the id of your element. This seems fundamentally wrong. Change, add, or remove a class instead. What are you trying to accomplish by changing the id?
Don't keep track of id's, just keep track of element references directly.
Most importantly, when you are doing your loop, by the time the functions are called, the value of i is 45, for all elements. Solve this by passing i to a function that creates your event handlers:
window.onload = function makeHalo() {
for (var i = 1; i < 44; i++) {
(function (i) {
var menu = document.getElementById("menu" + i);
var d = document.getElementById("d" + i);
function over () {
d.className = "hover";
menu.style.color = "#6DC5E6";
}
d.onmouseover = over;
menu.onmouseover = over;
function out () {
d.className = "";
menu.style.color = "#FFFFFF";
}
d.onmouseout = out;
menu.onmouseout = out;
})(i);
}
}
Related
For context, I am trying to code a memory game where you have to pair two of the same colored circles until the whole board is complete. I've called it Match-Two. Here is the code that I'll reference from:
class Circle {
constructor(element, circleColor){
this.elem = element;
this.color = circleColor;
}
}
var frequency = [0, 0, 0, 0, 0, 0, 0, 0];
var num;
var hue = new Array(8);
var circle = new Array(16);
hue[0] = "#0039ff";
hue[1] = "#ff0000";
hue[2] = "#43ff00";
hue[3] = "#fffa00";
hue[4] = "#7405b5";
hue[5] = "#ff9d00";
hue[6] = "#ff00c3";
hue[7] = "#00fff6";
onload = function() {
for(var i = 0; i < 16; i++){
circle[i] = new Circle(document.getElementById("circle" + i));
while(circle[i].color === undefined){
num = Math.floor(Math.random() * 8);
if(frequency[num] != 2){
frequency[num]++;
circle[i].color = hue[num];
circle[i].elem.addEventListener('click', function(){
main(circle[i])
});
}
}
}
}
function main(circle){
circle.elem.style.backgroundColor = circle.color;
}
So in this code I create a class of Circle and I create an array of Circle objects which is identified as 'circle'. When the page is loaded, I give each circle object an element reference from my html document (There are 16 circles and they each have an id of circle0, circle1, circle2.. etc. Then there's a small algorithm to ensure there are only two of each color in the matrix so they all have a matching pair. In each iteration of the for loop, I add an event listener to each circle. If the circle is clicked, I want it to change to its color which is stored in color[i].color. However, when I click the circles all it returns is:
Uncaught TypeError: Cannot read property 'elem' of undefined
at main (script.js:39)
at HTMLDivElement.<anonymous> (script.js:31)
Which is referencing:
circle.elem.style.backgroundColor = circle.color;
So I put some console.log() functions in to see what was going on:
if(frequency[num] != 2){
frequency[num]++;
circle[i].color = hue[num];
console.log(circle[i].elem);
console.log(circle[i].color);
circle[i].elem.addEventListener('click', function(){
main(circle[i])
});
}
And this spits out exactly what I expect:
script.js:31 #ff9d00
script.js:30 div data-brackets-id="11" class="circle" id="circle1" /div
script.js:31 #ff9d00
script.js:30 div data-brackets-id="12" class="circle" id="circle2" /div
script.js:31 #0039ff
script.js:30 div data-brackets-id="13" class="circle" id="circle3" /div
script.js:31 #0039ff
So it returns the element reference and the color of the circle. So then I try putting the "circle[i].elem.style.backgroundColor = circle[i].color" into the event listener and I get the same issue as before...
if(frequency[num] != 2){
frequency[num]++;
circle[i].color = hue[num];
console.log(circle[i].elem);
console.log(circle[i].color);
circle[i].elem.addEventListener('click', function(){
circle[i].elem.style.backgroundColor = circle[i].color
});
}
Circles without their colors. The console log statements are on the right-hand side with their specific colors as well...
So I gave up and decided to write that exact line of code outside the event listener to see if that works, and it changed all the circle's colors to their specific color...
if(frequency[num] != 2){
frequency[num]++;
circle[i].color = hue[num];
console.log(circle[i].elem);
console.log(circle[i].color);
circle[i].elem.style.backgroundColor = circle[i].color;
circle[i].elem.addEventListener('click', function(){
circle[i].elem.style.backgroundColor = circle[i].color
});
}
The circles with their specific colors...
There is some problem the event listener not being able to pass the object of a Circle or something... I don't know please help :(
Your problem boils down to the way JS treats var variables - they sort of "leak" into the global scope.
Consider the event listener that you've attached:
circle[i].elem.addEventListener('click', function(){
main(circle[i])
});
So, whenever the listener gets triggered, it calls main() function and passes circle[i] into it. But since i is the variable that's leaked outside of the supposed scope, it always has the value of 16 - the value assigned to it during the last iteration of the for loop. That's why the main() function tries to access a style property of undefined - it's the value of circle[16] that was passed into it.
Here's a couple of ways to fix it:
If you can use ES6 let variables:
Use let i instead of var i in your for loop:
for (let i = 0; i < 16; i++) {
//...
}
If not, a classic way with function closure:
function createListener(j) {
return function () {
main(circle[j])
}
}
// and use it in your 'for' loop later:
circle[i].elem.addEventListener('click', createListener(i));
Here's a useful topic that provides more techniques to avoid this: JavaScript closure inside loops – simple practical example
I know this is very naive, but I'm trying to do something like this:
var add01in = "#fff";
var add01out = #000";
function over(id) {
var dupe = id.attr('id')
id.style.backgroundColor = (dupe + 'in');
}
function out(id) {
var dupe = id.att('id');
id.style.backgroundColor = (dupe + 'out');
}
<div id="add01" onmouseover="over(this)" onmouseout="out(this)">Hello World!</div>
So I want it, when the user mouseovers the div with ID = "add01", for the color to change to whatever the value of the variable "add01in" is. And when they mouseout it changes to the value of "add01out".
The only thing is I cannot for the life of me figure out how to get the words 'in' and 'out' to add on to the end of the argument's ID.
So for instance, onmouseover should make id.style.backgroundColor = add01in (as in the var) and then equal to the var's value, so #fff
sorry for making this so cryptic. any help is welcome... or alternatives, but at this time I can't find any way around this since I need to use the function a LOT of time, and with changing colours, etc.
You may use an object for the colors of the ids and their state. And use the parameter of over/out for the id.
var color = {
add01in: "#fff",
add01out: '#000'
};
function over(id) {
document.getElementById(id).style.backgroundColor = color[id + 'in'];
}
function out(id) {
document.getElementById(id).style.backgroundColor = color[id + 'out'];
}
<div id="add01" onmouseover="over('add01')" onmouseout="out('add01')">Hello World!</div>
First, att is not valid. Maybe .getAttribute? Second, you are trying to reference a variable with a variable name, which is not something you can do with JS. Use an object instead:
var colors = {
add01in: '#fff',
add01out: '#000'
}
This way you can reference them with
id.style.background = colors[dupe + 'in'];
HOWEVER you should really, really use CSS for this kind of thing.
If you want to change the text color:
var t = document.getElementById('add01');
var overColor = '#585858';
var outColor = '#000';
t.addEventListener('mouseover', function (event) {
t.style.color = overColor;
});
t.addEventListener('mouseout', function (event) {
t.style.color = outColor;
});
if you want to change the bg color
var t = document.getElementById('add01');
var overColor = '#585858';
var outColor = '#000';
t.addEventListener('mouseover', function (event) {
t.style.background = overColor;
});
t.addEventListener('mouseout', function (event) {
t.style.background = outColor;
});
Don't think you need to interpolate using the ID yeah? I think your hangup here is not realizing you can save a reference (in my example it's variable t) to the element you want to manipulate. I think that's why you were essentially trying to simulate some kind of introspection using the ID to lookup the var name.
Regarding CSS-- you could use it, but then you would have to make sure all the colors you want have classes in the stylesheet. If you're looking for more dynamic control than I can see why you'd want to do it this way. If the colors never change, then make a CSS class:
.mouse-over { color: #fff; }
and just add/remove it in the event handlers with the classList API which you can read about on MDN.
I think I've searched long enough to warrant asking this, and I hope I'm not missing something obvious, but I'm at my wits' end with this. I'm a complete JavaScript noob, and I'm having difficulty getting a script I found online to work correctly.
The project I was assigned was to make it so this form could be extended by clicking a button, and I thought I'd be able to accomplish it with HTML alone, but that doesn't seem possible. I found this script, and was able to get the duplication part of it to work:
http://www.quirksmode.org/dom/domform.html
However, the part of the script that's supposed to append a counter to the names of the fields isn't working, and therefore when the form is submitted, everything is recorded under the first form's name value. My guess is that that part of the script is trying to get the name of the wrong node, but I really don't know. Here's a shortened version of what I have. Ugly, but hopefully it gets the point across...
http://pastebin.com/nQhnXXKx
Let me know if I can clarify, and any help would be greatly, greatly appreciated!
Reorganizing the code, you could use something like this:
(function () {
"use strict";
var counter, init, addWorkshop, renameInputs, removeWorkshop;
counter = 0;
init = function () {
document.getElementById("moreWorkshops").onclick = addWorkshop;
addWorkshop();
};
addWorkshop = function () {
var clonedWorkshop, targetInsert;
counter++;
clonedWorkshop = document.getElementById("readroot").cloneNode(true);
clonedWorkshop.id = "";
clonedWorkshop.className = "";
clonedWorkshop.querySelector(".remover").onclick = removeWorkshop;
renameInputs(clonedWorkshop);
targetInsert = document.getElementById("writeroot");
targetInsert.parentNode.insertBefore(clonedWorkshop, targetInsert);
};
renameInputs = function (container) {
var children, i, j, cur, theName;
children = container.children;
for (i = 0, j = children.length; i < j; i++) {
cur = children[i];
if (cur.nodeName.toLowerCase() === "input") {
theName = cur.name;
if (theName) {
cur.name = theName + counter;
}
} else {
renameInputs(cur);
}
}
};
removeWorkshop = function () {
this.parentNode.parentNode.removeChild(this.parentNode);
};
window.onload = init;
}());
DEMO: http://jsfiddle.net/gAaxS/
Note that this is very structure-specific - for example, the this.parentNode.parentNode means that it has exactly two ancestors that you want to target. If you changed the HTML, you'd have to change the JS (which is usual).
I have a variable number of sliders on a page. Each slider contains a variable number of slides, and a pair of prev/next buttons to navigate sequentially through its respective slides.
Here is the markup for a typical slider:
<section class="foo">
<button class="prev"></button>
<ul class="container slider">
<li class="slide" id="a01"></li>
<li class="slide" id="a02"></li>
<li class="slide" id="a03"></li>
</ul>
<button class="next"></button>
</section>
Each slider should know the index of the slide it is currently showing. This leads me to believe that on page load, I should loop through all $('.slider') elements and instantiate an object for each. How do I write the class that defines the slider? It should have a property that contains the index of the current slide being shown, and a method that increments or decrements that property depending on whether the user clicked 'next' or 'prev'. I've come as far as this:
var slider = function () {
this.pager = 0;
this.incrementPager = function () {
console.log(this.pager++);
};
};
$(function () {
$('.prev, .next').click(slider);
});
... But my code doesn't do much :)
Here's how to make a jQuery plugin, which I think is a better way since you're using jQuery, which is not really meant for Class based OO.
$.fn.slider = function() {
$(this).each(function() {
var wrapper = $(this);
var index = 0;
var listItems = wrapper.find('.slide');
wrapper.find('.prev').click(function(){
if (index > 0) {
$(listItems[index]).removeClass('active');
index--;
$(listItems[index]).addClass('active');
}
});
wrapper.find('.next').click(function(){
if (index < listItems.length - 1) {
$(listItems[index]).removeClass('active');
index++;
$(listItems[index]).addClass('active');
}
});
});
};
And you could use it like
$('section').slider();
Working Example http://jsfiddle.net/MR8wE/
If you really want some OO in there you could do the following (but I think it goes against how jQuery works).
/**
* Adds behavior to the HTML for a slider
*/
function Slider(wrapper) {
var me = this;
me.wrapper = $(wrapper);
me.index = 0;
me.listItems = wrapper.find('.slide');
wrapper.find('.prev').click(function(){
me.prev();
});
wrapper.find('.next').click(function(){
me.next();
});
}
Slider.prototype.next = function() {
this.go(1;)
}
Slider.prototype.previous = function() {
this.go(-1);
}
Slider.prototype.go = function(steps) {
var oldIndex = this.index;
var newIndex = oldIndex + steps
if (newIndex >= 0 && newIndex < this.listItems.length ) {
$(this.listItems[oldIndex]).removeClass('active');
$(listItems[new]).addClass('active');
this.index = newIndex;
}
}
Then you would use it like
var sliders = [];
$('section').each(function(){
sliders.push(new Slider(this));
});
// Control the slider without user intervention
sliders[0].next();
sliders[1].go(2);
Example http://jsfiddle.net/MR8wE/2/
In response to the question in the comments:
function Slider(elm)
{
this.domElement = elm;
this.pager = 0;
}
Slider.prototype.incrementPager = function()
{
this.pager++;
};//all instances share this method ==> only 1 function object in mem.
$(function()
{
var objectCollection = (function(elements)
{
var toReturn = [];
var scanElementsFunction = function()
{//declared in this scope, to have access to elements var
'use strict';//avoid setting globals
if (this.allElems === undefined)
{
this.allElems = elements;
}
return this.allElems;
};
elements.each(function(idx,el)
{
toReturn[idx] = new Slider(el);//<-- pass DOMElement to constructor
toReturn[idx].getAll = scanElementsFunction;//<-- reference, no new function object
});
return toReturn;
}($('.prev, .next')));//this scope preserves the elements returned by jQuery selector
console.log(objectCollection);
});
There's nothing really useful in there, but I tried to incorporate as much tricks and tips while keeping the snippet as short as possible. If some of the code is unclear, let me know and I'll provide some more explanation (which might take an hour or two, 'cause I'm going to grab a bite now :))
The following approach uses the more formal constructor function and prototype which keeps it quite lightweight rather than stacking enclosures. The constructor is...
function Slider(slides, transition) {
// Keeps a reference to the current slide index
this._current = 0;
// An array of slides
this._slides = slides;
// A transition function
this._transition = transition;
}
It accepts an array of slides and a function which will be given two slides when we transition between them. This means we keep control of our transition effect by externalizing it. It is also framework agnostic and has no dependencies to jQuery or any other framework. The constructor itself doesn't do much. The following method is our meat...
// The function that swaps slides
Slider.prototype.goto = function(i) {
// Do a bit of sense checking
if(i > this._slides.length || i < 0)
throw new Error("Slide does not exist");
// Swap the slides by passing them to the transition function
var currentSlide = this._slides[this._current];
var nextSlide = this._slides[i];
this._transition(currentSlide, nextSlide);
// Update the current index
this._current = i;
};
It takes the new index for a slide and passes the old and the new slide to the transition function. It then updates the index it uses for tracking the current slide. We then want to implement a rotating previous and next function so the following methods describe how we can do that using modulus, note we have to add the length of the slides because negative modulus does not work how we want it to for this function.
// Calculate the next index as a rotating index
Slider.prototype.getNextIndex = function() {
return (this._current + 1) % this._slides.length;
};
// Calculate the previous index as a rotating index
Slider.prototype.getPrevIndex = function() {
return (this._current + this._slides.length - 1) % this._slides.length;
};
Then we add some sugar...
// Sugar to go next and prev
Slider.prototype.next = function() {
this.goto(this.getNextIndex());
};
Slider.prototype.prev = function() {
this.goto(this.getPrevIndex());
};
You may have a problem with associating the prev and next buttons with their sliders. You can find them before and after the slider element or as I have done below have them contained in the slider element. To set up sliders using jQuery you could do the following...
$(".slider").each(function() {
var slider = new Slider($(this).find(".slide"), function(a, b) {
$(a).hide();
$(b).show();
});
$(this).data("slider", slider);
$(this).find(".prev").click(function() {
slider.prev();
});
$(this).find(".next").click(function() {
slider.next();
});
});
EDIT Here is it in action http://jsfiddle.net/w8u69/
And because the logic for transitioning is exposed you can quite easily add in transitioning effects without modifying the original Slider "class". http://jsfiddle.net/w8u69/1/
EDIT Just to show the power in this approach, without modifying the original slider "class" you can add in additional logic to automatically move between slides. You can do this with a decorator, or with inheritance, but this example shows how it can be done with composition. http://jsfiddle.net/w8u69/4/
One last thing and this is possibly the most important thing about the pure OO approach, by simply changing the integration code and keeping the OO "classes" untouched, we can reuse the logic we have written for the slider and plug it into a completely different framework. This fiddle shows it working with MooTools http://jsfiddle.net/w8u69/5/
I have this code which is supposed to fire on mouseover and it's counterpart to do the opposite on onmouseout:
colinc();
function colinc(){
var hexnum=number.toString(16);
var hexcolor="#"+hexnum+hexnum+hexnum;
document.getElementById("c"+x).style.backgroundColor=hexcolor;
number=number+8;
if(number<=184)
setTimeout(colinc,50);
}
The counter part only has the change of number = number-8; and number>=40;
The problem is i have multiple boxes that should light up with color change on mouseover and lightdown with mouseout. when i move slowly over my boxes(large in no.) then everything is ok but when i move quickly some boxes do not light down...it looks like the onmouseout doesn't happen if i pass very quickly.
Any help?
function flash(x){
number=0;
var cc = document.getElementById("c"+x);
var cs=document.defaultView.getComputedStyle(cc,null);
var bg=cs.getPropertyValue('background-color');
var str=""+bg;
var n=str.replace("rgb","");
n=n.replace("(","");
n=n.replace(")","");
var arr=n.split(",");
number=parseInt(arr[0]);
colinc();
function colinc(){
var hexnum=number.toString(16);
var hexcolor="#"+hexnum+hexnum+hexnum;
document.getElementById("c"+x).style.backgroundColor=hexcolor;
number=number+8;
if(number<=184)
setTimeout(colinc,50);
}
}
function flashe(x){
number=0;
var cc = document.getElementById("c"+x);
var cs=document.defaultView.getComputedStyle(cc,null);
var bg=cs.getPropertyValue('background-color');
var str=""+bg;
var n=str.replace("rgb","");
n=n.replace("(","");
n=n.replace(")","");
var arr=n.split(",");
number=parseInt(arr[0]);
colinc();
function colinc(){
var hexnum=number.toString(16);
var hexcolor="#"+hexnum+hexnum+hexnum;
document.getElementById("c"+x).style.backgroundColor=hexcolor;
number=number-8;
if(number>=40)
setTimeout(colinc,40);
}
}
This is my full js code
Check whether the events fire properly by logging them in the console:
function MouseOverHandler(event) {
console.log('mouseover');
}
function MouseOutHandler(event) {
console.log('mouseout');
}
Also do you ever halt the execution of either handlers when the opposite event happens. This would be done via getting the timeout id and canceling it.
var mouseOverTimeout, mouseOutTimeout;
function colinc(){
clearTimeout(mouseOutTimeout);
mouseOverTimeout = setTimeout(colinc,50);
}
function MouseOutHandler(event) {
clearTimeout(mouseOverTimeout);
mouseOutTimeout = setTimeout(MouseOutHandler,50);
}
In your code:
> function colinc(){
>
> var hexnum=number.toString(16);
The identifier number hasn't be declared or initialised, so you get a reference error and the script fails. Before the above line, you should probably add:
var number = 0;
or give number some other value.
> var hexcolor="#"+hexnum+hexnum+hexnum;
> document.getElementById("c"+x).style.backgroundColor=hexcolor;
> number=number+8;
> if(number<=184)
> setTimeout(colinc,50);
But here you need access to a global number, so you can keep a reference in a closure or make number global. If you're going to do that, give it a better name, like *colnic_counter* or something that is unlikely to clash with some other global.
> }
Something like:
var colinc = (function() {
var num = 0;
return function() {
var hexnum = num.toString(16);
var hexcolor = "#" + hexnum + hexnum + hexnum;
// document.getElementById("c"+x).style.backgroundColor=hexcolor;
console.log(hexcolor);
num += 8;
if (num <= 184)
setTimeout(colinc,50);
}
}());
colinc();
Note that since a function expression is used to initialise the function, you have to call it afterward.
I have solved the problem of cleartimeout. I created two arrays to hold the current mouseover and mouseout setTimeout ids of every box according to their Id. Everytime a mouseout is called it first clears its corresponding mouseover from the array and same for mouseout.