JQuery如何使用包含事件处理程序的另一个元素扩展元素?

时间:2011-09-20 04:27:52

标签: jquery event-handling extend

是否有解决方案来创建具有其属性,方法和事件处理程序的虚拟元素,并使用它扩展现有元素? 例如:

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

然后,

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

现在,$('#myElement')除了它自己之外还有dummyElement的属性,方法和事件处理程序。

有可能吗?我怎么能用JQuery做到这一点?

谢谢

3 个答案:

答案 0 :(得分: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) { // ... }
    }
});

答案 1 :(得分: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元素复制到另一个HTML元素,那么{ {1}}是工作的工具。确保您正在操作HTML元素本身,而不是Jquery设置对象。这看起来像这样:

$.extend(...)

答案 2 :(得分:0)

确定。感谢不同的答案,特别是来自 Lee 。 似乎$.extend(...) jQuery方法不是为了从另一个DOM元素扩展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插件。此插件包含一个使用指定扩展名扩展source元素的方法:

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

3)最后,我扩展了一些jQuery元素。请注意,在以下示例中,我通过链接someElement插件来扩展与myObjExtension1类匹配的元素,首先使用myObjExtension2,然后使用extendWith(...)。方法:

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

现在,所有myObjExtension1myObjExtension2数据属性,方法属性和事件处理程序都可以从我的$('。someElement')元素中获得。例如:

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