tags:

views:

114

answers:

1
<input type="text" id="sShState" />
$('#sShState').liveSearch(); // A plug-in
// inside plug-in:
$this = $(this);

// On focus I add a dropdown box and add li's;

var obj = '<ul id="ddList"></ul>';
$this.after(obj);
$this.next('ul').html(li's);

$('#ddList').live('mouseenter', function(){
    var $li = $this.next('ul').children('li');
    $li.removeClass('hoverLi');
    $li.hover(function(e){
        $li.filter('[last]').removeAttr('last');
        $(this).addClass('hoverLi');
    },function() {
        $li.filter('.hoverLi').attr('last', true);
        $li.filter('.hoverLi').removeClass('hoverLi');
    });

    $li.click(function(){
        selectLi($(this));
        removeList ();
    });
});

In Chrome it is very very fast!!

But in Firefox when the mouse enters for the first time over the ulbox it takes between 1-2 sec until it starts to execute the code.

Even in Internet Explorer 7 it works fine. The hovered li remains a little behind, but it starts executing immediately when the mouse enter the ul box.

+2  A: 

You seem to have event assignment code inside of another event. So whenever the 'mouseenter' event takes place it is re-assigning the 'hover' and 'click' events. You should attach those events once outside of the live() function.

I don't know your page structure, so this may not be entirely correct. But it does illustrate the problem.

$('#ddList').live('mouseenter', function(){ 
    var $li = $this.next('ul').children('li'); 
    $li.removeClass('hoverLi');         
});

$('#ddList li').hover(function(e){  
      // $(this).filter('[last]').removeAttr('last');
      $(this).addClass('hoverLi');
},function() { 
      // $(this).filter('.hoverLi').attr('last', true);
      $(this).filter('.hoverLi').removeClass('hoverLi');
});

$('#ddList li').click(function(){
      selectLi($(this));  removeList ();      
});

I'm not entirely sure what's going on in your code, but if your intention was to make sure that events get attached to dynamically created 'li' elements, then you would need to use .live() like you did for 'mouseenter'.

$('#ddList li').live('mouseover', function() {...

$('#ddList li').live('mouseout', function() {...

$('#ddList li').live('click', function() {...

EDIT: Explanation of click() vs live()

If I have a <div id='mydiv'></div> in HTML, then all I need to do is assign the following to attach a click event:

$('#mydiv').click(function() {
    // whatever I want to do on click
});

But if the div is being dynamically added to the DOM, then I can use live() instead, and jQuery will automatically assign an event whenever I dynamically add the element.

$('#mydiv').live('click', function() {
    // whatever I want to do on click
    // jQuery takes care of assigning it to mydiv when dynamically added to DOM
});
patrick dw
But why it is so fast in Chrome and even IE7 and so slow in FF ?
Good question. I don't know. Maybe binding events to elements is simply slower in FF. Chrome has a wicked fast javascript engine, so that helps. Ultimately, you want to form your code properly. Repeatedly binding superfluous events on the fly is not the way to go. Fix it up and see how it works in FF.
patrick dw
the li's are created dynamically so I can't traversse the dom and use live(). I don't think that I can use $('#ddList li').live(). I remember that in documentation it says that we should use live immediatlly after we select the obj () it doesn't support DOM traversing. Did I understood right?
live() is specifically meant for elements that are created dynamically. Say if I have a `<div id='mydiv'>` in my HTML that should get a click event, I simply call `$('#mydiv').click(function...`. But if my `div` is being created dynamically, then I would use `$('#mydiv').live('click', function...` instead. When I use live(), jQuery waits for me to create the `div` dynamically, and assigns the click event for me. It's just automatic. Woo hoo!!
patrick dw
And I think that live() doesn't support hover either. Although I think I could use mouseenter and mouseleave. the problem was that I didn't want to give to li's a class and then when mouse enters li to change the class to something else. I'll try to give a name to li's and to reference the li's by name when I use live(). let's see if it works.
You are correct about 'hover'. You will need two calls to live, using 'mouseover' and 'mouseout'.
patrick dw
From the looks of your code, you were adding a class on hover anyway. I'm not still not entirely sure what is going on in your code, but if the solution requires adding and removing a class, that is a trivial task for jQuery.
patrick dw
Yes, you have right. But I just wanted to do it with out changing clases.And I was just curious why it's much, mu<h, much slower in FF.But definitely it is not a good ideea to put an event inside other event. Thank you very much for your help Patrick.
Different browsers react differently to unusual situations. It may just get confused when assigning an event that already exists. Generally FireFox is pretty fast, so I'm betting that it's simply not optimized to deal with that situation. *If you found this answer helpful, please consider checking the checkbox next to it.*
patrick dw
JQuery 1.4.1 added support for .live(“hover”). See http://jquery14.com/day-12/jquery-141-released
Peter Olsson
I used only mouse enter (in this way I don't need to asign an attr of last, wich has to remain hovered). $('li[name=liOpt]').live('mouseenter', function(){ //console.log($(this)); $this.next('ul').children('li').filter('.hoverLi').removeClass('hoverLi'); $(this).addClass('hoverLi'); });
Of course now the speed is much better in FF also. Although it is not as fast as it is in Chrome. And now in FF is a little bit faster than IE7.
@Peter - I thought I had remembered that, but when I tried it with 1.4.1, it called the mouseenter event on mouseenter and mouseleave (in webkit). I'll have to try it again.
patrick dw
@silversky - I haven't used FF that much on my Mac. Only for testing. The javascript speed hasn't impressed me. I can only imagine there will be future optimizations.
patrick dw