目标描述
我想要的插件是类似jquery-ui的accordion插件
我想要的功能是这样的:
1. 此插件是否响应式应该是可选的,也就是宽度和高度是否自动自动填充父容器div
2. 可以自定义左边的图标,包括是否显示图标,以及自由的替换
3. 如果面板中没有内容,可以控制点击标题之后是跳转到另一个页面还是什么都不做
4. 如果面板中有内容,要支持ajax和标签这两种显示方式
5. 要支持事件,比如加载之前,展开面板之前,展开面板之后,ajax调用失败与成功等
6. 面板中的内容要支持自定义渲染
7. 一个页面调用多次要不冲突
8. 提供访问默认配置的方法
9. 提供全部展开、全部折叠或指定某一个面板展开/折叠的方法
参考jquery easyui的实现,应该是这样的:
属性
所有的属性都定义在jQuery.fn.{plugin}.defaults里面。例如,对话框属性定义在jQuery.fn.dialog.defaults里面。
事件
所有的事件(回调函数)也都定义在jQuery.fn.{plugin}.defaults里面。
方法
调用方法的语法:$('selector').plugin('method', parameter);
解释:
selector 是jQery对象选择器。
plugin 是插件的名称。
method 是相应插件现有的方法。
parameter 是参数对象,可以是一个对象、字符串等。
所有方法都定义在jQuery.fn.{plugin}.methods。每个方法都有2个参数:jq和param。第一个参数'jq'是必须的,这是指的jQuery对象。第二个参数'param'是指传入方法的实际参数。
目前需要的就这么多
基本的结构定义
html
1 <!DOCTYPE html>
2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <link type="text/css" rel="stylesheet" href="external/reset.css" /> 7 <link type="text/css" rel="stylesheet" href="jquery.km.accordion.css"/> 8 <style> 9 body { 10 padding: 20px 0 0 20px; 11 } 12 .box { 13 padding: 20px; 14 float: left; 15 } 16 .ac-box { 17 width: 300px; 18 } 19 20 .ac-box.border{ 21 border: 1px solid red; 22 } 23 p { 24 line-height: 25px; 25 text-indent: 2em; 26 padding: 0 5px; 27 } 28 </style> 29 </head> 30 <body> 31 <button id="tone">one</button> 32 <div class="box"> 33 <div class="ac-box border"> 34 <div id="one" class="km-accordion"> 35 <h3>第一段</h3> 36 <div> 37 <p>The Clarkson family lived in the country near Cambridge,about half a mile from the nearest village 38 and about a mile from the river.They had a big,old house with a beautiful garden,a lot of flowers 39 and many old.trees.</p> 40 </div> 41 <h3>第二段</h3> 42 <div> 43 <p> 44 One Thursday morning in July,Jackie came in from the garden.She was a tall,fat woman,thirty years 45 old.It was the hottest day of the year,but she wore a warm brown skirt and yellow shirt.She went 46 into the kitchen to get a drink of water.Just then the phone rang 47 </p> 48 </div> 49 <h3>第三段</h3> 50 <div> 51 <p> 52 Jackie put the phone down.She took a cigarette from her bag and began to smoke.She felt angry 53 because her sister always asked for money.Diane was twenty years old, the youngest in the family.She 54 lived in London,in one room of a big house.She wanted to be a singer.She sang very well but she 55 could never get work. 56 </p> 57 </div> 58 <h3>第四段</h3> 59 <div> 60 <p>'Mother,please wait a minute,'Jackie said.'Peter Hobbs came here this morning.He's very angry with 61 you about that letter.He lost his job,you know.Why did you write to his office?He wants to talk to 62 you about it.'</p> 63 </div> 64 </div> 65 </div> 66 </div> 67 68 <div class="box"> 69 <div class="ac-box border"> 70 <div id="two" class="km-accordion"> 71 <h3>第一段</h3> 72 <div> 73 <p> 74 “啊,公爵,热那亚和卢加现在是波拿巴家族的领地,不过,我得事先对您说,如果您不对我说我们这里处于战争状态,如果您还敢袒护这个基督的敌人(我确乎相信,他是一个基督的敌人)的种种卑劣行径和他一手造成的灾祸,那么我就不再管您了。您就不再是我的朋友,您就不再是,如您所说的,我的忠实的奴隶。啊,您好,您好。我看我正在吓唬您了,请坐,讲给我听。”</p> 75 </div> 76 <h3>第二段</h3> 77 <div> 78 <p> 79 一八○五年七月,遐迩闻名的安娜-帕夫洛夫娜-舍列尔——皇后玛丽亚-费奥多罗夫娜的宫廷女官和心腹,在欢迎首位莅临晚会的达官显要瓦西里公爵时说过这番话。安娜-帕夫洛夫娜一连咳嗽几天了。正如她所说,她身罹流行性感冒(那时候,流行性感冒是个新词,只有少数人才用它)。清早由一名红衣听差在分别发出的便函中,千篇一律地写道:“伯爵(或公爵),如您意下尚无任何可取的娱乐,如今日晚上这个可怜的女病人的症候不致使您过分惧怕,则请于七时至十时间莅临寒舍,不胜雀跃。安娜-舍列尔。” 80 </p> 81 </div> 82 <h3>第三段</h3> 83 <div> 84 <p> 85 他讲的是优雅的法语,我们的祖辈不仅借助它来说话,而且借助它来思考,他说起话来带有很平静的、长辈庇护晚辈时特有的腔调,那是上流社会和宫廷中德高望重的老年人独具的语调。他向安娜-帕夫洛夫娜跟前走来,把那洒满香水的闪闪发亮的秃头凑近她,吻吻她的手,就心平气和地坐到沙发上 86 </p> 87 </div> 88 <h3>第四段</h3> 89 <div> 90 <p> 91 她满腔热情,使她取得了社会地位。有时她甚至没有那种希冀,但为不辜负熟悉她的人们的期望,她还是要做一个满腔热情的人。安娜-帕夫洛夫娜脸上经常流露的冷淡的微笑,虽与她的憔悴的面容不相称,但却像娇生惯养的孩童那样,表示她经常意识到自己的微小缺点,不过她不想,也无法而且认为没有必要去把它改正'</p> 92 </div> 93 </div> 94 </div> 95 </div> 96 97 98 <script type="text/javascript" charset="UTF-8" src="./external/jquery.min.js"></script> 99 <script type="text/javascript" charset="UTF-8" src="jquery.km.accordion.js"></script> 100 <!--<script type="text/javascript" charset="UTF-8" src="one.js"></script>--> 101 <script type="text/javascript" charset="UTF-8"> 102 $(function () { 103 104 }); 105 </script> 106 </body> 107 </html>
css
1 @charset "UTF-8";
2
3 .km-accordion{ 4 overflow: hidden; 5 } 6 7 .km-accordion > h3{ 8 display: block; 9 background-color: #ededed; 10 padding: 6px 0 6px 25px; 11 border: 1px solid #d3d3d3; 12 cursor: pointer; 13 margin-top: 2px; 14 } 15 16 .km-accordion > h3:first-child{ 17 margin-top: 0; 18 } 19 20 .km-accordion > h3.active{ 21 background-color: #ffffff; 22 } 23 24 .km-accordion > div{ 25 display: none; 26 }
js
1 /**
2 * 折叠面板
3 *
4 */
5 ;(function ($, window, document, undefined) {
6 var classes = {
7 accordion: '.km-accordion',
8 accordionStr: 'km-accordion',
9
10 active: '.active',
11 activeStr: 'active'
12 };
13
14 var events = {
15 onSelect: '.kmAccordion',
16 onUnselect: 'onUnselect.kmAccordion',
17 onAdd: 'onAdd.kmAccordion',
18 onBeforeRemove: 'onBeforeRemove.kmAccordion',
19 onRemove: 'onRemove.kmAccordion'
20 };
21
22 function options(container){}
23
24 function panels(container){}
25
26 function resize (container){}
27
28 function getSelected (container){}
29
30 function getSelections(container){}
31
32 function getPanel(container,which){}
33
34 function getPanelIndex(container,panel){}
35
36 function select(container,which){}
37
38 function unselect(container,which){}
39
40 function selectAll(container,which){}
41
42 function unselectAll(container,which){}
43
44 function add(container,options){}
45
46 function remove(container,which){}
47
48 function createPanel(container,param){}
49
50 /**
51 * TODO 绑定事件
52 * @param jq
53 */
54 function bindEvent(jq) {}
55
56 /***
57 * TODO init
58 * 初始化
59 * @param jq
60 */
61 function init(jq) {}
62
63
64 $.fn.kmAccordion = function (options, param) {
65 if (typeof options === 'string') {
66 return $.fn.kmAccordion.methods[options](this, param);
67 }
68
69 var _opts = $.extend({}, $.fn.kmAccordion.defaults, options);
70 var jq = this;
71 jq.config = _opts;
72
73 return this.each(function () {
74 // 插件初始化
75 init(jq);
76 });
77 };
78
79 $.fn.kmAccordion.methods = {
80 /**
81 * TODO 返回当前折叠面板的属性
82 * @param jq
83 */
84 options: function (jq) {},
85
86 /**
87 * TODO 获取所有面板
88 * @param jq
89 */
90 panels : function(jq){},
91
92 /**
93 * TODO 调整折叠面板大小
94 * @param jq
95 */
96 resize : function (jq) {},
97
98 /**
99 * TODO 获取选中的面板
100 * @param jq
101 */
102 getSelected: function (jq) {},
103
104 /**
105 * TODO 获取所有选中的面板
106 * @param jq
107 */
108 getSelections : function (jq) {},
109
110 /**
111 * TODO 获取指定的面板
112 * @param jq
113 * @param which 面板的标题或索引
114 */
115 getPanel: function ( jq,which) {},
116
117 /**
118 * TODO 获取指定面板的索引
119 * @param jq
120 * @param panel
121 */
122 getPanelIndex : function(jq,panel){},
123
124 /**
125 * TODO 选择指定面板
126 * @param jq
127 * @param which 面板的标题或索引
128 */
129 select: function ( jq,which) {},
130
131 /**
132 * TODO 取消选择指定面板
133 * @param jq
134 * @param which 面板标题或索引
135 */
136 unselect: function (jq, which) {},
137
138 /**
139 * TODO 选择所有面板
140 * @param jq
141 */
142 selectAll : function(jq){},
143
144 /**
145 * TODO 取消选择所有面板
146 * @param jq
147 */
148 unselectAll : function(jq){},
149
150 /**
151 * TODO 添加一个新面板
152 * 默认情况下,新增的面板会被选中
153 * @param jq
154 * @param options 面板配置项
155 */
156 add: function (jq,options) {},
157
158 /**
159 * TODO 移除指定面板
160 * @param jq
161 * @param which 面板标题或索引
162 */
163 remove: function (jq, which) {}
164 };
165
166 $.fn.kmAccordion.defaults = {
167 /**
168 * 宽度,可以是百分比【相对父容器(div)】、数字(像素)、auto,默认为auto
169 */
170 width: 'auto',
171 /**
172 * 高度,可以是百分比【相对父容器(div)】、数字(像素)、auto,默认为auto
173 */
174 height: 'auto',
175 /**
176 * 如果为true,则自适应父容器【div】,默认为true
177 */
178 fit: true,
179 /**
180 * 是否显示边框,默认为false
181 */
182 border: false,
183 /**
184 * 边框样式,字面量对象形式
185 */
186 borderStyle: null,
187 /**
188 * 定义在展开和折叠的时候是否显示动画效果。默认:true
189 */
190 animate: true,
191 /**
192 * 如果为true,则可以同时展开多个面板
193 */
194 multiple: false,
195 /**
196 * 初始化时默认选中的面板索引号,如果为-1,则都不展开。默认:0
197 */
198 selected: 0,
199 /**
200 * 设置面板标题对齐方式,可用值:'left', 'center', 'right',默认为'left'
201 */
202 halign: 'left',
203
204 /**
205 * TODO 用户选择面板时触发
206 * @param title
207 * @param index
208 */
209 onSelect: function (title, index) {},
210
211 /**
212 * TODO 面板被取消选择时触发
213 * @param title
214 * @param index
215 */
216 onUnselect: function (title, index) {},
217
218 /**
219 * TODO 添加新面板时触发
220 * @param title
221 * @param index
222 */
223 onAdd: function (title, index) {},
224
225 /**
226 * TODO 移除面板之前触发,返回false可取消移除操作
227 * @param title
228 * @param index
229 */
230 onBeforeRemove: function (title, index) {},
231
232 /**
233 * TODO 面板被移除时触发
234 * @param title
235 * @param index
236 */
237 onRemove: function (title, index) {}
238 };
239 })(jQuery, window, document);
默认效果
未定义
1. 图标
2. 标题上的按钮
3. 面板。其实我现在只是实现一个容器,中间的面板还没做,由于完全参考easyui来做工作量实在是有点大,现在只能实现一个基本的架子
4. 远程加载。远程加载涉及到容器本身与面板内容的远程加载,且这又涉及到组件的继承问题,所以只能滞后了
初步实现
js
1 /**
2 * 折叠面板
3 *
4 */
5 ;(function ($, window, document, undefined) {
6 var classes = {
7 accordion: '.km-accordion',
8 accordionStr: 'km-accordion',
9
10 active: '.active',
11 activeStr: 'active'
12 };
13
14 var events = {
15 onSelect: '.kmAccordion',
16 onUnselect: 'onUnselect.kmAccordion',
17 onAdd: 'onAdd.kmAccordion',
18 onBeforeRemove: 'onBeforeRemove.kmAccordion',
19 onRemove: 'onRemove.kmAccordion'
20 };
21
22 function options(container) {
23 }
24
25 function panels(container) {
26 }
27
28 function resize(container) {
29 }
30
31 function getSelected(container) {
32 }
33
34 function getSelections(container) {
35 }
36
37 /**
38 * 根据标题或索引返回指定的面板
39 * @param container
40 * @param which
41 */
42 function getPanel(container, which) {
43 var panelAndParam = [];
44 panelAndParam[0] = null;
45 // TODO 优化选择
46 if ('string' === typeof which) {
47 panelAndParam[0] = container.children("h3[title='" which "']");
48 panelAndParam[1] = which;
49
50 /**
51 * TODO 工具类 增强jquery.index方法,返回当前元素在父元素中相同的所有元素集合中的索引
52 * 如
53 * <div>
54 * <h3 id="h1"></h3>
55 * <div></div>
56 * <h3 id="h2"></h3>
57 * <div></div>
58 * * <h3 id="h3"></h3>
59 * <div></div>
60 * <h3 id="h4"></h3>
61 * <div></div>
62 * </div>
63 * h3#h2 应该返回1而不是2
64 */
65 panelAndParam[2] = panelAndParam[0].index() / 2;
66 } else if ("number" === typeof which) {
67 panelAndParam[0] = container.children('h3').eq(which);
68 panelAndParam[1] = panelAndParam[0].text();
69 panelAndParam[2] = which;
70 }
71 return panelAndParam;
72 }
73
74 function getPanelIndex(container, panel) {
75 }
76
77
78 /**
79 * 选择指定面板
80 * @param container
81 * @param which 面板标题或索引
82 */
83 function select(container, which) {
84 var panelAndParam = getPanel(container, which);
85 var titleElement = panelAndParam[0];
86
87 if (titleElement) {
88 var title = panelAndParam[1];
89 var index = panelAndParam[2];
90 var animate = container.config.animate;
91 titleElement.addClass(classes.activeStr);
92 if (animate) {
93 titleElement.next('div').slideDown();
94 } else {
95 titleElement.next('div').show();
96 }
97 if (!container.config.multiple) {
98 titleElement.siblings('h3').each(function (i) {
99 unselect(container, $(this).text());
100 });
101 }
102 container.config.onSelect.call(this, title, index);
103 }
104 }
105
106 /**
107 * 取消选择指定面板
108 * @param container
109 * @param which 面板标题或索引
110 */
111 function unselect(container, which) {
112 var panelAndParam = getPanel(container, which);
113 var titleElement = panelAndParam[0];
114 if (titleElement) {
115 var title = panelAndParam[1];
116 var index = panelAndParam[2];
117 var animate = container.config.animate;
118 titleElement.removeClass(classes.activeStr);
119 if (animate) {
120 titleElement.next('div').slideUp();
121 } else {
122 titleElement.next('div').hide();
123 }
124 container.config.onUnselect.call(this, title, index);
125 }
126 }
127
128 function selectAll(container, which) {
129 }
130
131 function unselectAll(container, which) {
132 }
133
134 function add(container, options) {
135 }
136
137 function remove(container, which) {
138 }
139
140 function createPanel(container, param) {
141 }
142
143 /**
144 * 绑定事件
145 * @param jq
146 */
147 function bindEvent(jq) {
148 jq.on(events.onSelect, jq.config.onSelect);
149 jq.on(events.onUnselect, jq.onUnselect);
150 jq.on(events.onAdd, jq.config.onAdd);
151 jq.on(events.onBeforeRemove, jq.config.onBeforeRemove);
152 jq.on(events.onRemove, jq.config.onRemove);
153 }
154
155 /**
156 * 初始化标题
157 * @param jq
158 */
159 function initTitle(jq) {
160 jq.children('h3').each(function () {
161 $(this).attr('title', $(this).text());
162 });
163 var halign = jq.config.halign;
164 // 设置标题
165 if ('left' !== halign) {
166 switch (halign) {
167 case 'center': {
168 jq.find('h3').css({
169 'padding-left': '0',
170 'padding-right': '0',
171 'text-align': 'center'
172 });
173 break;
174 }
175 case 'right': {
176 jq.find('h3').css({
177 'padding-left': '0',
178 'padding-right': '25px',
179 'text-align': 'right'
180 });
181 break;
182 }
183 default: {
184 break;
185 }
186 }
187 }
188 }
189
190 /**
191 * 初始化选择面板
192 * @param jq
193 */
194 function initSelect(jq) {
195 var selected = jq.config.selected;
196 if (0 <= selected && selected < jq.children('h3').length) {
197 select(jq, selected);
198 }
199 }
200
201 /**
202 * 初始化边框样式
203 * @param jq
204 */
205 function initBorder(jq) {
206 if (jq.config.border) {
207 var borderStyle = jq.config.borderStyle;
208 jq.css(borderStyle);
209 jq.attr('offsetWidth', jq.parent().width()).attr('offsetHeight', jq.parent().height());
210 }
211 }
212
213 /**
214 * 初始化高度与宽度
215 * @param jq
216 */
217 function initWidthAndHeight(jq) {
218 // 如果fit为true,则忽略宽度与高度的设置
219 if (jq.config.fit) {
220 return;
221 }
222
223 if ('auto' !== jq.config.width) {
224 jq.css({
225 'width': jq.config.width 'px'
226 });
227 }
228
229 if ('auto' !== jq.config.height) {
230 jq.css({
231 'height': jq.config.height 'px'
232 });
233 }
234 }
235
236 function initStyle(jq) {
237 initTitle(jq);
238 initBorder(jq);
239 initSelect(jq);
240 initWidthAndHeight(jq);
241 }
242
243
244 /***
245 * TODO init
246 * 初始化
247 * @param jq
248 */
249 function init(jq) {
250 initStyle(jq);
251 bindEvent(jq);
252 jq.children('h3').click(function () {
253 var titleClass = $(this).attr('class');
254 // TODO 工具类 判断某个元素是否包含给定的class样式
255 if (undefined === titleClass || titleClass.indexOf(classes) < 0) {
256 console.log('click:select');
257 select(jq, $(this).text());
258 }
259
260 if (undefined !== titleClass && titleClass.indexOf(classes.activeStr) >= 0) {
261 console.log('click:unselect');
262 unselect(jq, $(this).text());
263 }
264 })
265 }
266
267
268 $.fn.kmAccordion = function (options, param) {
269 if (typeof options === 'string') {
270 return $.fn.kmAccordion.methods[options](this, param);
271 }
272
273 var _opts = $.extend({}, $.fn.kmAccordion.defaults, options);
274 var jq = this;
275 jq.config = _opts;
276
277 return this.each(function () {
278 // 插件初始化
279 init(jq);
280 });
281 };
282
283
284 $.fn.kmAccordion.methods = {
285 /**
286 * 返回当前折叠面板的属性
287 * @param jq
288 */
289 options: function (jq) {
290 return jq.config;
291 },
292
293 /**
294 * TODO 获取所有面板
295 * @param jq
296 */
297 panels: function (jq) {
298 },
299
300 /**
301 * TODO 调整折叠面板大小
302 * @param jq
303 */
304 resize: function (jq) {
305 },
306
307 /**
308 * TODO 获取选中的面板
309 * @param jq
310 */
311 getSelected: function (jq) {
312 },
313
314 /**
315 * TODO 获取所有选中的面板
316 * @param jq
317 */
318 getSelections: function (jq) {
319 },
320
321 /**
322 * TODO 获取指定的面板
323 * @param jq
324 * @param which 面板的标题或索引
325 */
326 getPanel: function (jq, which) {
327 return jq.each(function () {
328 getPanel(jq, which);
329 });
330 },
331
332 /**
333 * TODO 获取指定面板的索引
334 * @param jq
335 * @param panel
336 */
337 getPanelIndex: function (jq, panel) {
338 },
339
340 /**
341 * 选择指定面板
342 * @param jq
343 * @param which 面板的标题或索引
344 */
345 select: function (jq, which) {
346 return jq.each(function () {
347 select(jq, which);
348 });
349 },
350
351 /**
352 * TODO 取消选择指定面板
353 * @param jq
354 * @param which 面板标题或索引
355 */
356 unselect: function (jq, which) {
357 return jq.each(function () {
358 unselect(jq, which);
359 });
360 },
361
362 /**
363 * TODO 选择所有面板
364 * @param jq
365 */
366 selectAll: function (jq) {
367 },
368
369 /**
370 * TODO 取消选择所有面板
371 * @param jq
372 */
373 unselectAll: function (jq) {
374 },
375
376 /**
377 * TODO 添加一个新面板
378 * 默认情况下,新增的面板会被选中
379 * @param jq
380 * @param options 面板配置项
381 */
382 add: function (jq, options) {
383 },
384
385 /**
386 * TODO 移除指定面板
387 * @param jq
388 * @param which 面板标题或索引
389 */
390 remove: function (jq, which) {
391 }
392 };
393
394 $.fn.kmAccordion.defaults = {
395 /**
396 * 宽度,可以是百分比【相对父容器(div)】、数字(像素)、auto,默认为auto
397 */
398 width: 'auto',
399 /**
400 * 高度,可以是百分比【相对父容器(div)】、数字(像素)、auto,默认为auto
401 */
402 height: 'auto',
403 /**
404 * 如果为true,则自适应父容器【div】,默认为true
405 */
406 fit: true,
407 /**
408 * 是否显示边框,默认为false
409 */
410 border: false,
411 /**
412 * 边框样式,字面量对象形式
413 */
414 borderStyle: null,
415 /**
416 * 定义在展开和折叠的时候是否显示动画效果。默认:true
417 */
418 animate: true,
419 /**
420 * 如果为true,则可以同时展开多个面板
421 */
422 multiple: false,
423 /**
424 * 初始化时默认选中的面板索引号,如果为-1,则都不展开。默认:0
425 */
426 selected: 0,
427 /**
428 * 设置面板标题对齐方式,可用值:'left', 'center', 'right',默认为'left'
429 */
430 halign: 'left',
431
432 /**
433 * 用户选择面板时触发
434 * @param title
435 * @param index
436 */
437 onSelect: function (title, index) {
438 },
439
440 /**
441 * 面板被取消选择时触发
442 * @param title
443 * @param index
444 */
445 onUnselect: function (title, index) {
446 },
447
448 /**
449 * TODO 添加新面板时触发
450 * @param title
451 * @param index
452 */
453 onAdd: function (title, index) {
454 },
455
456 /**
457 * TODO 移除面板之前触发,返回false可取消移除操作
458 * @param title
459 * @param index
460 */
461 onBeforeRemove: function (title, index) {
462 },
463
464 /**
465 * TODO 面板被移除时触发
466 * @param title
467 * @param index
468 */
469 onRemove: function (title, index) {
470 }
471 };
472 })(jQuery, window, document);
调用
现在的调用其实和easyui没有什么区别了
更进一步
现在已经有展开/收缩的能力了,其中的某些方法并未实现,比如add和remove方法,原因在于这涉及到远程加载与面板中内容加载的问题。
除了通过监听click事件之外,还可以使用MutationObserver来监听元素属性的变化,这样当元素的class发生变化的时候,就可以接收到事件,然后在监听事件的处理中解决,如:
1 <div class="box border">
2 <span id="one" class="red" title="hello">hello world</span>
3 </div>
4
5
6 <script type="text/javascript" charset="UTF-8" src="./external/jquery.min.js"></script>
7 <script type="text/javascript" charset="UTF-8" src="one.js"></script>
8 <script type="text/javascript" charset="UTF-8">
9 $(function () {
10 var MutationObserver = window.MutationObserver;
11 var target = document.querySelector('#one');
12 var observer = new MutationObserver(function (mutations) {
13 mutations.forEach(function (mutation) {
14 console.log(mutation);
15 $(mutation.target).trigger('click');
16 })
17 });
18
19 var config = {attributes: true, attributeFilter:['class']};
20
21 observer.observe(target,config);
22
23 $('#one').click(function () {
24 console.log('click');
25 });
26
27
28 });
29 </script>
这样可以完成组件之间的解耦,就不会看到满屏的jq.xxx.('xxx');了。然而当组件的属性变化比较多的时候,或者组件之间的调用关系比较复杂的时候,这种方法写起来就会极其的麻烦,我觉得当元素属性变化比较少的时候用这种方法还是很好的。或者在编辑器这种应用中也是非常好用的。
可以尝试一下