开发者

jquery hover() mouseOut event not firing when mouse is moved quickly over link

I have simple link list and when you hover over it it appends a div (loading data in this div from XML) and on hover out it removes the div, but it only happens when mouse moves slowly over the links as soon as mouse moves more fast then usual over the links then it doesn't remove the div which means mouseout event was not fired

Move your mouse aggressively on first two links then you can see that div some times doesn't hide

Here is link to my demo http://ukcatonline.com/template/

Here is my code:

$(document).ready(function () { 

//vertical navigat开发者_C百科ion js
$(".mainnav_v a").hover(
    function (e) {
        $this = $(this)
        $this.stop().animate({  paddingLeft : '16px'}, 300);

        var brand ="";
        var category="designer_frames";
        $this.each(function() 
        {
            var title = this.title;
            if ($this.is('a') && $this.attr('title') != '' && $this.attr('id')==category)
            {  
                brand= this.title;

                $.ajax({
                    type: "GET",
                    url: "xml/peek_menu.xml",
                    //ie bug : it send wrong datatype on localmachine
                    dataType: ($.browser.msie) ? "text" : "xml",
                    success: function(data) {
                        var xml;
                         if (typeof data == "string") {
                           xml = new ActiveXObject("Microsoft.XMLDOM");
                           xml.async = false;
                           xml.loadXML(data);
                         } else {
                           xml = data;
                         }
                        //could have used $(xml).find(category).each(function() but jquery is intelligent enough to know wat element is currently selected
                        $(category, xml).each(
                            function(){
                                $(brand,this).each(
                                    function(){
                                        var title = $(this).attr('title');
                                        var imgurl = $(this).attr('imgurl');
                                        var description = $(this).find('description').text();
                                        var feature1 = $(this).find('feature1').text();
                                        var feature2 = $(this).find('feature2').text();
                                        var feature3 = $(this).find('feature3').text();
                                        var feature4 = $(this).find('feature4').text();

                                        var html =  '<div id="peek_container"><img src="' + imgurl + '" alt="" /><br /><br /><h1>'+title+'</h1><br />';
                                        html += '<p>' + description + '</p><br />';
                                        html += '<ul><li>'+feature1+'</li><li>'+feature2+'</li><li>'+feature3+'</li><li>'+feature4+'</li></ul><br /></div>';
                                        $this.parent().append(html);
                                    }
                                );
                            }
                        );
                    }
                }
                );

            }
        });

    },
    function (e) {
        $this = $(this);
        $this.stop().animate({  paddingLeft : '6px' }, 300);
        $this.siblings().remove();
    }
);});

Here is my HTML:

<ul class="mainnav_v">
  <li><a href="#url" class="peek" title="Boss" id="designer_frames">Boss</a></li>
  <li><a href="#url" title="Burberry" id="designer_frames">Burberry</a></li>
  <li><a href="#url" title="Bvlgari" id="designer_frames">Bvlgari</a></li>
  <li><a href="#url">Chanel</a></li>
  <li><a href="#url">Diesel</a></li>
  <li><a href="#url">Dior</a></li>


I am not 100% sure but my gut feeling is, the function call to get the panel via ajax should be a callback of the hover animate function.

The way it is now, the hover animate is 'independent' of the ajax call.

I've not tried this so I might be wrong. :P


Let us examine an offending order of operations:

  • Mouse over - Start Ajax Call
  • Mouse out - remove siblings
  • ajax success - append div.

Add in the fact that you aren't using var $this to declare $this - therefore it is global, the $this in the ajax call could be getting overwritten.

You should probably change your function to create and append the <div> before the ajax call, and then append to it later (added comments):

$(document).ready(function () { 
  //vertical navigation js
  $(".mainnav_v a").hover(function (e) {
    // be sure to SCOPE your $this, so that the other function can't overwrite it
    var $this = $(this)
    $this.stop().animate({  paddingLeft : '16px'}, 300);
    var brand ="";
    var category="designer_frames";
    $this.each(function() {
      var title = this.title;
      if ($this.is('a') && $this.attr('title') != '' && $this.attr('id')==category)
      {  
        brand= this.title;
        // create div BEFORE ajax call, and append it to dom in a hidden state
        var $results = $("<div id='peek_container'/>").hide();
        $this.parent().append($results);
        $.ajax({
          type: "GET",
          url: "xml/peek_menu.xml",
          //ie bug : it send wrong datatype on localmachine
          dataType: ($.browser.msie) ? "text" : "xml",
          success: function(data) {
            var xml;
            if (typeof data == "string") {
              xml = new ActiveXObject("Microsoft.XMLDOM");
              xml.async = false;
              xml.loadXML(data);
            } else {
              xml = data;
            }
            $(category, xml).each(function(){
              $(brand,this).each(function(){
                var title = $(this).attr('title');
                var imgurl = $(this).attr('imgurl');
                var description = $(this).find('description').text();
                var feature1 = $(this).find('feature1').text();
                var feature2 = $(this).find('feature2').text();
                var feature3 = $(this).find('feature3').text();
                var feature4 = $(this).find('feature4').text();

                var html =  '<img src="' + imgurl + '" alt="" /><br /><br /><h1>'+title+'</h1><br />';
                html += '<p>' + description + '</p><br />';
                html += '<ul><li>'+feature1+'</li><li>'+feature2+'</li><li>'+feature3+'</li><li>'+feature4+'</li></ul><br />';
                // set the html of the results object we made.
                $results.show().html(html);
              });
            });
          }
        });
      }
    });
  },
  function (e) {
    var $this = $(this);
    $this.stop().animate({  paddingLeft : '6px'     }, 300);
    $this.siblings().remove();
  });
});


Using console.log() or some other logging method you should be able to determine if the mouseout is firing before the mouseover is finished adding content, or if there is another problem.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜