我有许多不同的控制元素"在我的应用程序:下拉菜单,选项卡,菜单等。在相同的页面上,有许多相同的控件。在编写JavaScript来处理与每个控件相关的不同事件时,我试图尽可能地将我的代码设置为DRY。其中一个挑战是模块化我的JQuery代码,以便在特定控件中发生的事件仅影响该控件。
以这个初始代码为例,它所做的就是点击它时打开一个下拉菜单。我过去常常只编写由不同事件触发的大量不同的匿名函数,所以这种类型的JQuery对我来说真的很新。
var dropdown = {
init: function() {
$(".dropdown").click(".dropdown", dropdown.openDropdown);
},
openDropdown: function() {
$(this).children(".dropdown-menu").show();
$(this).addClass("open");
}
}
$(document).ready(dropdown.init);
我的问题是,在这个dropdown
变量中,我希望能够保存/跟踪当前正在执行的dropdown
控件的不同部分。例如,我可能想写:
var menu = $(this).children(".dropdown-menu");
在这个块中的某个地方,这样我可以在调用不同的函数时返回这个菜单。我只是无法弄清楚如何做到这一点。欢迎任何帮助/指导!感谢。
答案 0 :(得分:3)
我喜欢coffeescript
的内容是如何让您轻松创建 classes
。咖啡中的类只是生成"模块的简单方法。使用javascript的原型继承。更多相关内容:http://coffeescript.org/#classes
但是你如何实现更多的模块化jQuery代码就是做这样的事情:
var DropDown = (function(){
// constructor
function DropDown(el){
this.el = $(el);
this.link = this.el.find("a");
this.menu = this.el.find(".dropdown-menu");
this.bindClick();
}
// method binding click event listener
DropDown.prototype.bindClick = function(){
var _this = this;
this.link.click(function(e){
_this.openDropDown();
e.preventDefault();
});
};
// click event handler
DropDown.prototype.openDropDown = function(){
this.menu.show();
this.link.addClass("open");
};
return DropDown;
})();
$(function(){
// init each .dropdown element as a new DropDown
$(".dropdown").each(function(){
new DropDown(this);
});
});
答案 1 :(得分:1)
你已经触及了我越来越倾向于的模式。基本上,创建一个JavaScript对象,在页面上给定根元素的情况下充当控制器。由于这个“下拉列表”非常通用,它可能可以访问整个页面并且非常高兴。我还建议制作这些“模块”可实例化的对象,因为这样可以更容易地编写单元测试:
function DropdownModule() {
this.handleClick = this.handleClick.bind(this);
}
DropdownModule.prototype = {
element: null,
$element: null
constructor: DropdownModule,
init: function(element) {
this.setElement(element);
this.$element.on("click", ".dropdown", this.handleClick);
},
handleClick: function(event) {
var $dropdown = $(event.currentTarget);
$dropdown.children(".dropdown-menu").show();
$dropdown.addClass("open");
this.someOtherFunction($dropdown);
},
someOtherFunction($dropdown) {
// do something with $dropdown
},
setElement: function(element) {
this.element = element;
this.$element = $(element);
}
}
然后使用它,只需在Dropdown
:
var dropdown = new Dropdown()
.init(document.documentElement);
document.documentElement
属性引用<html>
标记,并在JavaScript开始执行时可用。
作为旁注,我围绕这种方法构建了一个完整的框架:Foundry。其他框架,如Angular,也采用了类似的方法。
答案 2 :(得分:1)
您想要的听起来就像jQuery UI已经在Widget Factory中实现的那样。
我强烈建议你查看它,因为你最终会得到它像
$.widget( 'dropdown', {
_create: function() {
this.element.addClass( 'dropdown' );
this._on({
'click': '_clicked'
});
},
_clicked: function( event ) {
// `this` is an instance of dropdown here, not the element
this.clicked = !this.clicked;
this.element.toggleClass( 'clicked', this.clicked );
},
_destroy: function() {
this.element.removeClass( 'dropdown' );
}
});
然后你会像任何其他jQuery UI Widget一样使用它
$( '#some-element' ).dropdown();