【问题标题】:Alternative to jQuery's .toggle() method that supports eventData?替代支持 eventData 的 jQuery 的 .toggle() 方法?
【发布时间】:2010-03-17 00:29:11
【问题描述】:

.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;
  }
});

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

【问题讨论】:

  • 我不明白你的问题。你想做什么?
  • @cletus:我不能使用 .toggle() 因为它似乎不支持将 eventData 传递给处理函数。我正在寻找支持 eventData 的最佳替代解决方案,它(据我所知)将基于 .bind() 方法。换句话说,在 jQuery 文档中说“手动实现相同的行为相对简单”,我正在尝试这样做。

标签: javascript jquery event-handling jquery-events


【解决方案1】:

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

【讨论】:

  • 谢谢,Alconja - 好答案!我很欣赏简洁的代码示例。
  • @Gnuey - 在第一次点击时为我工作(只需将这个确切的源代码复制/粘贴到我的 Firebug 控制台中,现在此页面上的每个链接都会先触发警报)。您是看到错误还是没有警报?
  • 好吧,我尝试在第一次点击时实现一个 slideDown。还将“a”选择更改为类选择。不确定这是否相关。我在这里复制了这个问题:jsfiddle.net/3gpfc
  • @Gnuey - 切换您的 slideUpslideDowns。在第一次点击时,clicks 将是 undefined 将被解释为 false,因此它将执行 else 分支。
  • 啊,我明白了。我终于看懂了你的代码,而且很漂亮。谢谢,如果我还没有投票,我会再次投票!
【解决方案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');
    }
]);

我已经包含了一个演示 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);

【讨论】:

    猜你喜欢
    • 2014-08-25
    • 1970-01-01
    • 2013-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-07
    • 2023-03-28
    • 1970-01-01
    相关资源
    最近更新 更多