2011-09-20 58 views
1

是否有解決方案來創建一個虛擬元素的屬性,方法和事件處理程序,並用它擴展現有的元素? 例如:JQuery如何使用另一個包含事件處理程序的元素來擴展元素?

var dummyElement = $('<div />', { 
    // properties 
    ... 
    // methods 
    ... 
    // event handlers 
    ... 
}); 

然後,

$.extend($('#myElement'), dummyElement); 

現在,$( '#myElement')具有dummyElement的屬性,方法和事件處理,除了它自己的。

可能嗎?我怎麼能用JQuery來做到這一點?

謝謝

+0

你爲什麼不試試看看發生了什麼! – 2011-09-20 04:51:38

+0

我做到了,但(可能是因爲語法不正確)它沒有工作。 – jym

回答

0

好的。由於不同的答案,特別是從。 看來,jQuery方法並不是用來擴展另一個DOM元素的。但它可以從一個對象擴展DOM元素。這是一個解決方案:

1)首先我創建擴展對象。每個擴展都必須定義一個initExtension()方法。下面是創建兩個擴展對象的示例:

var myObjExtension1 = { 
    // constructor 
    initExtension : function() { 
    // Add some data properties 
    this.something = 'something'; 

    // Add some method properties 
    this.doSomething = function() { alert(this.something); }; 

    // Add some DOM elements 
    $(this).append('<div>element created from extension 1</div>'); 

    // Add some event handlers 
    $(this).click(
     function(evt) { 
     $(this).append('<div>element created from extension 1 click event</div>'); 
     } 
    ); 
    } 
}; 

var myObjExtension2 = { 
    // constructor 
    initExtension : function() { 
    // Add some data properties 
    this.more = 'more'; 

    // Add some method properties 
    this.doMore = function() { alert(this.more); }; 

    // Add some DOM elements 
    $(this).append('<div>element created from extension 2</div>'); 

    // Add some event handlers 
    $(this).click(
     function(evt) { 
     $(this).append('<div>element created from extension 2 click event</div>'); 
     } 
    ); 
    } 
}; 

2)爲了容易地擴展所有我需要延長元件,我創建一個小的jQuery插件。這個插件包含一個擴展具有指定擴展名的源元素的方法:

(function($){ 
    $.fn.extendWith = function(objExtension) { 
    this.each( 
     function(index) { 
     $.extend(this, objExtension); 
     this.initExtension(); 
     } 
    ); 
    return this; // jQuery chaining 
    } 
})(jQuery); 

3)最後,我擴展了一些jQuery元素。請注意,在下面的例子中,我延伸匹配someElement類元素,先用​​,然後與myObjExtension2,通過級聯extendWith(...)插件方法:

$('.someElement').extendWith(myObjExtension1).extendWith(myObjExtension2); 

現在,所有的​​和myObjExtension2數據屬性,方法屬性和事件處理程序可以從我的$('。someElement')元素中獲得。例如:

$('.someElement').each(function() { 
    this.doSomething(); 
    this.doMore(); 
}); 
+0

在你的jQuery插件中使用'$ .extend'是沒有必要的。它導致你的「initExtension」方法被複制到元素本身,你可能*不需要。更簡單的方法是刪除'$ .extend',並將調用改爲initExtension,如下所示:'objExtension.initExtension.call(this)'。這會調用'initExtension()'將'this'設置爲元素(與您的代碼相同),但它不會將'initExtension'複製到元素上。 – Lee

+0

另一種觀察:你的「擴展」重複了jQuery插件架構提供的相同設計模式。當你在一個jQuery元素集上調用一個插件函數時,插件函數被調用,元素集爲'this'。典型的插件然後改變或加入(即「擴展」)集合中的元素。這可能包括添加/刪除子元素,事件處理程序和/或設置屬性,屬性和css值。你的「Obj擴展」只是增加了另一層抽象:一個應用「擴展函數」的jQuery插件,它本身可以是jQuery插件。 – Lee

0

IMO你根本不需要虛擬元素。在下面的例子中,我演示了一種在純javascript中創建元素的簡單方法。

源代碼

createElement: function (options) { 
    /// <summary>Creates a document object model (DOM) element.</summary> 
    /// <param name="options" type="Object">An object that contains tag name, attributes, events, properties and children.</param> 

    var clone = this.extend({}, options); 

    // Create element 
    var e = document.createElement(clone.tag); 
    delete clone.tag; 

    // Assign attributes 
    if (clone.attributes) { 

     for (var attrib in clone.attributes) { 
      e.setAttribute(attrib.replace('$', ''), clone.attributes[attrib]); 
     } 

     delete clone.attributes; 
    } 

    // Create and append children if has 
    if (clone.children) { 

     for (var idx in clone.children) { 
      e.appendChild(this.createElement(clone.children[idx])); 
     } 

     delete clone.children; 
    } 

    // Assign event handlers 
    if (clone.events) { 

     for (var en in clone.events) { 

      var handler = clone.events[en]; 

      if (handler instanceof Function) 
       this.addHandler(e, en, handler); 
     } 

     delete clone.events 
    } 

    // Assign properties 
    for (var prop in clone) { 
     e[prop] = clone[prop]; 
    } 

    return e; 

}, 

addHandler: function (element, eventName, handler) { 

    // Firefox is first, Of cource after chrome :p 
    if (element.addEventListener) { 
     element.addEventListener(eventName, handler, false); 
    } 
    else if (element.attachEvent) { 
     element.attachEvent('on' + eventName, handler); 
    } 

}, 

extend: function (expando, properties, override) { 

    if (properties && typeof (properties) == 'object') { 

     for (var prop in properties) { 

      var val = properties[prop]; 

      if (!expando[prop] || override) 
       expando[prop] = val; 

     } 

    } 

    return expando; 

} 

您可以重寫上面的代碼使用jQuery延長,而不是創建一個新的元素。

使用

Util.createElement({ 
    tag: 'input', 
    type: 'checkbox', 
    checked: this.checked, 
    events: { 
     change: function(e) { // ... } 
    } 
}); 
0

退房jQuery的clone()方法。在與replaceWith()一起,我想你可以完成一些接近(但不完全),你在找什麼:

// 1- create dummy 
var dummy - $('<div />'); 

// 2- add stuff to dummy... 
// ex: adding a click handler, and an "alt" attribute 
dummy.click(function(evt) { console.log("click"); } 
dummy.attr("alt", "this is the alt text for dummy"); 

// 3- clone dummy, and the replace `#myElement` with the clone 
$('#myElement').replaceWith(dummy.clone(true)); 

注意:創建你的榜樣dummyElement時所使用的代碼,是不是jQuery函數的有效形式。據我所知,你不能通過將它們作爲第二個參數傳遞給jQuery函數來添加屬性,方法和處理程序。如果你傳遞第二個參數,jQuery將把它解釋爲解析選擇器的上下文。我已經展示了添加點擊處理程序和屬性的示例。


編輯:如果你只是想複製對象的屬性(如你所說:「屬性」,「方法」和「事件處理程序」)從一個HTML元素到另一個,則是$.extend(...)這項工作的工具。只要確定你正在使用HTML元素本身,而不是Jquery set對象。這看起來像這樣:

var dummy = $('<div />'); 
var myElement = $('#myElement'); 
$.extend(myElement.get(0), dummy.get(0)); 
+0

謝謝Lee,但是你的代碼的結果是替換現有代碼的新元素,而這不是我正在尋找的。現有元素已具有類和屬性。另外,我想從幾個不同的元素向現有元素添加一些行爲(屬性,方法和事件處理程序)。 – jym

+0

那麼''.extend(A,B)'就是這樣做的。它將所有屬性(和方法)從'B'複製到'A'。也許你的問題是,當你試圖在元素本身上操作時,你試圖在jquery集上進行操作。嘗試:'$ .extend($('#myElement')。get(0),dummy.get(0))' – Lee

+0

當我對元素使用$ .extend()(即.get(0))時,我有一個JQuery錯誤:NO_MODIFICATION_ALLOWED_ERR:DOM異常7:嘗試修改不允許修改的對象。 – jym

相關問題