Подтвердить что ты не робот

Как узнать, какой элемент в теле вызвал запрос AJAX в jQuery

Я работаю над приложением и пытаюсь использовать поведение Facebook для запроса AJAX. В Facebook вы получаете хорошее загрузочное изображение рядом с пиктограммой, которая запускает запрос AJAX. Ну, это довольно просто реализовать, если на странице есть 1-2 элемента.

Я хочу сделать его общим и хотел бы, чтобы всякий раз, когда какой-либо элемент запускает запрос AJAX, я хочу показать небольшой GIF рядом с ним. Для этого я думал, что событие AjaxSend jQuery будет достаточно хорошим, но, увы, это не дает мне дескриптора объекта, который вызвал вызов AJAX. Я хотел бы знать, возможно ли с помощью некоторого метода jQuery узнать, какой элемент вызвал вызов AJAX, а также получить тот же самый дескриптор, когда вызов AJAX завершен.

Если вы чувствуете, что мой подход к проблеме неверен, я хотел бы услышать ваши предложения.

4b9b3361

Ответ 1

Если вы хотите использовать обработчики запросов ajax, идентификатор должен быть назначен (вручную или автоматически) для элемента, вызвавшего событие. Затем вы можете отправить этот идентификатор в качестве дополнительной пары ключ-значение в запросе (element_id: THEID) и захватить его различными методами подстроки в обработчиках запросов ajax.

Пример:

<script type="text/javascript">

    $(document).ready(function(){

        $("input").click(function(){

            var newid = (create a custom id with date and time);

            $(this).attr("id", newid);
            $.post("handler.php", {element_id : $(this).attr("id")});
        });

   }).ajaxSend(function(e, xhr, settings){

        var start_position = settings.data.indexOf("element_id");
        var equalsign_position = settings.data.indexOf("=", start_position);
        var ampersand_position = settings.data.indexOf("&", start_position);

        var element_id;
        if(ampersand_position == -1){
            element_id = settings.data.substr(equalsign_position+1);
        } else {
            element_id = settings.data.substr(equalsign_position+1, ampersand_position-equalsign_position-1);
        }

        $("#"+element_id).after("<div id='div"+element_id+"'><img src='loading_start.png' /></div>");

    }).ajaxComplete(function(e, xhr, settings) {

        var start_position = settings.data.indexOf("element_id");
        var equalsign_position = settings.data.indexOf("=", start_position);
        var ampersand_position = settings.data.indexOf("&", start_position);

        var element_id;
        if(ampersand_position == -1){
            element_id = settings.data.substr(equalsign_position+1);
        } else {
            element_id = settings.data.substr(equalsign_position+1, ampersand_position-equalsign_position-1);
        }

        $("#div"+element_id).remove();


    });

    </script>

    <input type="button" value="Save" />

Альтернативой является обработка появления и исчезновения загружаемого изображения в каждом обработчике событий (но, похоже, вы понимаете, что у вас их слишком много?), например:

<script type="text/javascript">

    $(document).ready(function(){

        $("input").click(function(){


            var element_id = (generate custom id);

            $(this).after("<div id='div"+element_id+"'><img src='loading_start.png' /></div>");

            $.post("handler.php", {var:"hello"}, function(){
                $("#div"+element_id).remove();
            });

        });
    })
</script>

Ответ 2

Другим общим способом, который требует наименьшей настройки, является использование свойства activeElement для объекта события:

$(document).ajaxStart(function (e) {
    try {
        var $el = $(e.target.activeElement);
        var isButton = $el.hasClass('btn');

        // just a precautionary check
        if (!isButton) {
            return;
        }

        $el.button('loading'); // or whatever else you want to do

    } catch (ex) {
        console.log(ex);
    }
});

$(document).ajaxStop(function (e) {
    try {
        var $el = $(e.target.activeElement);
        var isButton = $el.hasClass('btn');

        if (!isButton) {
            return;
        }

        $el.button('reset');

    } catch (ex) {
        console.log(ex);
    }
});

Причина этого в том, что при нажатии кнопки она получает фокус. И e.target (который document в этой точке сообщает нам о текущем элементе в фокусе с помощью свойства activeElement.

Обратите внимание, что try...catch является полностью необязательным. Обычно рекомендуется обернуть любые глобальные обработчики в try...catch, чтобы гарантировать, что любое исключение здесь не вызывает никаких побочных эффектов. console.log сообщит вам об исключении, если оно есть, и вы сможете исправить его позже.

Ответ 3

Я также пытался поймать событие ajax для анимации некоторых кнопок, и я придумал:

        $j('.btn').bind('click',function(){
            triggerElement = $j(this);
        });
        $j(document).ajaxSend(function(event,xhr,options){
            var userAgent = $j.browser;
            if (userAgent.mozilla)
                triggerElement = $j(event.target.activeElement);
            if (triggerElement && triggerElement.is('.btn')){
                var triggerOffset = triggerElement.offset();
                genericDisabler = $j('<div></div>');
                genericDisabler.addClass('generic-disabler');
                $j('body').append(genericDisabler);
                genericDisabler.width(triggerElement.outerWidth());
                genericDisabler.height(triggerElement.outerHeight());
                genericDisabler.offset({
                    left:triggerOffset.left,
                    top:triggerOffset.top
                });
                triggerElement.switchClass('orange','gray-ajax-gradient',25).animate({
                    opacity: 0.6
                });         
            }
        });
        $j(document).ajaxComplete(function(event,xhr,options){
            if (triggerElement && triggerElement.is('.btn')){
                triggerElement.switchClass('gray-ajax-gradient','orange',25,function(){
                    if (genericDisabler)
                        genericDisabler.remove()
                }).animate({
                    opacity: 1
                });
            }
            triggerElement = null;
        });

Итак, я уверен, что получаю элемент, где выполняется клик, но я сохраняю ссылку на то, что FF может преуспеть.

Ответ 4

Я столкнулся с той же проблемой, прежде чем... ну, это не даст ручку u, посмотрите, полезен ли код ниже или нет. вот мое решение

$(document).click(function(event){
        if(event.target.id != "comment" && event.target.id != "fb-button"){
            $("#submit-button").css("display","none");
            if($("#comment").val() == ""){
                $("#comment").addClass("lightText").val("write a comment...");
            }
        }
    });

просто отслеживать все события кликов на теле и получать его источник

Ответ 5

У меня была такая же проблема, я установил глобальный параметр и установил для него кнопку клика:

var btn = null;

$(document).ajaxSend(function(event, xhr, settings) {
    btn.find(".ui-button-text:first").append('<div class="loading"></div>');
}).ajaxComplete(function(event,request, settings) {
    $(".loading").remove();
});

просто добавьте стиль для загрузки, и он добавит индикатор загрузки в пользовательские кнопки JQuery.

<style type="text/css">
.btn {
    margin: 5px 10px 0 0;
}

.loading {
    display: inline;
    background: url(../images/loading.gif) center no-repeat;
    margin: 0 0 0 5px;
    padding: 0 0 0 16px;
}
</style>

Ответ 6

Довольно много подходов к решению этой проблемы.

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

Я закончил завершение метода $.get() в свой собственный объект:

var AJAX = {
  fetch: function (url, data, targetObj) {
    var oldText = ''
    targetObj = (this.isDefined(targetObj) ? targetObj : null)
    if (targetObj) {
      oldText = targetObj.text()
      targetObj.text('Loading...')
    }

    return $
      .get(url, data)
      .always(function () {
        // if target object is provided, run end callbacks on it
        if (targetObj) {
          targetObj.text(oldText)
        }
      })
  }
}

Затем назовем это следующим образом:

AJAX.fetch('my_script.php', {somedata: 'blabla'}, $(this))

Вы можете полностью обобщить его, чтобы он мог запускать любой обратный вызов, который вы автоматически добавляете + ошибки журналов. Я написал учебник, как это сделать + вы можете найти код на GitHub.

Ответ 7

$(document).ajaxStart( function(e) {
    var el = e.target.activeElement.id;
    alert('event triggerd by : ' + el);     
});

Основное решение: e.target.activeElement.id