views:

11270

answers:

11

On the front page of a site I am building, several <div>s use the CSS :hover property to add a border when the mouse is over them. One of the <div>s contains a <form> which, using jQuery, will keep the border if an input within it has focus. This works perfectly except that IE6 does not support :hover on any elements other than <a>s. So, for this browser only we are using jQuery to mimic css :hover using the $(#element).hover() method. The only problem is, now that jQuery handles both the form focus() and hover(), when an input has focus then the user moves the mouse in and out, the border goes away.

I was thinking we could use some kind of conditional to stop this behavior. For instance, if we tested on mouse out if any of the inputs had focus, we could stop the border from going away. AFAIK, there is no :focus selector in jQuery, so I'm not sure how to make this happen. Any ideas?

Thanks for your help.

+1  A: 

have you thought about using mouseOver and mouseOut to simulate this. Also look into mouseEnter and mouseLeave

mkoryak
That is essentially what I am doing with jQuery's hover. You supply two functions, one for mouse in and one for mouse out.
Bloudermilk
A: 

Keep track of both states (hovered, focused) as true/false flags, and whenever one changes, run a function that removes border if both are false, otherwise shows border.

So: onfocus sets focused = true, onblur sets focused = false. onmouseover sets hovered = true, onmouseout sets hovered = false. After each of these events run a function that adds/removes border.

Blixt
A: 

As far as I know, you can't ask the browser if any input on the screen has focus, you have to set up some sort of focus tracking.

I usually have a variable called "noFocus" and set it to true. Then I add a focus event to all inputs that makes noFocus false. Then I add a blur event to all inputs that set noFocus back to true.

I have a MooTools class that handles this quite easily, I'm sure you could create a jquery plugin to do the same.

Once that's created, you could do check noFocus before doing any border swapping.

rpflo
+1  A: 

I'm not entirely sure what you're after but this sounds like it can be achieved by storing the state of the input elements (or the div?) as a variable:

$('div').each(function(){

    var childInputHasFocus = false;

    $(this).hover(function(){
        if (childInputHasFocus) {
            // do something
        } else { }
    }, function() {
        if (childInputHasFocus) {
            // do something
        } else { }
    });

    $('input', this)
        .focus(function(){
            childInputHasFocus = true;
        })
        .blur(function(){
            childInputHasFocus = false;
        });
});
J-P
This is what I wound up doing, but I used an arbitrary CSS class rather than a global javascript variable.
Bloudermilk
A: 

There is no :focus, but there is :selected http://docs.jquery.com/Selectors/selected

but if you want to change how things look based on what is selected you should probably be working with the blur events.

http://docs.jquery.com/Events/blur

Chris Brandsma
A: 

What I wound up doing is creating an arbitrary class called .elementhasfocus which is added and removed within the jQuery focus() function. When the hover() function runs on mouse out, it checks for .elementhasfocus:

if(!$("#quotebox").is(".boxhasfocus")) $(this).removeClass("box_border");

So if it doesn't have that class (read: no elements within the div have focus) the border is removed. Otherwise, nothing happens.

Thanks for your input, everyone!

Bloudermilk
+3  A: 

CSS:

.focus {
border-color:red;
}

JQuery:

$(document).ready(function() {    

    $('input').blur(function(){
      $('input').removeClass("focus");
     })
             .focus(function() {  
              $(this).addClass("focus")
     });

});
Daniel Moura
A: 

An alternative to using classes to mark the state of an element is the internal data store functionality.

P.S.: You are able to store booleans and whatever you desire using the data() function. It's not just about strings :)

$("...").mouseover(function ()
{
    // store state on element
}).mouseout(function ()
{
    // remove stored state on element
});

And then it's just a matter of accessing the state of elements.

roosteronacid
+2  A: 

There is a plugin to check if an element is focused: http://plugins.jquery.com/project/focused

$('input').each(function(){
   if ($(this) == $.focused()) {
      $(this).addClass('focused');
   }
})
Murat Corlu
+13  A: 

Cletus posted an answer on this other question I thought was worth reposting, please upvote his original if you find it useful! Now onto the answer:

There is no native solution but yes there is a more elegant way you can do it:

jQuery.extend(jQuery.expr[':'], {
    focus: function(element) { 
        return element == document.activeElement; 
    }
});

You're defining a new selector. See Plugins/Authoring. Then you can do:

if ($("...").is(":focus")) {
  ...
}

or:

$("input:focus").doStuff();
gnarf
A: 

I posted an answer on the related question "Is there a ‘has focus’ in JavaScript (or jQuery)?".
I've enhanced cletus approach cited by gnarf.

luiggitama