目标描述
我想要的插件是类似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 '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 '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');了。然而当组件的属性变化比较多的时候,或者组件之间的调用关系比较复杂的时候,这种方法写起来就会极其的麻烦,我觉得当元素属性变化比较少的时候用这种方法还是很好的。或者在编辑器这种应用中也是非常好用的。
可以尝试一下