重构 jQuery 以使用 $(this) 并从另一个元素中添加/删除类

Refactoring jQuery to use $(this) and add/remove classes from another element

本文关键字:元素 另一个 添加 删除 jQuery this 重构      更新时间:2023-09-26

所以我有这个想法,我正在研究Codepen。我已经让它按原样工作,但在我添加更多可点击区域之前,我已经意识到需要重构和干燥东西。到目前为止,它可以工作,但它像地狱一样丑陋,并且会涉及大量重复的代码。

所以我正在尝试用一个 switch 语句替换许多 $(.class).click(function() { ... }); 函数,该语句使用 $(this) 来填充单个 .click 函数。但我迷路了。

您可以在此处查看所有内容并进行编辑:http://codepen.io/lukewatts/pen/ubtmI

我觉得我离得很近,但我碰壁了。最上面注释掉的部分是 DRY 尝试,而现在未注释的是工作版本。单击最小值、关闭字数、最大值字数或 LED 以查看其工作情况。

非常感谢您对此的任何建议。老实说,PHP是我的主要语言。

附言我有leds.click(function() { ... }),我用leds.on(function() { ... })代替了它,但仍然一无所获。

我明白你想做什么,但不是jQuery对象的工作方式。为了检查对象是否与选择器匹配,您必须使用 .is() .

因此,您将无法使用 switch ,但您必须使用一系列链式if才能以您尝试的方式实现目标,例如

if ( $this.is('.led[data-level="one"]') )
   var led = $('p.min a');
   var level = "one";

我已经更新了您的代码笔示例以这种方式工作:代码笔

不过,正如我在对该问题的评论中提到的,我在这里不进行任何代码审查,只是修复对您不起作用的内容。老实说,我不确定这实际上比您混乱的原始方法更好。

重构后的版本对我来说看起来不错。如果你不喜欢使用 addClass 和 removeClass,你可以直接更改元素的 class 属性:

indicator.attr("class", "one on");

你的switch语句不起作用的原因是,每次你创建一个jQuery对象时,它都会得到一个Id,所以当switch试图将$this与像$(p.min a)这样的选择器进行比较时,它们不会相等。但是,如果将多个 if 语句与 $.is 一起使用,则可以比较:

$this = $(this)
if($this.is('p.min a')) {
   // do work
} else if($this.is('p.max a')) {
   // do work
}

但是,我不推荐这种方法。对于更复杂的页面,我推荐像Knockout.js这样的绑定框架。对于小事,你增加了很多复杂性。为清楚起见:如果这成为更大的控件集或系统的一部分,则绑定框架将很有用。对于按原样控制,绑定框架和 OP 的当前方法都是矫枉过正的。

你可能想看看事件委托,我发现它对保持干燥非常有帮助。单击会将 DOM 树向上冒泡到更高的元素,您可以在祖先元素上注册处理程序。这实际上是理想的,因为您只将单个处理程序绑定到单个元素,而不是绑定到多个元素,因此除了更干净的代码之外,您还可以实现性能优势。

第一件事,将所有.led元素包装在一个<div id="leds">中:

 <div id="leds">
     <a href="#" class="led" data-level="one"></a>
     <a href="#" class="led" data-level="thirteen"></a>
 </div>

现在创建您的处理程序:

   $('#leds').bind('click', function(e){
    var target = e.target;
    var $target = $(target);
       //do interesting stuff
       if (target.nodeName === 'A') {
            var level = $target.data('level');
            if(level = 'one'){
                //do more interesting stuff
            }
        }       
     }
    });