1

我需要有关 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 对象上的自定义方法的新函数(例如getParentBoxgetNestedBoxes...)时,我都必须在我的一个函数中手动映射它(即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());
});
4

1 回答 1

1

Q1:我如何编写我的函数,而不必在名称中重复命名空间作为前缀(例如 myfunctions_boxes_),同时避免与第三方代码冲突?

现在的问题是您的函数是全局的,因此您需要将命名空间附加到其名称以防止名称冲突(但这仍然不能保证名称冲突的安全性)。您应该做的是将整个 javascript 代码包装在一个自调用函数中,例如:

(function {
    $.extend(true, window, {
        MyFunctions: {
            Boxes: {
                getBox: getBox
            }
        }
    });

    function getBox($element) {
        // Do something.
        return $element;
    }
}());

getBox 函数现在是私有的,您不必担心与第三方库/等的名称冲突。

(现在只解决第一个问题)

于 2012-08-28T10:46:47.680 回答