1

当用户将鼠标悬停在 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>
4

5 回答 5

4

为什么不只是有一个布尔标志,var ajaxed = false并在请求完成一次后将其切换为 true?然后只需将悬停动作包装在检查中ajaxed

于 2011-08-17T13:27:49.450 回答
1

您应该考虑使用mouseover而不是悬停。您可以在鼠标悬停时执行一些操作,例如将其与操作解除绑定。你可以将它再次绑定到mouseout.

这个想法是在调用 mouseover 函数时取消绑定 mouseover 动作。这将从悬停的元素中删除鼠标悬停功能。我没有对此进行测试...如果它不完全正确,我深表歉意。

$(ele).mouseover(function() {
   $(this).unbind('mouseover');
});
于 2011-08-17T13:29:49.580 回答
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')

于 2011-08-17T14:45:12.670 回答
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>
于 2011-08-17T15:17:57.977 回答
0

使用 jQueryone('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>
于 2011-08-17T13:26:46.037 回答