jQuery: The Write Less, Do More JavaScript Library

mouse control issue within nested tags

View: New views
15 Messages — Rating Filter:   Alert me  

mouse control issue within nested tags

by jmatthews :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

This is related to an earlier post, but rather than address it is a
selecting issue, I am thinking it is an append issue.  I'd like
others' thoughts on this.

If you have:

<div id="mymouse">Hello</div>

You can control the innerHTML through Jquery mouseover(), etc.  Simple
enough.

If you have:

<div id="mymouse">Hello<div>Goodbye</div></div>

The mouseover, I believe, still on effects the Hello, recognizing it
is the innerHTML of the tag with the id="mymouse."

However, using the original example, if you APPEND like this:

<div id="mymouse">Hello</div>

....  and somewhere in your script, you append by:  $("#mymouse).append
("<div>Goodbye</div>")

The mouseover() to "mymouse" now controls the next div.

I think the append assumes all appended material is more innerHTML and
not necessarily new sections of a document.

Does anybody else agree and see this as a "not so proper" working of
the append() method?

(I have not tested the example I just wrote, but it is my observation
based on my application, which uses append() to add new document
sections.  In my application, I have been struggling with mouseover
being inherited by the appended sections.  I have tried to modify the
program to set particular mouseovers in the new HTML tags that are
part of the appended materials - like appending <div
onmouseover="mymouse2">Goodbye</div> - all to no avail.)




Re: mouse control issue within nested tags

by Karl Swedberg-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

It sounds like you want to use the .after() method rather than .append()

--Karl

____________
Karl Swedberg




On Oct 31, 2009, at 11:06 AM, jmatthews wrote:

This is related to an earlier post, but rather than address it is a
selecting issue, I am thinking it is an append issue.  I'd like
others' thoughts on this.

If you have:

<div id="mymouse">Hello</div>

You can control the innerHTML through Jquery mouseover(), etc.  Simple
enough.

If you have:

<div id="mymouse">Hello<div>Goodbye</div></div>

The mouseover, I believe, still on effects the Hello, recognizing it
is the innerHTML of the tag with the id="mymouse."

However, using the original example, if you APPEND like this:

<div id="mymouse">Hello</div>

....  and somewhere in your script, you append by:  $("#mymouse).append
("<div>Goodbye</div>")

The mouseover() to "mymouse" now controls the next div.

I think the append assumes all appended material is more innerHTML and
not necessarily new sections of a document.

Does anybody else agree and see this as a "not so proper" working of
the append() method?

(I have not tested the example I just wrote, but it is my observation
based on my application, which uses append() to add new document
sections.  In my application, I have been struggling with mouseover
being inherited by the appended sections.  I have tried to modify the
program to set particular mouseovers in the new HTML tags that are
part of the appended materials - like appending <div
onmouseover="mymouse2">Goodbye</div> - all to no avail.)





Re: mouse control issue within nested tags

by jmatthews :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I tried that, but successive appends wind up happening in reverse
order (i.e. ABCDE winds up EDCBA).  Plus, it makes my html tag listing
in firebug look like it has poor structure.  I want to see everything
I add as being children, and not siblings, of the innerHTML that
precedes it.

What I want is to make mouseover honor n instruction to exclude
children of selected elements.

Instead of $("#parent).mouseover(function()

I need.....

$("#parent {and not children of parent}).mouseover(function()

I don't know how to do this, but I think a filter might do it.  Going
to check on filter now.

If anyone knows the syntax, please post in case I can't find it.

Thanks.


Re: mouse control issue within nested tags

by jmatthews :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Nope.  I know what I want, but not what I'm doing.

What is the proper syntax to make the mouseover() below only take
effect on the parent BUT NOT ITS CHILDREN?

$(".House,.Senate,.Assembly").mouseover(function()


Re: Re: mouse control issue within nested tags

by Karl Swedberg-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Nov 1, 2009, at 1:33 AM, jmatthews wrote:

Nope.  I know what I want, but not what I'm doing.

What is the proper syntax to make the mouseover() below only take
effect on the parent BUT NOT ITS CHILDREN?

$(".House,.Senate,.Assembly").mouseover(function()


You're making it pretty difficult for people to help you. You've started a few threads asking the same basic question.

http://groups.google.com/group/jquery-en/browse_thread/thread/e86b4b62d0a86590/

And you have replied to earlier posts without providing any context for that reply.

Have you taken a look at the demo I put up on jsbin.com? 

http://jsbin.com/enero/edit

Doesn't that do what you want it to do? And if not, can you describe how it's different from what you want?

You're fighting against two principles: event bubbling and style cascading. You can limit the event to be triggered only on those top-level items, but if you're directly applying a style to those top-level items, the child elements are also going to receive the styles because of the cascade, unless their styles are explicitly set to something different. I already showed one way to get around the cascade problem in my jsbin demo. Here is a way to limit the triggering:

$(".House,.Senate,.Assembly").mouseover(function(event) {
  if (event.target == this) {
      // do something
  }
}).mouseout(function(event) {
  if (event.target == this) {
     // do something else
  }
});


--Karl

____________
Karl Swedberg
www.englishrules.com
www.learningjquery.com






Re: mouse control issue within nested tags

by jmatthews :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thanks, Karl.  I realize the problem I created with multiple threads.
The actual issue was changing as I was recognizing what was
happening.  I wanted people to know what subject I was on and the
original post was describing another topic.  I probably should not
have done that...

Anyway, I looked at your site and couldn't tell if it is what I need
to mimic.  It has an initial window that never returns again.  That
kind of threw me.

OK!!!!!  I see that you coded it.  Very nice job!

Okay, see how the members are firing their respective "House" or
"Senate?"  That's what I want to stop.

The members need their own class.  Let's say you mouse over a member.
I want it to turn red when you do.  If you mouse over House or Senate,
only House or Senate shou;d turn blue.  If you mouse of member, only
THAT member should turn red (not all members).  Further, members MUST
remain children of their respective house or senate.

Make sense?

Check out this article which describes the issue in terms of
referencing "relatedTarget" and "fromElement."
http://www.quirksmode.org/js/events_mouse.html

I am not sure how to implement it, but it sounds like what the article
covers includes the solution to the problem.

Thanks!


Re: mouse control issue within nested tags

by jmatthews :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Oh, and by the way, the reason for needing separate control for the
members (senators and representatives) is I want a click on any member
to take you (fly) to the office of that member on the Google Earth map
and zoom-in to it.

Just like when you click on the parent ("Senate" or "House").  If you
click on one of those, it will fly to that state, zoom in, and show
you a panorama of the whole state, with each members placemarks.

So, the member function I am trying to achieve will take you to just
that ONE member's office and, of course, the zoom will be closer to
the ground, where you can see streets, etc.

On Nov 1, 1:57 pm, jmatthews <jmatth...@...> wrote:

> Thanks, Karl.  I realize the problem I created with multiple threads.
> The actual issue was changing as I was recognizing what was
> happening.  I wanted people to know what subject I was on and the
> original post was describing another topic.  I probably should not
> have done that...
>
> Anyway, I looked at your site and couldn't tell if it is what I need
> to mimic.  It has an initial window that never returns again.  That
> kind of threw me.
>
> OK!!!!!  I see that you coded it.  Very nice job!
>
> Okay, see how the members are firing their respective "House" or
> "Senate?"  That's what I want to stop.
>
> The members need their own class.  Let's say you mouse over a member.
> I want it to turn red when you do.  If you mouse over House or Senate,
> only House or Senate shou;d turn blue.  If you mouse of member, only
> THAT member should turn red (not all members).  Further, members MUST
> remain children of their respective house or senate.
>
> Make sense?
>
> Check out this article which describes the issue in terms of
> referencing "relatedTarget" and "fromElement."http://www.quirksmode.org/js/events_mouse.html
>
> I am not sure how to implement it, but it sounds like what the article
> covers includes the solution to the problem.
>
> Thanks!

Re: mouse control issue within nested tags

by jmatthews :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

OK.  Sooooo.....  Close!  Even "done" if this is the best that can be
had.

You all were right about adding and removing classes.  You were just
suggesting they be added and removed in the wrong place.  The parent
class should be removed when the child element is entered.  Vice
Versa, when the child element is exited, the parent class should be
reset.

Only one problem which you can check in code below.

It works good if you move sort of slow or medium into the child div.
You can watch the parent class lose its features (be removed).  But,
working FROM BELOW the bottom border of the child div (which is also
the bottom border of the parent div), if you "zip" the mouse UPWARD
past the bottom border and onto the last "member", you will move too
fast for the class to be removed.  In other words, you zip right
through the "innerDiv" and right onto the "member."  There was not
enough time of presence in the innerDiv before heading into member to
cause a fire within innerDiv.  So, senate's class does not get
removed.

A dirty, little plug, which I included in a comment below in the
"member" mouseenter() below, is to ALSO turn off the class for
senate.  It's sort-of a "catch-all."

It will work, and it is tolerable.  One unfortunate effect is you can
see the senate flicker as you enter from the bottom border.  That VERY
FIRST, TEENY, TINY pixel at the edge is the "no-man's land" where
senate gets fired.  1 pixel up, and the next fire occurs to turn it
off.  Thus, the flicker effect.

Thank you all so much for working me through this.  Couldn't have done
it without you.

Here's the code:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/
jquery.min.js"></script>
<title>Sandbox</title>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<style type="text/css" media="screen">
body { background-color: #fff; font: 16px Helvetica, Arial; color:
#000; }

.senate,
.house {
  font-size:12px;
  margin-left:5px;
  padding:0;
  color: black;
  font-style: normal;
  cursor: default;
  text-decoration: none;
  border:1px solid black;
}

.highlight {
  color: blue;
}
.highlight * {
  color: black;
}

#innerDiv
{
        border:1px solid black;
}

.member
{
        /*border:1px solid black;*/
}
</style>

<script type="text/javascript">
$(function()
{
        $('.senate').mouseenter(function(event) {
                //console.log("Related target: "+event.relatedTarget.nodeName);
                //console.log("Current target: "+event.currentTarget.nodeName);
                $(this).addClass('highlight');
        }).mouseleave(function(event) {
                $(this).removeClass('highlight');
        });


        $('.member').mouseenter(function(event) {
                // The next comment line is the catch-all.
                // Uncomment this, and you will cure the problem
described above
                // of moving through the
                // innerDiv too quickly.
                //$(".senate").removeClass("highlight");

                $(this).addClass('highlight');
        }).mouseleave(function(event) {
                $(this).removeClass('highlight');
        });


        $('#innerDiv').mouseenter(function(event) {
                $(".senate").removeClass("highlight");
        }).mouseleave(function(event) {
                $(".senate").addClass("highlight");
        });
});
</script>

</head>

<body>
        <div id="senate" class="senate">Senate
                <div id="innerDiv">
                                <p id="s1" class="member">member</p>
                                <p id="s2" class="member">member</p>
                </div>
        </div>
</body>
</html>

Re: Re: mouse control issue within nested tags

by Karl Swedberg-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message



On Nov 1, 2009, at 2:57 PM, jmatthews wrote:

Okay, see how the members are firing their respective "House" or
"Senate?"  That's what I want to stop.

Hmm. No, I'm not seeing that.

The members need their own class.  Let's say you mouse over a member.
I want it to turn red when you do.  If you mouse over House or Senate,
only House or Senate shou;d turn blue.  If you mouse of member, only
THAT member should turn red (not all members).  Further, members MUST
remain children of their respective house or senate.

Make sense?

Yes, it's starting to make sense.

Check out this article which describes the issue in terms of
referencing "relatedTarget" and "fromElement."
http://www.quirksmode.org/js/events_mouse.html

yes, I've seen that article. I don't think it's necessary to refer to relatedTarget and fromElement. As I mentioned in my previous reply, you just need to use the event.target property.

Here is another demo:


Mousing over senate and house change those words to blue, and mousing over the members changes their respective words to red. Only the moused over senate or house changes to blue and only the moused over member changes to red.

--Karl



Re: mouse control issue within nested tags

by jmatthews :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Karl coded:

  $('.house, .senate').mouseover(function(event) {
    $(event.target).addClass('highlight');

  }).mouseout(function(event) {
    $(event.target).removeClass('highlight');
  });


I did not notice then in prior posts.  Guess I completely missed it.

What is target, and how does it differ from "this"?  It seems to work
as I was wanting- i.e. only the particular one you are on.  No
children to inherit the method.

Am I understanding correctly?


Re: mouse control issue within nested tags

by jmatthews :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Karl, I think I have finally snapped to what you advised.

You said:

You're fighting against two principles: event bubbling and style
cascading. You can limit the event to be triggered only on those top-
level items, but if you're directly applying a style to those top-
level items, the child elements are also going to receive the styles
because of the cascade, unless their styles are explicitly set to
something different.

So, I have to limit trigger to event.target PLUS I need to make sure
that each of my bottom elements do not inherit styles?

Now, I will work on this principle.  I suppose that means that I need
to counter every style attribute I give to the highlight,plus every
style of every parent or ascendant above.


Re: mouse control issue within nested tags

by jmatthews :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I'm going to have to sleep on this.  I am flustered.

I think adding a class like that actually creates a second class, and
that the second class is also inherited by children.  Here'e the
frustrating part:


When the sub-table opens up under House, it has a set of tree branches
on the left.  I refer to them as .dottedCheckBoxColumn because I
basically filled the cell with some dashes and pipes and reduced the
font to 3 pt to give a light, dashed appearance.

So, Senate is ABOVE dottedCheckBoxColumn.

Now, when I leave the font-size in Senate uncommented (set it to
12px), it changes the font-size on my dottedCheckBoxColumn and makes
those dashes and pipes full size.  Of course, this causes visual
havoc.  But curiously, the havoc only occurs when you mouseover
Senate.

Why would the Senate font-size be inherited by dottedCheckBoxColumn,
when the dottedCheckBoxColumn expressly sets the font-size at 3px?

I am surmising, at this point, that mousingover Senate ADDS a second
class to senate, which also designates a 12px font.  Now, I have two
classes in Senate, BOTH with 12px font-size.

The font-size of 3px in dottedCheckBox overrides the first coming from
Senate, but NOT the second.


.House,.Senate,.Assembly,.placemark
{
        font-size:12px;
        etc....
}


.chamberHighlight
{
        font-size:12px;
        color:blue;
        font-style:italic;
        /*text-decoration:underline;*/
        cursor:pointer;
        /*border-spacing:0;*/
}
.chamberHighlight *
{
        font-size:12px;
        color:black;
        font-style:normal;
        /*text-decoration:none;*/
        cursor:default;
        /*border-spacing:0;*/
}



.dottedCheckBoxColumn
{
        //  The column left of checkBox columns, which contains the tree of
dots.
        height=10px;
        width:7px;
        font-size:3px;
        line-height: 80%;
        vertical-align:top;
        border-spacing:0;
        /*border:1px solid black; */
}




$(".House,.Senate,.Assembly,.placemark").mouseenter(function(event)
{
    $(event.target).addClass('chamberHighlight');
}).mouseout(function(event)
{
    $(event.target).removeClass('chamberHighlight');
});




Re: mouse control issue within nested tags

by jmatthews :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Resolved!!!

I needed to clean up the class issue slightly.  The event issue came
down to Karl's ($event.target)issue PLUS USING MOUSEOVER AND NOT
MOUSEENTER.

The reference guide DOES describe it properly; I am just thick-headed,
I guess.  Mouseover will fire when entering over a child.  Mouseout
will not.

We had to use mouseover because mouseenter was operating on Senate but
not firing when entering Senate's descendant, placemark.

That's the first half.

The second half is the $(event.target).  The best way to describe this
is to say it means, "Whatever your mouse is on at the most inner
level.  You might be in library, in book, on page 23, and event.target
reports page 23 and not book or library.

So, we use $(event.target) to change style of the descendant, even
though it is encapsulated by the parent.  If the mouseover was on a
part of parent that did NOT contain child, parent is reported as
event.target.  If you are sitting on a descendant, descendant is
reported as event.target.

Click works the same.  If you don't want the click on a child to do
whatever a click on its parent would do, then, in the $(parent).click
(), test to be sure event.target!=this.  If it does not, do nothing
but return.

These are VERY IMPORTANT distinctions that should be known and
emphasized more than they are.

I hope I described them well, and I hope others have gained from
this.

Now, I get to move to the next level of functionality in my app.
Woohoo!

Thanks, everyone, and special thanks to Andrei and Karl for putting
real time into helping me sort this out.  Karl nailed it and gets the
trophy!

Re: mouse control issue within nested tags

by jmatthews :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Okay, now that, through event.target, I have trapped and deflected a
click in "senate" when the actual click was on the checkbox next to a
member, I want to determine the element from which it came and modify
it.  Specifically, I know it came from one of the checkboxes preceding
the many senate members.  I do not know WHICH one.

Also, I know it has an img src, and I want to redefine the image.
Toggle it it to a checked/unchecked box image.

How do I do this through event.target?

I am used to basing everything off of (this) and knowing the node
structure to traverse.  event.target is not the same, and it does not
allow the same methods.  Therefore, I need to get information out of
event.target which will let me find and select the element
from which it came.

Was it senator #32, 54, 7, or what?  That's the question.

Re: mouse control issue within nested tags

by jmatthews :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hah!  Got it!  Just getting used to mixing languages.  Kept looking
for the solution in Jquery.  It was just plain HTML Dom.