Альтернатива методу .toggle () в jQuery, который поддерживает eventData? - PullRequest
12 голосов
/ 17 марта 2010

Документация jQuery для метода .toggle() сообщает:

Метод .toggle () предоставляется для удобства. Относительно просто реализовать то же самое поведение вручную, и это может быть необходимо, если предположения, встроенные в .toggle (), ограничивают.

Предположения, встроенные в .toggle, оказались ограничивающими для моей текущей задачи, но документация не раскрывает, как реализовать то же поведение. Мне нужно передать eventData в функции-обработчики, предоставляемые toggle(), но похоже, что только .bind() будет поддерживать это, а не .toggle().

Мое первое желание состоит в том, чтобы использовать флаг, который является глобальным для одной функции-обработчика, для сохранения состояния щелчка. Другими словами, а не:

$('a').toggle(function() {
  alert('odd number of clicks');
}, function() {
  alert('even number of clicks');
});

сделать это:

var clicks = true;
$('a').click(function() {
  if (clicks) {
    alert('odd number of clicks');
    clicks = false;
  } else {
    alert('even number of clicks');
    clicks = true;
  }
});

Я не проверял последнее, но подозреваю, что это сработает. Это лучший способ сделать что-то подобное, или я пропускаю лучший способ?

Спасибо!

Ответы [ 2 ]

36 голосов
/ 17 марта 2010

Похоже, это разумный способ сделать это ... Я бы просто предложил вам использовать утилиты jQuery data storage вместо того, чтобы вводить дополнительную переменную (которая может стать головной болью, если вы захотите отслеживать целую кучу ссылок). Итак, исходя из вашего примера:

$('a').click(function() {
  var clicks = $(this).data('clicks');
  if (clicks) {
    alert('odd number of clicks');
  } else {
    alert('even number of clicks');
  }
  $(this).data("clicks", !clicks);
});
2 голосов
/ 27 февраля 2013

Вот плагин, который реализует альтернативу .toggle(), тем более что он был удален в jQuery 1.9 +.

Как использовать:

Подпись для этого метода:

.cycle( functions [, callback] [, eventType])
  • functions [Array]: Массив функций для переключения между
  • callback [Функция]: функция, которая будет выполняться по завершении каждой итерации. Будет передана текущая итерация и вывод текущей функции. Может использоваться для выполнения чего-либо с возвращаемым значением каждой функции в массиве functions.
  • eventType [String]: Строка, указывающая типы событий для циклирования, например. "click mouseover"

Пример использования:

$('a').cycle([
    function() {
      alert('odd number of clicks');
    }, function() {
      alert('even number of clicks');
    }
]);

Я включил демонстрацию здесь .

Код плагина:

(function ($) {
    if (!Array.prototype.reduce) {
        Array.prototype.reduce = function reduce(accumulator) {
            if (this === null || this === undefined) throw new TypeError("Object is null or undefined");
            var i = 0,
                l = this.length >> 0,
                curr;

            if (typeof accumulator !== "function") // ES5 : "If IsCallable(callbackfn) is false, throw a TypeError exception."
            throw new TypeError("First argument is not callable");

            if (arguments.length < 2) {
                if (l === 0) throw new TypeError("Array length is 0 and no second argument");
                curr = this[0];
                i = 1; // start accumulating at the second element
            } else curr = arguments[1];

            while (i < l) {
                if (i in this) curr = accumulator.call(undefined, curr, this[i], i, this);
                ++i;
            }

            return curr;
        };
    }
    $.fn.cycle = function () {
        var args = Array.prototype.slice.call(arguments).reduce(function (p, c, i, a) {
            if (i == 0) {
                p.functions = c;
            } else if (typeof c == "function") {
                p.callback = c;
            } else if (typeof c == "string") {
                p.events = c;
            }
            return p;
        }, {});
        args.events = args.events || "click";
        console.log(args);
        if (args.functions) {
            var currIndex = 0;

            function toggler(e) {
                e.preventDefault();
                var evaluation = args.functions[(currIndex++) % args.functions.length].apply(this);
                if (args.callback) {
                    callback(currIndex, evaluation);
                }
                return evaluation;
            }
            return this.on(args.events, toggler);
        } else {
            //throw "Improper arguments to method \"alternate\"; no array provided";
        }
    };
})(jQuery);
...