Как мне сделать AJAX-вызов только один раз на JQuery.hover ()? - PullRequest
1 голос
/ 17 августа 2011

Я хотел бы отобразить результаты вызова AJAX в div, когда пользователь наводит на него курсор (то есть заменить содержимое div на результаты вызова AJAX).Основная функция заключается в замене точки на странице кружком, который содержит контент с сервера, когда пользователь наводит курсор на точку, и отображает точку снова, когда он прекращает зависание.На странице может быть много точек, каждая с разным содержимым круга при наведении.

У меня это работает, но я замечаю, что вызов AJAX неоднократно вызывается, пока пользователь наводит указатель мыши на данный элемент div.Как я могу предотвратить повторные звонки?

Я пробовал различные варианты использования .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 ]

4 голосов
/ 17 августа 2011

Почему бы просто не иметь логический флаг типа var ajaxed = false и переключить его в значение true после завершения запроса один раз? Затем просто оберните свое действие при наведении курсом на ajaxed.

1 голос
/ 17 августа 2011

На основании вашего ответа на мой вопрос в комментарии к вашему ОП, я бы скорректировал весь ваш образец, как указано ниже (не проверено).Основная идея заключается в том, чтобы ничего не делать, если 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>
1 голос
/ 17 августа 2011

добавление загруженного атрибута на лету - лучшее, что я нашел.

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

1 голос
/ 17 августа 2011

Вы должны рассмотреть возможность использования mouseover вместо наведения. Вы можете выполнить некоторые действия, когда они наведены, например, отсоединить их от действия. И вы можете связать его снова на mouseout.

Идея состоит в том, чтобы отменить привязку при наведении мыши, когда вызывается функция наведения мыши. Это удаляет функцию наведения мыши от элемента, который был наведен. Я не проверял это ... Я прошу прощения, если это не совсем правильно.

$(ele).mouseover(function() {
   $(this).unbind('mouseover');
});
0 голосов
/ 17 августа 2011

используйте 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>
...