12

该方法的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;
  }
});

我没有测试过后者,但我怀疑它会起作用。这是做这样的事情的最好方法,还是有更好的方法我错过了?

4

2 回答 2

36

似乎是一种合理的方法...我只是建议您使用 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);
});
于 2010-03-17T00:47:05.063 回答
2

这是一个实现替代的插件.toggle(),特别是因为它已在 jQuery 1.9+ 中被删除。

如何使用:

此方法的签名是:

.cycle( functions [, callback] [, eventType])
  • functions[Array]:要在其中循环的函数数组
  • callback[Function]:每次迭代完成时执行的函数。它将传递当前迭代和当前函数的输出。可以用来对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);
于 2013-02-27T04:04:29.747 回答