JsViews树形控件展开后触发二次点击事件求助
解决JsViews树形控件嵌套结构下的二次点击折叠问题
我之前调整JsViews树形结构模板时也碰到过一模一样的问题!这事儿根源就是事件冒泡——你点击.toggle按钮时,事件会向上冒泡到父级的<li>元素,而JsViews的树形标签默认可能会给<li>绑定展开/折叠的触发逻辑,结果一次点击触发了两次expanded状态切换,刚展开就立刻折叠回去了。
问题分析
你的模板把<ul>嵌套在<li>内部的结构是完全正确的,但事件传递机制在这里踩了坑:
- 点击
.toggle时,首先触发你期望的状态切换(展开) - 事件冒泡到
<li>后,树形控件的默认点击逻辑又触发了一次状态切换(折叠) - 最终表现就是看起来点击没生效,或者刚展开就立刻收起来
两种可行的解决方案
方案1:阻止Toggle元素的事件冒泡
直接在.toggle的点击事件里阻止冒泡,不让事件传递到<li>。修改你的模板,给toggle添加一个点击处理函数:
template: '<li>' + '{{if folders && folders.length}}' + '<span class="toggle" data-link="onclick{:~stopBubble}">{^{:expanded ? "-" : "+"}}</span>' + '{{else}}' + '<span class="spacer">•</span>' + '{{/if}}' + '{{>name}}' + '{^{if expanded}}' + '<ul>' + '{{for folders}}' + '{^{tree/}}' + '{{/for}}' + '</ul>' + '{{/if}}' + '</li>'
然后在你的JsViews标签配置里添加辅助函数:
$.views.tags({ tree: { template: yourTemplate, helpers: { stopBubble: function(e) { e.stopPropagation(); // 阻止事件向上冒泡 e.preventDefault(); // 可选,根据需要是否阻止默认行为 } }, // 其他树形控件的配置... } });
方案2:修改树形控件的触发逻辑
如果不想用阻止冒泡的方式,也可以直接修改树形控件的点击触发条件,让它只响应.toggle元素的点击,而不是整个<li>。在注册tree标签时,自定义点击处理:
$.views.tags({ tree: { template: yourTemplate, onTap: function(e, data) { // 只在点击.toggle元素时才切换展开状态 if ($(e.target).hasClass('toggle')) { const item = data.view.data; item.expanded = !item.expanded; } // 同样可以在这里阻止冒泡,避免其他冲突 e.stopPropagation(); } // 其他树形控件的配置... } });
验证效果
两种方案都能解决二次点击的问题,你可以根据自己的代码结构选择更合适的一种。测试时注意点击.toggle和<li>的其他区域,确保只有点击toggle时才触发展开/折叠,其他区域不会误触发。
内容的提问来源于stack exchange,提问作者Russ
相关产品推荐
相关产品推荐

