Альтернатива методу jQuery.toggle(), который поддерживает eventData?

документация 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;
  }
});

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

Спасибо!

Ответ 1

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

$('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

Вот плагин, который реализует альтернативу .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);