How JQuery could extend an element with another one containing event handlers?
Is there a solution to create a dummy element with its properties, methods and event handlers and extend an existing element with it ? For example :
var dummyElement = $('<div />', {
// properties
...
// methods
...
// event handlers
...
});
and then,
$.extend( $('#myElement'), dummyElement );
Now, $('#m开发者_开发百科yElement') has the dummyElement's properties, methods and event handlers, in addition to its own.
Is it possible? How could I do that with JQuery ?
Thank you
IMO you don't need a dummy element at all. In following example I demonstrates a simple way to create an element in pure javascript.
Source Code
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;
}
You can rewrite the above code with jQuery to extend your element, instead of creating a new one.
Usage
Util.createElement({
tag: 'input',
type: 'checkbox',
checked: this.checked,
events: {
change: function(e) { // ... }
}
});
Check out jQuery's clone()
method. In conjunction with replaceWith()
, I think you can accomplish something close to (but not exactly) what you're looking for:
// 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) );
Note: the code you've used when creating dummyElement
in your example, is not a valid form of the jQuery
function. As far as I know, you can't add properties, methods, and handlers by just passing them as a second argument to the jQuery function. If you do pass a second argument, jQuery will interpret this as a context in which to resolve the selector. I've shown an example of adding a click handler, and an attribute.
Edit: If you're just trying to copy object properties (as you said: "properties", "methods", and "event handlers") from one HTML Element to another, then $.extend(...)
is the tool for the job. Just be sure you're operating on the HTML Elements themselves, not the Jquery set objects. That'll look something like this:
var dummy = $('<div />');
var myElement = $('#myElement');
$.extend(myElement.get(0), dummy.get(0));
Ok. Thanks to the different answers, particularly from Lee.
It seems that the $.extend(...)
jQuery method is not designed to extend a DOM element from another one. But it can extend a DOM element from an object. Here is a solution to do that :
1) First I create the extension objects. Each of these extensions must have an initExtension()
method defined. Here is an example for creating two extension objects :
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) In order to extend easily all the elements I need to extend, I created a little jQuery plug-in. This plug-in contains one method that extend the source element with the specified extension:
(function($){
$.fn.extendWith = function( objExtension ) {
this.each(
function(index) {
$.extend( this, objExtension );
this.initExtension();
}
);
return this; // jQuery chaining
}
})(jQuery);
3) Finally, I extend some jQuery elements. Note that in the following example, I extend the elements that match the someElement
class, first with the myObjExtension1
and then with the myObjExtension2
, by chaining the extendWith(...)
plug-in method:
$('.someElement').extendWith( myObjExtension1 ).extendWith( myObjExtension2 );
Now, all the myObjExtension1
and myObjExtension2
data properties, method properties and event handlers are available from my $('.someElement') elements. Example:
$('.someElement').each( function() {
this.doSomething();
this.doMore();
});
精彩评论