AjaxSend и цифры в спиннере

Всем привет!

Проблема с AjaxSend и спиннером, реализующим количество единиц товаров в MS2.



Есть на страничке красивый спиннер, реализованный следующим образом.

В шаблоне:

<input type="number" name="count" min="1" max="999" value="1">
Далее это обрабатывается следующим куском Jquery:

(function ($) {
        $.fn.spinner = function () {
            this.each(function () {
                var el = $(this);
                var parent = $(el.parents('span.spinner')).length;

                // Если такого родителя нет, то оборачиваем спиннер и добавляем + и -
                if (parent == 0) {
                    el.wrap('<span class="spinner"></span>');
                    el.before('<span class="sub">-</span>');
                    el.after('<span class="add">+</span>');
                }

                // Реагируем на нажатие -
                el.parent().on('click', '.sub', function () {
                    if (el.val() > parseInt(el.attr('min')))
                        el.val(function (i, oldval) {
                            return --oldval;
                        });
                });

                // Реагируем на нажатие +
                el.parent().on('click', '.add', function () {
                    if (el.val() < parseInt(el.attr('max')))
                        el.val(function (i, oldval) {
                            return ++oldval;
                        });
                });
            });
        };
    })(jQuery);
$('input[type=number]').spinner();
И если страница статична, то все ОК (проверка наличия родителя добавлена уже для страницы с Ajax). Поскольку спиннер используется на странице, где выводятся товары MS2, то при нажатии на кнопку и прочие телодвижения происходят Ajax-события. Чтобы их отлавливать, я создал такую конструкцию:

$(document).bind("ajaxSend", function(){
     }).bind("ajaxStop", function(){
        $('input[type=number]').spinner();
     });
И на первый взгляд вроде бы все ок, спиннер не дублируется (есть проверка на его наличие), и заново создается при перезагрузке. НО! Странный баг: если нажать на кнопку «в корзину», то спиннер начинает приращение цифры на столько, на сколько раз было нажата кнопка «в корзину» на текущей странице. Пример: только загрузились — переключатся 1-2-3-4-5, положили один товар в корзину — на всех товарах начало переключаться 1-3-5-7-9, еще один — 1-4-8-12 и т.д.

Подскажите, откуда он это берет? Как так получается, что нарушается логика приращения?
Павел Ширяев
09 апреля 2015, 17:43
modx.pro
1 228
0

Комментарии: 3

Павел Ширяев
09 апреля 2015, 22:08
0
Когда никто долго не отвечает, это полезно — есть время пораскинуть мозгами :)

Проблема решилась.

Реакции на нажатия надо инициализировать единожды при загрузке страницы.
А вот сам спиннер нужно инициализировать каждый раз на событие ajaxComplete.

Собственно, выносим реакции на нажатия в отдельную функцию, и инициализируем ее на событие document.ready, и далее не трогаем.
    Павел Ширяев
    09 апреля 2015, 23:25
    0
    Мда, поторопился.

    Надо покурить Ajax, вообще с ним не работал.
    Павел Ширяев
    10 апреля 2015, 13:50
    0
    Функция самого спиннера должна для MS2 выглядеть так:

    (function ($) {
            $.fn.spinner = function () {
                this.each(function () {
                    var el = $(this);
                    var parent = $(el.parents('span.spinner')).length;
    
                    // Если такого родителя нет, то оборачиваем спиннер и добавляем + и -
                    if (parent == 0) {
                        el.wrap('<span class="spinner"></span>');
                        el.before('<span class="sub">-</span>');
                        el.after('<span class="add">+</span>');
                    
    
                    // Реагируем на нажатие -
                    el.parent().on('click', '.sub', function () {
                        if (el.val() > parseInt(el.attr('min')))
                            el.val(function (i, oldval) {
                                return --oldval;
                            });
                    });
    
                    // Реагируем на нажатие +
                    el.parent().on('click', '.add', function () {
                        if (el.val() < parseInt(el.attr('max')))
                            el.val(function (i, oldval) {
                                return ++oldval;
                            });
                    });
    }
                });
            };
        })(jQuery);
    Ну и вызов спиннера при Ajax-перезагрузке (работает и для первой загрузки):

    $(document).bind("ajaxComplete", function(){
            $('.goods_container').ready(function() {
            $('input[type=number]').spinner();
            
            });
         });
      Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
      3