Skip to content

Commit 7e9a714

Browse files
committed
Favour options.scanMode over scanDocument.
1 parent e907465 commit 7e9a714

4 files changed

Lines changed: 130 additions & 101 deletions

File tree

jquery.initialize.js

Lines changed: 45 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
* https://github.com/timpler/jquery.initialize/blob/master/LICENSE
88
*/
99
;(function ($) {
10-
10+
1111
"use strict";
12-
12+
1313
// MutationSelectorObserver represents a selector and it's associated initialization callback.
1414
var MutationSelectorObserver = function (selector, callback, options) {
1515
this.selector = selector;
@@ -23,7 +23,6 @@
2323
// List of MutationSelectorObservers.
2424
var msobservers = [];
2525
msobservers.initialize = function (selector, callback, options) {
26-
var target = options.target || document.documentElement;
2726

2827
// Wrap the callback so that we can ensure that it is only
2928
// called once per element.
@@ -36,7 +35,7 @@
3635
};
3736

3837
// See if the selector matches any elements already on the page.
39-
$(selector).each(callbackOnce);
38+
$(options.target).find(selector).each(callbackOnce);
4039

4140
// Then, add it to the list of selector observers.
4241
var msobserver = new MutationSelectorObserver(selector, callbackOnce, options)
@@ -45,45 +44,67 @@
4544
// The MutationObserver watches for when new elements are added to the DOM.
4645
var observer = new MutationObserver(function (mutations) {
4746

47+
var matches = [];
48+
function add(match) {
49+
matches.push(match);
50+
}
51+
4852
// For each mutation.
4953
for (var m = 0; m < mutations.length; m++) {
50-
console.log(mutations[m]);
5154

5255
// Do we observe this mutation type?
5356
if ($.inArray(mutations[m].type, mtypes) == -1) continue;
5457

55-
if (msobserver.options.scanDocument) {
58+
if (msobserver.options.scanMode == 'target') {
5659

5760
// Search within the observed node for elements matching the selector.
5861
// This can take longer, but we are more likely to find a match with
5962
// complex selectors.
60-
$(target).find(msobserver.selector)
61-
.each(msobserver.callback);
62-
} else {
63+
msobserver.options.target.querySelectorAll(msobserver.selector).forEach(add);
64+
} else if (msobserver.options.scanMode == 'descendants') {
6365

6466
// If this is an attributes mutation, then the target is the node upon which the mutation occurred.
6567
if (mutations[m].type == 'attributes') {
66-
$(mutations[m].target)
67-
.find(msobserver.selector) // Find any descendent nodes matching selector
68-
.addBack(msobserver.selector) // Include the mutated node itself.
69-
.each(msobserver.callback); // initialize with the callback.
70-
continue;
68+
mutations[m].target.querySelectorAll(msobserver.selector).forEach(add);
69+
if (mutations[m].target.matches(msobserver.selector)) {
70+
matches.push(mutations[m].target);
71+
}
72+
} else if (mutations[m].type == 'childList') {
73+
74+
// Otherwise, search for added nodes.
75+
// Search added nodes only for matching selectors.
76+
for (var n = 0; n < mutations[m].addedNodes.length; n++) {
77+
78+
mutations[m].addedNodes[n].querySelectorAll(msobserver.selector).forEach(add);
79+
if (mutations[m].addedNodes[n].matches(msobserver.selector)) {
80+
matches.push(mutations[m].addedNodes[n]);
81+
}
82+
}
7183
}
84+
} else if (msobserver.options.scanMode == 'exact') {
7285

73-
// Otherwise, search for added nodes.
74-
// Search added nodes only for matching selectors.
75-
for (var n = 0; n < mutations[m].addedNodes.length; n++) {
76-
$(mutations[m].addedNodes[n])
77-
.find(msobserver.selector) // Find any descendent nodes matching selector
78-
.addBack(msobserver.selector) // Include the added node itself.
79-
.each(msobserver.callback); // initialize with the callback.
86+
// Similar to descendant scan mode, except it will not search within child nodes.
87+
// This offers the most performance.
88+
if (mutations[m].type == 'attributes') {
89+
if (mutations[m].target.matches(msobserver.selector))
90+
matches.push(mutations[m].target);
91+
} else if (mutations[m].type == 'childList') {
92+
for (var n = 0; n < mutations[m].addedNodes.length; n++) {
93+
if (mutations[m].addedNodes[n].matches(msobserver.selector))
94+
matches.push(mutations[m].addedNodes[n]);
95+
}
8096
}
97+
8198
}
8299
}
100+
101+
matches.forEach(function(match) {
102+
$(match).each(msobserver.callback);
103+
});
83104
});
84105

85106
// Observe the target element.
86-
observer.observe(target, {childList: true, subtree: true, attributes: true});
107+
observer.observe(options.target, {childList: true, subtree: true, attributes: true});
87108
};
88109

89110
// Deprecated API (does not work with jQuery >= 3.1.1):
@@ -97,8 +118,8 @@
97118
};
98119

99120
$.initialize.defaults = {
100-
scanDocument: true,
101-
target: null // Defaults observe the entire document.
121+
scanMode: 'target', // Can be either: 'target', 'descendants', or 'exact'
122+
target: document.documentElement // Defaults observe the entire document.
102123
}
103124

104125
})(jQuery);

jquery.initialize.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test.html

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,56 @@
11
<!DOCTYPE html>
22
<html lang="en">
33
<head>
4-
<meta charset="UTF-8">
5-
<title>jquery.initialize test</title>
6-
<!-- Load MutationObserver and WeakMap polyfill for IE9 and 10 -->
7-
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
8-
<script src="jquery.initialize.js"></script>
4+
<meta charset="UTF-8">
5+
<title>jquery.initialize test</title>
6+
<!-- Load MutationObserver and WeakMap polyfill for IE9 and 10 -->
7+
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
8+
<script src="jquery.initialize.js"></script>
99
</head>
1010
<body>
1111

12-
<h2>We want every .initialize-me item to have color changed to blue by js - no matter how and when item with this class is added</h2>
12+
<h2>We want every .initialize-me item to have color changed to blue by js - no matter how and when item with this class is added</h2>
1313

14-
<button id="add-new">Add new item</button>
14+
<button id="add-new">Add new item</button>
1515

16-
<button id="change-class">Just add .initialize-me to .wrong-class</button>
16+
<button id="change-class">Just add .initialize-me to .wrong-class</button>
1717

1818
<hr>
1919

20-
<div class="wrong-class">
21-
This elem has .wrong-class and will not be initialized
22-
</div>
20+
<div class="wrong-class">
21+
This elem has .wrong-class and will not be initialized.
22+
</div>
2323

24-
<div class="initialize-me">
25-
This class has .initialize-me class so it will be initialized
26-
</div>
24+
<div class="initialize-me">
25+
This class has .initialize-me class so it will be initialized.
26+
</div>
2727

28-
<p>You can even add item with .initialize-me class via browser inspector - proper js will be executed on it just when you finish edition.</p>
28+
<p>You can even add item with .initialize-me class via browser inspector - proper js will be executed on it just when you finish edition.</p>
2929

30-
<script>
30+
<script>
3131

32-
$(function() {
33-
34-
// Deprecated API (does not work with jQuery >= 3.1.1):
35-
// $('.initialize-me').initialize(function() {
36-
// $(this).css('color', 'blue');
37-
// });
38-
39-
$.initialize('.initialize-me', function() {
40-
$(this).css('color', 'blue');
41-
});
32+
$(function() {
4233

43-
$('#add-new').click(function(){
44-
$('<div>').addClass('initialize-me').text('New item that was just appended to body and it’s color is automatically changed to blue without any additional js.').appendTo('body');
45-
});
34+
// Deprecated API (does not work with jQuery >= 3.1.1):
35+
// $('.initialize-me').initialize(function() {
36+
// $(this).css('color', 'blue');
37+
// });
4638

47-
$('#change-class').click(function(){
48-
$('.wrong-class').addClass('initialize-me');
49-
});
39+
$.initialize('.initialize-me', function() {
40+
$(this).css('color', 'blue');
41+
});
5042

51-
});
43+
$('#add-new').click(function(){
44+
$('<div>').addClass('initialize-me').text('New item that was just appended to body and it’s color is automatically changed to blue without any additional js.').appendTo('body');
45+
});
46+
47+
$('#change-class').click(function(){
48+
$('.wrong-class').addClass('initialize-me');
49+
});
50+
51+
});
52+
53+
</script>
5254

53-
</script>
54-
5555
</body>
5656
</html>

test2.html

Lines changed: 49 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,80 @@
11
<!DOCTYPE html>
22
<html lang="en">
33
<head>
4-
<meta charset="UTF-8">
5-
<title>jquery.initialize test</title>
6-
<!-- Load MutationObserver and WeakMap polyfill for IE9 and 10 -->
7-
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
8-
<script src="jquery.initialize.js"></script>
4+
<meta charset="UTF-8">
5+
<title>jquery.initialize test</title>
6+
<!-- Load MutationObserver and WeakMap polyfill for IE9 and 10 -->
7+
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
8+
<script src="jquery.initialize.js"></script>
99
</head>
1010
<body>
1111

12-
<h2>We want every .initialize-me item to have color changed to blue by js - no matter how and when item with this class is added</h2>
12+
<h2>We want every .initialize-me item to have color changed to blue by js - no matter how and when item with this class is added</h2>
1313

14-
<button id="add-new">Add new item</button>
14+
<button id="add-new">Add new item</button>
1515

16-
<button id="change-class">Just add .initialize-me to .wrong-class</button>
16+
<button id="change-class">Just add .initialize-me to .wrong-class</button>
1717

18-
<button id="add-outside">Add new item outside target element.</button>
18+
<button id="add-outside">Add new item outside target element.</button>
1919

2020
<hr>
2121

22-
<p>You can even add item with .initialize-me class via browser inspector - proper js will be executed on it just when you finish edition.</p>
22+
<p>You can even add item with .initialize-me class via browser inspector - proper js will be executed on it just when you finish edition.</p>
2323

2424
<div id="target-element" style="border: 1px dashed red; margin: 15px;">
2525
<div class="wrong-class">
26-
This elem has .wrong-class and will not be initialized
26+
This elem has .wrong-class and will not be initialized.
27+
<span>Sub element</span>
2728
</div>
2829

2930
<div class="initialize-me">
30-
This class has .initialize-me class so it will be initialized
31+
This class has .initialize-me class so it will be initialized.
32+
<span>Sub element</span>
3133
</div>
3234
</div>
3335

34-
<script>
35-
36-
$(function() {
37-
38-
// Deprecated API (does not work with jQuery >= 3.1.1):
39-
// $('.initialize-me').initialize(function() {
40-
// $(this).css('color', 'blue');
41-
// });
42-
43-
$.initialize.defaults.scanDocument = false;
44-
$.initialize.defaults.target = document.getElementById('target-element');
45-
$.initialize('.initialize-me', function() {
46-
$(this).css('color', 'blue');
47-
});
48-
49-
$('#add-new').click(function(){
50-
$('<div>')
36+
<div class="initialize-me">
37+
This item wont be initialised because it is outside the target element that is being observed.
38+
</div>
39+
40+
<script>
41+
42+
$(function() {
43+
44+
$.initialize.defaults.scanMode = 'descendants';
45+
$.initialize.defaults.target = document.getElementById('target-element');
46+
47+
$.initialize('.initialize-me', function() {
48+
$(this).css('color', 'blue');
49+
});
50+
51+
$.initialize('.initialize-me span', function() {
52+
$(this).css('background-color', 'blue');
53+
$(this).css('color', 'white');
54+
});
55+
56+
$('#add-new').click(function(){
57+
var $div = $('<div>')
5158
.addClass('initialize-me')
52-
.text('New item that was just appended to the target element and it’s color is automatically changed to blue without any additional js.')
53-
.appendTo('#target-element');
54-
});
59+
.text('New item that was just appended to the target element and it’s color is automatically changed to blue without any additional js. ')
60+
.append($('<span>Sub element</span>'));
61+
$div.appendTo('#target-element')
62+
});
5563

56-
$('#add-outside').click(function(){
57-
$('<div>')
64+
$('#add-outside').click(function(){
65+
$('<div>')
5866
.addClass('initialize-me')
5967
.text('This item wont be initialised because it was added outside the target element that is being observed.')
6068
.appendTo('body');
61-
});
69+
});
70+
71+
$('#change-class').click(function(){
72+
$('.wrong-class').addClass('initialize-me');
73+
});
6274

63-
$('#change-class').click(function(){
64-
$('.wrong-class').addClass('initialize-me');
65-
});
75+
});
6676

67-
});
77+
</script>
6878

69-
</script>
70-
7179
</body>
7280
</html>

0 commit comments

Comments
 (0)