1

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

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

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

我觉得我很接近,但我撞到了墙。顶部注释掉的部分是 DRY 尝试,而目前未注释的是工作版本。单击最小、关闭、最大字数或 LED 以查看它的工作情况。

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

PS我有leds.click(function() { ... }),我用它代替了它,leds.on(function() { ... })但仍然没有。

4

4 回答 4

1

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

因此,您将无法使用 a switch,但您将不得不使用一系列链式ifs 来以您尝试的方式实现目标,例如

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

我已更新您的 CodePen 示例,使其以这种方式工作:Codepen

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

于 2013-09-20T13:32:55.893 回答
1

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

indicator.attr("class", "one on");
于 2013-09-20T13:15:50.630 回答
1

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

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

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

于 2013-09-20T13:26:34.617 回答
0

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

首先,将所有.led元素包装在 a 中<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
            }
        }       
     }
    });
于 2013-09-20T13:20:12.270 回答