我需要有关 JavaScript/jQuery 设计模式的帮助。下面是一些 HTML 和 JS 代码,说明了我的工作,下面是从这些示例中推断出的问题。
一些HTML
使用嵌套 div 来创建遍历场景:
<div class="box">
BOX 1
<div class="nested-boxes">
<div class="box">
BOX 1-1
<div class="nested-boxes">
<div class="box">
BOX 1-1-1
</div>
</div>
</div>
<div class="box">
BOX 1-2
</div>
</div>
</div>
这是Javacript
代码:
// First I declare functions that I want to have available globally
// under a common namespace. Those functions reproduce that namespace as
// a prefix in their name to avoid conflict.
$.extend(true, window, {
MyFunctions: {
Boxes: {
getBox: myfunctions_boxes_getBox
},
Circles: {
// getCircle: myfunctions_circle_getCircle
}
// Squares....
}
});
// I write functions which I want to use on jQuery objects as so:
function myfunctions_boxes_getNestedBoxes() {
return this.find('.nested-boxes').first().children('.box');
}
function myfunctions_boxes_showLabel() {
return this.find('span').first().text();
}
// I then add those functions as new methods to my jQuery objects:
function myfunctions_boxes_getBox($element) {
var $box = $element.closest('.box');
$box.getParentBox = myfunctions_boxes_getParentBox;
$box.getNestedBoxes = myfunctions_boxes_getNestedBoxes;
$box.showLabel = myfunctions_boxes_showLabel;
console.log('getBox',$box);
return $box;
}
// Traversing functions call each other to make sure I retrieve a jQuery object with all
// my custom methods:
function myfunctions_boxes_getParentBox() {
var $parent_box = myfunctions_boxes_getBox(this.closest('.box').parents('.box').first());
console.log('getParentBox',$parent_box);
return $parent_box;
}
现在这就是我的代码的样子:
// I first need to call a global function:
$box = MyFunctions.Boxes.getBox($('#box-1-1'));
// Then I can start chaining my methods
$box.getParentBox().getNestedBoxes().each(function(){
// however as soon as I use a native jQuery method, I end up with
// a jQuery object which doesn't have my custom methods ans I need
// to use a global function again.
console.log($(this), MyFunctions.Boxes.getBox($(this)).showLabel());
});
可以使用jsFiddle
显示此代码的实际操作(是否可以帮助您理解我的工作)。
Q1:如何编写我的函数而不必在名称中重复命名空间作为前缀(例如myfunctions_boxes_
),同时避免与第三方代码冲突?
每次我创建一个我想用作 jQuery 对象上的自定义方法的新函数(例如getParentBox
,getNestedBoxes
...)时,我都必须在我的一个函数中手动映射它(即myfunctions_boxes_getBox
):
Q2:有没有办法自动映射我的自定义方法?
下面的问题可能与上面的问题有关,但我更喜欢单独提问,因为我觉得它们并不完全相同
一旦我使用本机 jQuery 方法(例如each
在上面的示例中),我最终会得到没有我的自定义方法的 jQuery 对象,我需要再次调用我的一个全局函数来检索相同的对象,但使用我的自定义附加到它的方法。
Q3:为我的全局函数创建一个 jQuery 插件以保持我的代码的 OO 特性是否有意义(见下面的示例)?
// plugin declaration (the getBox function should be modified to make use of this)
jQuery.fn.getBox = MyFunctions.Boxes.getBox
// then my code becomes cleaner:
$('#box-1-1').getBox().getParentBox().getNestedBoxes().each(function(){
console.log($(this).getBox().showLabel());
});