/    Sign up×
Community /Pin to ProfileBookmark

Newbie: Mouse events don’t work on jQuery elements

Let me say right off, I am a newbie. So apologies if this issue has been addressed before. I tried seraching for an answer, but I am not even sure of which terms to search for.

I am totally new to Javascript, and I was just experimenting with trying to create a drag and drop feature. I am using JQuery. I created a <span> and then had a javascript function create several DIV’s in the span, stacked above each other. Each DIV contains a small image.

The idea was for the user to drag on one of the DIV’s and change it’s position in the stack – kind of like the “layers” palatte in Photoshop, where you can drag a layer up or down to determine it’s position in the stack.

How I tried to do it was to fill an array with some HTML snippets containing the DIV and IMG tags, and then pass that array to a function that first wipes out any DIV and IMG tags on the page, and then inserts the HTML snippets into the SPAN in the body.

From that point, it is all about mouse events – I see if the user creates a mousedown event on one of the DIVs and then check to see if that is followed by a mousemove event. If the user drags the DIV, the order of the elements in the array is changed to reflect the new order of the stack.

Once this has been done, the same function is called to wipe out the existing HTML, and create new HTML based on the new order of HTML elements in the array – just the way it was done when the page loaded.

The problem is, although the mouse events work fine on the initially created DIV’s, once a drag happens, and the old HTML is wiped out to be replaced by the new HTML, none of the DIVs respond to mouse events. The page is dead.

While debugging, I had placed a lot of “alert” statements in the code to display the HTML before and after a drag, and it all seems correctly formatted. It just seems that the DIV’s that are created the second time don’t respond.

One test I did do was to comment out the two lines at the top of the function that delete the old DIV and IMG tags before inserting the new. When I did this, the old code remained, with the new code prepended onto it. The old DIVs still responded to the mouse events, while the new DIVs above would not. Even though they are identical.

I am sure this is a newbie dumb error, but I am having trouble tracking down the cause of the problem. The stripped-down code is below, in order to show the problem. My apologies if I have provided too much – I don’t consider myself knowledgeable enough yet to know what to show and what to leave out. I also notice that my indents in the code below went a little out of whack in this post, even though they are aligned well in Dreamweaver. Any help would be appreciated. And please don’t laugh at my coding practices or skills, as I have neither yet!?

[CODE]<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN”
“http://www.w3.org/TR/html4/loose.dtd”>
<html>
<head>
<title>Example Problem</title>
<meta http-equiv=”Content-Type” content=”text/html; charset=iso-8859-1″>
<script type=”text/javascript” src=”salvation_files/jquery.js”></script>
<script type=”text/javascript”>
$(document).ready(function()
{
function orderimages(images)
{
$(‘img’).remove();//remove all IMG tags from the page
$(‘div’).remove();//removes all the DIV tags from the page
for(var i=0;i<(images.length);i++)
{
$(‘#idex’).prepend(“<div id=’place_”+i+”‘ class=’lister’><div class=’biddy’>”+images[i]+”</div></div>”);//inserts HTML so each element of the images array, surrounded by two DIV’s, into the Span tag in the <body>
}
$(‘div.lister’).unbind(‘mousemove’);//stops a mousemove event over all DIV’s with class lister – effectively ending the “dragging” once an item has been dragged
};
var first='<img id=”first” src=”thumbs/image01.png” >’;//assigns a variable to the first of three images (each image should be 100px x 100px in size BTW)
var second='<img id=”second” src=”thumbs/image02.png” >’;//assigns a variable to the second of three images
var third='<img id=”third” src=”thumbs/image03.png” >’;//assigns a variable to the third of three images
var images=[first,second,third];//load the array with the three images
orderimages(images);//run the function above
$(‘div.lister’).mouseover(function()//change the background color of the DIV ifthere is a mouseover
{
$(this).css(‘background-color’,’#000000′);
})
$(‘div.lister’).mouseout(function()//set the color back on a mouseout
{
$(this).css(‘background-color’,’#00FFFF’);
})

$(‘div.lister’).mousedown(function(evt)//triggers on a mousedown
{ evt.preventDefault();//prevent any normal mousedown default action
var yPos=evt.pageY; //Get the Y position of the mouse
$(‘div.lister’).mousemove(function(evt)//triggers if the mouse moves while down
{
var yPosn=evt.pageY; //Get the Y position of the mouse as it moves
if(yPosn>(yPos+20)) ///checks to see if the mouse has moved down the page at least 20 pixels
{
if($(this).attr(‘id’)!=’place_0′) //checks to make sure the DIV that is being dragged is not already in the bottom position
{
var imageid=parseInt($(this).attr(‘id’).slice(-1)); //Get the ID number of the DIV which corresponds to the element number in the array
var temp1=images[imageid]; //set a temp variable to hold a copy of the array element at this number
var temp2=images[imageid-1]; //set a temp variable to hold a copy of the array element just before the one above
images.splice(imageid-1,1,temp1); //this line and the next basically just swap the two elements in the array
images.splice(imageid,1,temp2);
orderimages(images); //now call the function again which will wipe out all the DIV and IMG tags and re-create new HTML based on the new array order
}
}
if(yPosn<(yPos-20)) //checks to see if the mouse has moved up the page at least 20 pixels
{ var ender=images.length;
if($(this).attr(‘id’)!=’place_’+(ender-1)) //checks to make sure the DIV that is beuing dragged is not already in the top position
{
var imageid=parseInt($(this).attr(‘id’).slice(-1)); //Get the ID number of the DIV which corresponds to the element number in the array
var temp1=images[imageid]; //set a temp variable to hold a copy of the array element at this number
var temp2=images[imageid+1]; //set a temp variable to hold a copy of the array element just after the one above
images.splice(imageid+1,1,temp1); //this line and the next basically just swap the two elements in the array
images.splice(imageid,1,temp2);
orderimages(images); //now call the function again which will wipe out all the DIV and IMG tags and re-create new HTML based on the new array order
}
}
})//end of mousemove
})//end of mouseover
});//end of doc ready
</script>
<style type=”text/css”>
<!–
#idex {
background-color: #CCCCCC;
border: thin solid #000000;
position: absolute;
overflow: hidden;
height: 500px;
width: 250px;
left: 20px;
top: 20px;
}
.lister {
background-color: #00FFFF;
border: medium solid #0000FF;
overflow: hidden;
position: relative;
width: 244px;
height: 100px;
left: 0px;
}
.biddy {
background-color: red;
border: thin solid #FF33FF;
overflow: hidden;
position: relative;
height: 100px;
width: 100px;
left: 0px;
}
–>
</style>
</head>
<body>
<span id=”idex”></span>
</span>
</body>
</html>[/CODE]

to post a comment
JavaScript

7 Comments(s)

Copy linkTweet thisAlerts:
@FangJan 19.2009 — I created a <span> and then had a javascript function create several DIV's in the span, stacked above each other. Each DIV contains a small image.[/QUOTE]
This is invalid code. Browsers don't like DOM referencing on invalid html.
The problem is, although the mouse events work fine on the initially created DIV's, once a drag happens, and the old HTML is wiped out to be replaced by the new HTML, none of the DIVs respond to mouse events.[/QUOTE]Are the events re-created in the new elements?
Copy linkTweet thisAlerts:
@bossmossauthorJan 19.2009 — Thanks for the reply. And - again - pardon my ignorance. When you say "are the events re-created in the new elements" my knee-jerk response is Yes. The events are set in the code to occur whenever any DIV with the appropriate class is acted upon by the mouse. The first run of the function creates DIVs which respond as expected. The second run of the function wipes out the first DIVs but creates and inserts identically-formatted DIVs that should respond to the same events in te same way as the first round of created DIVs did. Is that what you meant?

Your first comment interests me the most. You say it is invalid code to have Javascript insert DIVs into a SPAN? Although it wouldn't explain why the first round of DIVs works when the second doesn't, this seems like it could be the culprit. And I was looking for exactly this kind of thing my various Javascript books, but couldn't find anything. If I may ask, why is it invalid? Is it that all HTML containers like DIV and SPAN have to be created in the HTML code rather than Javascript? In the case of my larger application for which this was a test, images (and their surrounding DIVs) need to be added or removed as needed. What process should I be using to do this?

Any and all help is appreciated.
Copy linkTweet thisAlerts:
@FangJan 19.2009 — The first run of the function creates DIVs which respond as expected. The second run of the function wipes out the first DIVs but creates and inserts identically-formatted DIVs that should respond to the same events in te same way as the first round of created DIVs did. Is that what you meant?[/QUOTE]So the JavaScript is is run again on the new elements?

A block element, div, may not be the child of an inline element, span.

How the html is created is not important, but creating valid html is.
Copy linkTweet thisAlerts:
@bossmossauthorJan 19.2009 — Thanks again. Yes, the Javascript is run again on the new elements. At least - to clarify - I try moving the mouse over the new elements which [I]should[/I] trigger the mouseover code. I also tried swapping the <span> tag for a <div> tag which (I believe) is not an inline element. I still am not sure if it is valid to have Javascript insert a <div> inside another <div>, but the same result still occurs.

I start by running a function to create child DIVS of class "lister" inside the main DIV. I assign a mouseover event to all DIVs of class "lister." Slide my mouse over the DIVs and they react - it works. Then I run the function again, which deletes all those child DIVs and then re-creates them again in the main DIV. These new child DIVs are also created with class "lister" but now the mouseover events don't work on those new DIVs. It is the same function producing identical DIVs in the same location. But now the mouseover events which are supposed to fire when the mouse moves over the new DIVs won't work.

Is it possible the DOM doesn't "see" the new divs because, while they are clones of the originals (as far as the HTML goes), some internal pointer isn't being updated when the swap occurs??
Copy linkTweet thisAlerts:
@bossmossauthorJan 19.2009 — I realize the chunk of code I provided above is ugly. So I went about creating a stripped down piece of code to illustrate the problem better.

The code below uses a function to delete any DIVs of class "lister" from the page (and there are none to begin) and then creates three child DIVS of class "lister" inside of a main DIV, which is of class "holder".

There is a mouseover event attached to any DIVs of class "lister." When the page loads, if you move your mouse over the DIVs, you will see they react, as expected. There is also a click event that triggers whenever any DIV of class "lister" is clicked. This click event causes the function mentioned above to run again. When you click, all of the DIVs of class "lister" are deleted, and identical DIVs of class "lister" are created, exactly as they were the first time.

Except now if you move your mouse over these new DIVs, they do not react. Yet they are identical to the DIVs that did work.

Hopefully this code is easier to read and illustrates my problem better. You should be able to copy it whole and try it in your editor (except for the location of the jquery.js file would need updating.) I am testing this with Firefox, BTW. Don't know if that matters.

Any help is appreciated.

[CODE]<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Stripped Down</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<script type="text/javascript" src="salvation_files/jquery.js"></script>
<script type="text/javascript">
$(document).ready(function()
{
function createdivs()
{
$('div.holder div').remove();
for(var i=0;i<3;i++)
{
$('#idex').prepend("<div id='number_"+i+"' class='lister'></div>");
}
}
createdivs();
$('div.lister').mouseover(function()
{
$(this).css('background-color','#000000');
})
$('div.lister').mouseout(function()
{
$(this).css('background-color','#00FFFF');
})
$('div.lister').click(createdivs);
});
</script>
<style type="text/css">
<!--
#idex {
background-color: #CCCCCC;
border: thin solid #000000;
position: absolute;
overflow: hidden;
height: 500px;
width: 250px;
left: 20px;
top: 20px;
}
.lister {
background-color: #00FFFF;
border: medium solid #0000FF;
overflow: hidden;
position: relative;
width: 244px;
height: 100px;
left: 0px;
}
.holder {
left: 0px;
top: 0px;
}
-->
</style>
</head>

<body>
<div id="idex" class="holder"></div>
</body>
</html>
[/CODE]
Copy linkTweet thisAlerts:
@FangJan 20.2009 — Although the div's are recreated the events are not, only onload are the events created.

Move the event creation into the createdivs function. The onload is:$(document).ready(function()
{createdivs();
});

Why are the elements not hard coded in the html initially? Accessibility problem.

The mouseover functions can be achieved with css, no scripting required.

If this is intended to be a drag sort routine, then re-creating the elements is unnecessary.

Valid containers:

block within block

inline within block
Copy linkTweet thisAlerts:
@bossmossauthorJan 20.2009 — Fang - that was the problem. And thanks for hammering in the event re-creation issue. I wasn't sure what you meant, but now it is clear. Thanks for that lesson. None of the tutorials I have been reading explained that as clearly as you.

I only started learning Javascript last week, and I have a looooong way to go. Your help is appreciated.
×

Success!

Help @bossmoss spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 5.7,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @AriseFacilitySolutions09,
tipped: article
amount: 1000 SATS,

tipper: @Yussuf4331,
tipped: article
amount: 1000 SATS,

tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,
)...