替代jQuery的支持eventData的.toggle()方法?

时间:2010-03-17 00:29:11

标签: javascript jquery binding javascript-events event-handling

.toggle()方法的jQuery documentation说明:

  

提供.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 个答案:

答案 0 :(得分:36)

似乎是一种合理的方式...我只是建议您使用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);
});

答案 1 :(得分: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');
    }
]);

我已经加入了演示here

插件代码:

(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);