如何在JQuery.hover()上只进行一次AJAX调用?

时间:2011-08-17 13:22:58

标签: jquery javascript-events jquery-hover

当用户将鼠标悬停在div上时,我想在div中显示AJAX调用的结果(即用AJAX调用的结果替换div内容)。基本功能是在用户将鼠标悬停在点上时,用包含服务器内容的圆圈替换页面上的点,并在停止悬停时再次显示点。页面上可能有许多点,每个点在悬停时都有不同的圆形内容。

我有它的工作,但我注意到当用户将鼠标悬停在给定的div上时,AJAX调用会被重复调用。如何防止重复通话?

我尝试了.one和.unbind('mouseenter','mouseleave')的各种用法,但还没有让它正常工作。

这就是我现在所拥有的(悬停行为适用于用户,但会导致重复调用后端)。

<div class="box1" s='<%=value1 %>' t='<%=value2 %>'>
   <div id="circle" style="display: none;">
   </div>
   <div class="dot" id="dot">
      <img src="orangeDot.png" />
   </div>
</div>

和脚本:

<script type='text/javascript'>
    $(document).ready(function () {
        $(".box1").hover(function () {
            var source = $(this).attr('s');
            var target = $(this).attr('t');
            $('#dot').attr("style", "display: none;");
            $('#circle').hide().load('/GetCircle?s=' + source + '&t=' + target).show();
        }, function () {
            $('#circle' + divid).attr("style", "display: none;");
            $('#dot' + divid).attr("style", "display: inline-block;");
        });
    });
</script>

5 个答案:

答案 0 :(得分:4)

为什么不只是有一个类似var ajaxed = false的布尔标志,并在请求完成一次后将其切换为true?然后将您的悬停操作包裹在ajaxed

的支票中

答案 1 :(得分:1)

您应该考虑使用mouseover而不是悬停。当它被鼠标悬停时你可以做一些动作,例如从动作中解除绑定。你可以在mouseout上再次绑定它。

想法是在调用鼠标悬停功能时取消绑定鼠标悬停操作。这将从悬停的元素中删除鼠标悬停功能。我没有对此进行测试...如果不完全正确我会道歉。

$(ele).mouseover(function() {
   $(this).unbind('mouseover');
});

答案 2 :(得分:1)

动态添加加载的属性是我找到的最好的。

<script type='text/javascript'>
    $(document).ready(function () {
        $(".box1").hover(function () {
            var source = $(this).attr('s');
            var target = $(this).attr('t');
            var $circle = $('#circle' + divid);
            $('#dot').attr("style", "display: none;");
            if ( $circle.data('loaded') == 'yes' ) {
                $circle.show();
            }
            else {
                $.get('/GetCircle', {s: source, t: target}, function (data) {
                    $circle.data('loaded', 'yes');
                    $circle.html(data); // note: "$circle.get(0).innerHTML = data" is faster
                    $circle.show(); // of course, the 3 methods can be chained 
                }};
            }, function () {
                $('#circle' + divid).hide(); // was ".attr("style", "display: none;");"
                $('#dot' + divid).attr("style", "display: inline-block;");
            }):
        });
    });
</script>

注意:添加和删除类(以前在CSS中定义)更快。示例:$(obj).removeClass('invisible')。addClass('inlineBlock')

答案 3 :(得分:1)

根据您对OP的评论中对我的问题的回答,我会调整您的整个样本,如下所示(未经测试)。一般的想法是,如果ajax正在等待响应(试图避免竞争条件),获取内容并使用它,如果它没有被标记为已经完成,或者只是调整显示/隐藏,则什么都不做。可能需要对您的偏好和整合进行一些调整。

<div class="box" data-s="<%=value1 %>" data-t="<%=value2 %>">
    <div class="circle" style="display: none;">
    </div>
    <div class="dot">
        <img src="orangeDot.png" alt="orange dot" />
    </div>
</div>

<script type='text/javascript'>
    $( function()
    {
        var IN_FLIGHT = 'requestinflight',
            RETRIEVED = 'contentretrieved';

        $( '.box' ).hover(
            function()
            {
                var $box, $circle, $dot;

                $box = $( this );

                if( ! $box.data( IN_FLIGHT ) )
                {
                    $dot = $box.find( '.dot' );
                    $circle = $box.find( '.circle' );

                    if( ! $box.data( RETRIEVED ) )
                    {
                        $box.data( IN_FLIGHT, true );
                        $.ajax( {
                            url: '/GetCircle',
                            data: {
                                s: $box.data( 's' ),
                                t: $box.data( 't' )
                            }
                            dataType: 'html',
                            success: function( html )
                            {
                                $box.data( RETRIEVED, true );
                                $circle.html( html ).show();
                                $dot.hide();
                            },
                            complete: function()
                            {
                                $box.data( IN_FLIGHT, false );
                            }
                        } );
                    }
                    else
                    {
                        $circle.show();
                        $dot.hide();
                    }
                }
            },
            function()
            {
                var $box = $( this );
                if( ! $box.data( IN_FLIGHT ) )
                {
                    $box.find( '.circle' ).hide();
                    $box.find( '.dot' ).show();
                }
            }
        );
    } );
</script>

答案 4 :(得分:0)

使用jQuery one('hover', function() {...});

http://api.jquery.com/one/

 <script type='text/javascript'>
        $(document).ready(function () {
            $(".box1").one('hover',function () {
                var source = $(this).attr('s');
                var target = $(this).attr('t');
                $('#dot').attr("style", "display: none;");
                $('#circle').hide().load('/GetCircle?s=' + source + '&t=' + target).show();
            }, function () {
                $('#circle' + divid).attr("style", "display: none;");
                $('#dot' + divid).attr("style", "display: inline-block;");
            });
        });
    </script>