tags:

views:

75

answers:

4

I want to alert something if the user's mouse has left TWO html elements (a textfield as well as a span block). How do I say the AND in jquery, in vain I tried something like this:

if ($('textarea.commentField') && $('span.loginPrompt')).mouseout(function() {
     alert('something');
});
+1  A: 

This might help:

$('textarea.commentField, span.loginPrompt').mouseout(function() {
     alert('something');
});
Floyd Pink
That would mean if it leaves either one, it would alert that. So you'd probably get two.
Mark Snidovich
This will only attach it to a textarea with the class commentField INSIDE a span with the class loginPrompt.
Bennor McCarthy
Actually, this wouldn't do much, since span.loginPrompt is used as "context" for the selector. the comma needs to be within the single quotes.
Marko
@Marko, You're right... thanks for pointing that out... Editing to correct it to the way I meant it...
Floyd Pink
@Bennor McCarthy no, it would bind it to two separate elements (or as many as match the two selectors). Note how they are separately enclosed in quotes and have a comma between them. What you are saying would be $('span.loginPrompt textarea.commentField ')
Mark Snidovich
Bennor McCarthy
@Bennor, my apologies... I was just correcting my wrong answer. And yes, your original comment was spot on with the incorrect answer that I edited out as seen here - http://stackoverflow.com/posts/3723049/revisions
Floyd Pink
Not your fault mate, just the nature of the beast.
Bennor McCarthy
+3  A: 

If the span encloses the textfield, you will only need the handler on the span.

If you want to attach the same handler to two independent elements, use this:

$('textarea.commentField, span.loginPrompt').mouseout(...)
Bennor McCarthy
+6  A: 

You can't do this natively, as this will require some legwork.

Something like this would work, but there must be a better solution:

var state = {a:false,b:false};
$('.a').mouseenter(enterA);
$('.a').mouseout(exitA);
$('.b').mouseenter(enterB);
$('.b').mouseout(exitB);

function enterA(){ state.a = true }
function exitA(){ state.a = false }
function enterB(){ state.b = true }
function exitB(){ state.b = false }

And then if you have jQuery 1.4.2, you can bind multiple events, so add these after the first events.

$('.a,.b').mouseout(function(){ 
//we're outside of both blocks
if( !state.a && !state.b )
{
   //do something
}
});

This will then fire when you've left A or B, and you're also outside of the other one. I think this is what you meant.

Stefan Kendall
this is the only right answer, +1
Matt Briggs
There has to be a better way, though. Sanity dictates such :P.
Stefan Kendall
If one element is inside the other in your markup, then only the parent element needs the event. If you were attaching a mouseenter, you would need to attach it to the child.
Bennor McCarthy
What if they overlap, but aren't 100% contained? Consider two absolute positioned divs that interlock. I assume there's some crazy UI stuff going on here.
Stefan Kendall
If they're completely independent in the markup, then yeah you'd need the above code, but if you're overlapping two elements, why not just absolutely position one relative to (and inside) the other? It's hard to say without seeing the markup, but in general if it takes nasty workarounds to do what you're trying to do, you're probably doing it the hard way.
Bennor McCarthy
But yes, if A contains B, then only A needs to be considered, and then you only need to use $('.a').mouseout.
Stefan Kendall
@Bennor: Probably. You never know what kind of control someone has over markup, though, or the reasoning for such. The question seemed to imply that only using the container element wouldn't work, or at least that's the only way in which the question makes sense. $('.a').mouseout may very well be the only thing necessary.
Stefan Kendall
Yeah, fair call. I just assumed that because of the poor wording of the question, the obvious and simplest solution hadn't been tried. Without a good understanding of HTML, it's possible to overlook the fact that if a wraps b in the markup then even if part of b is rendered outside of a it's still considered to be in inside a as far as mouse events are concerned.
Bennor McCarthy
Gaaaaah. Where's the feedback from the OP?
Matt Ball
A: 

Building on the other answers, you could try

(function() {
  var inc = 0;
  var both = false;
  $('textarea.commentField, span.loginPrompt')
    .mouseover(function() {
      inc++;
      if(inc==2) { both = true; }
    })
    .mouseout(function() {
      inc--;
      if(inc == 0 && both) {
        both = false; 
        // do whatever else you wanted here
    });
})();

This differs in functionality from the other state-based answer, in that the do whatever bit will be triggered only when the mouse has been inside both the textarea and the span simultaneously. The both var tracks whether, at any time, both elements have had the mouse enter without leaving either.

It's wrapped in a function so the state vars don't pollute the exterior namespace

kibibu