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

发布于 2024-11-30 04:39:31 字数 1209 浏览 1 评论 0原文

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

我可以正常工作,但我注意到当用户将鼠标悬停在给定的 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>

I would like to display the results of an AJAX call in a div when the user hovers over it (i.e. replace the div contents with the results of the AJAX call). The basic functionality is to replace a dot on the page with a circle that contains content from the server when the user hovers over the dot, and show the dot again when they stop hovering. There may be many dots on the page, each with different circle content on hover.

I have it working, but I notice that the AJAX call is getting repeatedly called while the user is hovering over the given div. How can I prevent repeated calls?

I have tried various usages of .one and .unbind('mouseenter', 'mouseleave') but haven't gotten it to work right yet.

Here's what I have right now (the hover behavior works right for the user but causes repeated calls to the backend).

<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>

and the script:

<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>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

帅冕 2024-12-07 04:39:31

为什么不直接使用像 var ajaxed = false 这样的布尔标志,并在请求完成一次后将其切换为 true?然后只需将您的悬停操作包装在 ajaxed 检查中即可。

Why not just have a boolean flag like var ajaxed = false and switch it to true after the request is completed once? Then just wrap your hover action in a check for ajaxed.

愿得七秒忆 2024-12-07 04:39:31

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

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

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

You should consider using mouseover instead of hover. You could do some actions when it's moused over, such as unbinding it from the action. And you could bind it again on a mouseout.

The idea is to unbind the mouseover action when the mouseover function is called. This removes the mouseover function from the element that was hovered. I didn't test this...I apologize if it isn't exactly correct.

$(ele).mouseover(function() {
   $(this).unbind('mouseover');
});
≈。彩虹 2024-12-07 04:39:31

根据您在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>

Based on your response to my question in the comment to your OP, I would adjust your entire sample as posted below (untested). The general idea is to do nothing if the ajax is awaiting response (try to avoid race condition), to get content and use it if it hasn't been flagged as having already been done, or just adjust the showing/hiding. Some adjustment for your preferences and integration may be necessary.

<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>
若沐 2024-12-07 04:39:31

动态添加加载的属性是我发现的最好的。

<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')

adding a loaded attribute on the fly is the best I found.

<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>

note: add and removing classes (previously defined in your CSS) is faster. example: $(obj).removeClass('invisible').addClass('inlineBlock')

旧情别恋 2024-12-07 04:39:31

使用 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>

use 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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文