2012-08-28 23 views
1

我需要關於JavaScript/jQuery設計模式的幫助。下面是一些說明我做什麼的HTML和JS代碼,以下是從這些示例中推斷出的問題。設計模式:使用鏈接+命名空間擴展jQuery對象

一些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()); 
}); 

A jsFiddle showing this code in action (should it help you understand what I do) is available.

Q1:如何編寫我的函數,而不必在其名稱中重複命名空間作爲前綴(例如, myfunctions_boxes_),同時避免與第三方代碼衝突?

每次我創建一個新的功能,我想作爲一個jQuery對象上的自定義方法使用(如getParentBoxgetNestedBoxes ...)我必須手動映射它裏面的我的功能之一(即myfunctions_boxes_getBox):

Q2:有沒有辦法自動映射我的自定義方法?

,因爲我覺得他們只要是不完全一樣的

,因爲我用一個本地的jQuery方法,下面的問題可能與上面的一個,但我更喜歡單獨要求它(例如,在上面的例子中each) ,我結束了沒有我的自定義方法的jQuery對象,我需要再次調用我的全局函數中的一個來檢索相同的對象,但附加了自定義方法。

Q3:爲我的全局函數創建一個jQuery插件以保持我的代碼的OO本質(請參見下面的示例)是否有意義?

回答

1

Q1:我怎麼能寫我的功能,而無需重複的命名空間作爲其名稱的前綴(例如myfunctions_boxes_),同時避免與第三方的代碼衝突?

現在的問題是你的函數是全局的,所以你需要追加命名空間到它的名字以防止名稱衝突(但是這仍然不能保證名稱衝突的安全)。你應該做的是包裹整個JavaScript代碼在一個自調用函數,例如:

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

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

的getBox功能現在是私人和你不必擔心名稱的衝突與第三方庫/等等

(現在只處理第一個問題)