1

问题

我刚开始学习javascript。我正在尝试以更模块化的方式重现一段工作代码。它帮助我保持清洁,并更好地理解它。

我确信有更有效或更简洁的方法来实现代码的功能,所以请女士/男士不要提及它 - 你可以省去呼吸。这里的重点是通过玩代码来学习我还不明白的东西。

代码有什么作用

它为已弃用的方法切换创建了一种替代方法, 然后可以按以下方式使用$('#foo h2').mytoggle(plus,minus);

下面是一段原始代码:

$.fn.clicktoggle = function(a, b) {
return this.each(function() {
    var clicked = false;
    $(this).click(function() {
        if (clicked) {
            clicked = false;
            return b.apply(this, arguments);
        }
        clicked = true;
        return a.apply(this, arguments);
    });
});
};

以下是我之前代码的版本:

function call_a_or_b (a,b) {
    var clicked = false;
    function alternate (a,b) {
        if (clicked) {
        clicked = false;
        return a.apply(this, arguments);
        }
        else {
        clicked = true; 
        return b.apply(this, arguments);
        }
    } // end function alternate


    return $(this).each(function () {$(this).click(alternate(a,b))}); 
} //end function call_a_or_b

$.fn.clicktoggle = function(a,b) {  call_a_or_b(a,b); };

问题

  1. 为什么原始版本使用 return this.each 而不是return $(this).each

    • 注意:我不能this在我的版本上使用,否则会返回错误:Uncaught TypeError: Object [object global] has no method 'each'
  2. 不是eachjQuery方法吗?

    • 据我了解,在使用时this,您可以在其上调用 DOM 方法,但不能调用 jQuery 方法。反之亦然。
  3. 为什么我的版本不工作?我错过了什么?

    • 注意:我没有错误,因此更难调试。
4

2 回答 2

0

当你为它分配一个函数时,$.fn它会在 jQuery 的上下文中执行,this一个 jQuery 对象也是如此。您的函数最有可能在窗口的上下文中执行。如果将最后一行更改为 this ,它的工作方式应该完全相同:

$.fn.clicktoggle = call_a_or_b(a,b);
于 2013-09-22T00:43:28.960 回答
0
  1. 插件对象内部是this指启动插件的 jQuery 包装器对象,而不是其他方法中的 dom 对象
  2. 由于thisjQuery 包装器对象.each()可用
  3. 您的实施中存在多个问题
    1. 当您调用时,call_a_or_b您没有将执行上下文传递给方法,因此this在您的方法内部是指window对象
    2. 根据经验,要在 jQuery 中启用链接,您需要返回 jQuery 包装器,而您没有这样做
    3. 替代方法存在关闭和调用相关问题

尝试

(function ($) {
    function call_a_or_b(a, b) {

        //for each matched element the clicked variable should be a closure one, so needed to rearrage it a bit        
        function alternate(el) {
            var clicked = true;
            $(this).click(function () {
                if (clicked) {
                    clicked = false;
                    return a.apply(this, arguments);
                } else {
                    clicked = true;
                    return b.apply(this, arguments);
                }
            })
        } // end function alternate

        return $(this).each(alternate);
    } //end function call_a_or_b

    $.fn.clicktoggle = function (a, b) {
        //call the method with the current execution context and return the value returned fromit
        return call_a_or_b.apply(this, arguments);
    };
})(jQuery);

演示:小提琴

于 2013-09-22T01:01:05.637 回答