我需要JavaScript / jQuery设计模式的帮助。下面是一些HTML和JS代码,说明了我的工作,下面是从这些示例中推断出来的问题。
一些带有嵌套div的HTML
来创建遍历场景:
<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());
});
A jsFiddle
showing this code in action (should it help you understand what I do) is available.
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());
});
答案 0 :(得分:1)
Q1:我如何编写我的函数而不必在名称中重复命名空间(例如myfunctions_boxes_),同时避免与第三方代码冲突?
现在的问题是你的函数是全局的,所以你需要将名称空间附加到它的名字以防止名称冲突(但是这仍然不能保证名称冲突的安全性)。你应该做的是将你的整个javascript代码包装在一个自我调用的函数中,例如:
(function {
$.extend(true, window, {
MyFunctions: {
Boxes: {
getBox: getBox
}
}
});
function getBox($element) {
// Do something.
return $element;
}
}());
getBox函数现在是私有的,您不必担心与第三方库/等的名称冲突。
(目前仅处理第一个问题)