所以我有这个想法,我正在研究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
}
}
}
});