forked from ehynds/jquery-create-event
-
Notifications
You must be signed in to change notification settings - Fork 0
/
jquery.create.js
118 lines (93 loc) · 3.06 KB
/
jquery.create.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// written by eric hynds (erichynds.com)
// http://www.erichynds.com/jquery/jquery-create-event/
// version 1.4 - 10/12/2010
(function($, _domManip, _html){
var selectors = [], gen = [], guid = 0, old = {};
$.event.special.create = {
add: function( data ){
selectors.push( data.selector );
},
// won't fire in 1.4.2 http://dev.jquery.com/ticket/6202
remove: function( data ){
var len = selectors.length;
while( len-- ){
if( selectors[len] === data.selector ){
selectors.splice(len, 1);
break;
}
}
}
};
// deal with 99% of DOM manip methods
$.fn.domManip = function( args, table, callback ){
// if no create events are bound, just fire the original domManip method
if( !selectors.length || $.isFunction(args[0]) ){
return _domManip.apply( this, arguments );
}
return logic.call( this, _domManip, arguments );
};
// deal with the remaining 1% (html method)
$.fn.html = function( value ){
// if no create events are bound, html() is being called as a setter,
// or the value is a function, fire the original and peace out. only string values use innerHTML;
// function values use append() which is covered by $.fn.domManip
if( !selectors.length || $.isFunction(value) || typeof value === "undefined" || !value.length ){
return _html.apply( this, arguments );
}
// make value an array
arguments[0] = [value];
return logic.call( this, _html, arguments );
};
function logic( method, args ){
var node, nodes = args[0], html = $(), numSelectors = selectors.length, matches = [];
// crawl through the html structure passed in looking for matching elements.
for( var i=0, len=nodes.length; i<len; i++ ){
node = $(nodes[i]);
if( !node.length ){
continue;
}
(function walk( element ){
element = element || node[0].parentNode;
var cur = (element ? element.firstChild : node[0]);
while(cur !== null){
for( var x=0; x<numSelectors; x++ ){
if( $(cur).is(selectors[x]) ){
if( !cur.id ){
cur.id = "jqcreateevt"+(++guid);
gen.push(cur.id); // remember that this ID was generated
}
// remember this match
matches.push(cur.id);
}
}
walk( cur );
cur = cur.nextSibling;
}
})();
// the html we started with, but with ids attached to elements
// bound with create.
html = html.add( node );
}
// overwrite the passed in html with the new html
args[0] = html;
// inject elems into DOM
var ret = method.apply(this, args);
// for elements with a create event...
$.each(matches, function(i,id){
var elem = document.getElementById( id );
if( elem ){
// cleanup generated IDs
if( $.inArray(id, gen) !== -1 ){
elem.removeAttribute("id");
}
// double check to make sure the event hasn't already fired.
// can happen with wrap()
if( !$.data( elem, "jqcreateevt") ){
$.event.trigger("create", {}, elem);
$.data(elem, "jqcreateevt", true);
}
}
});
return ret;
}
})(jQuery, jQuery.fn.domManip, jQuery.fn.html);