事件委托:
利用事件的冒泡传播机制完成的(当前元素的某个事件行为触发,那么其祖先元素的相关事件行为都会被触发)
假设:一个大容器中有N个子元素,这N个子元素在点击的时候都要做点事情,此时我们可以这样处理
方案一:给N个元素的点击行为都绑定方法,点击谁触发谁
方案二:给容器的点击行为绑定方法,这样不管点击N个元素中的哪一个,容器的点击行为也一定会触发,此时我们在容器中根据事件源不同,处理不同的事情即可 =>事件委托方案 (性能好)
常用树插件
zTree 是一个依靠 jQuery 实现的多功能 “树插件”。优异的性能、灵活的配置、多种功能的组合是 zTree 最大优点。
手写模拟数
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>zTree树形结构菜单</title>
<!-- import css -->
<link rel="stylesheet" href="css/reset.min.css">
<style>
* {
-webkit-user-select: none;
}
.container {
box-sizing: border-box;
margin: 20px auto;
padding: 10px;
width: 600px;
border: 1px dashed #AAA;
}
.level {
display: none;
font-size: 14px;
margin-left: 10px;
}
.level.level0 {
display: block;
margin-left: 0;
}
.level li {
position: relative;
padding-left: 15px;
line-height: 30px;
}
.level li .icon {
position: absolute;
left: 0;
top: 9px;
box-sizing: border-box;
width: 12px;
height: 12px;
line-height: 8px;
text-align: center;
border: 1px solid #AAA;
background: #EEE;
cursor: pointer;
}
.level li .icon:after {
display: block;
content: "+";
font-size: 12px;
font-style: normal;
}
.level li .icon.open:after {
content: "-";
}
.level li .title {
color: #000;
}
</style>
</head>
<body>
<div class="container">
<ul class="level level0" id="tree1"></ul>
</div>
<div class="container">
<ul class="level level0" id="tree2"></ul>
</div>
<!-- import js -->
<script src="js/jquery.min.js"></script>
<!-- 这是封装的插件 -->
<!-- <script src="js/ztree-plugin.js"></script> -->
<script>
// $.ajax({
// url: './data.json',
// method: 'get',
// success: result => {
// // $('#tree1').bind(result);
// // $('#tree2').bind(result);
// }
// });
</script>
<script>
// 1.动态绑定层级结构数据
let $tree1 = $('#tree1'),
count = 0;
let bind = function bind(result) {
count++;
let str = ``;
result.forEach(item => {
str += `<li>
<a href="#" class="title">${item.name}</a>
${item.children?`
<em class="icon ${item.open?'open':''}"></em>
<ul class="level level${count}" style="display: ${item.open?'block':'none'};">
${bind(item.children)}
</ul>
`:``}
</li>`;
});
count--;
return str;
};
$.ajax({
url: './data.json',
method: 'get',
success: result => {
let str = bind(result);
$tree1.html(str);
}
});
// 2.实现无限极展开(事件委托:可以处理动态绑定的元素)
$tree1.on('click', function (ev) {
let target = ev.target;
console.log(target.tagName);
//获取的标签名是大写的EM
if (target.tagName === 'EM') {
// 把原生JS对象变为JQ对象,目的是使用JQ中的方法
let $target = $(target),
$next = $target.next('ul');
// toggleXxx特点:和现在的值相反
$target.toggleClass('open');
$next.stop().slideToggle(200);
}
});
</script>
</body>
</html>
${ } 是模板板字符串拼接
向JQ中扩展插件(封装成插件形式)
~ function ($) {
function ztree(data) {
let count = 0,
$this = $(this); //=>$tree1
//=>数据绑定
let bindHTML = function (result) {
let str = ``;
result.forEach(item => {
count++;
let {
name,
open,
children
} = item;
str += `<li>
<a href="" class="title">${name}</a>
${children?`<em class="icon ${open?'open':''}"></em>
<ul class="level level${count}"
style="display:${open?'block':'none'}">
${bindHTML(children)}
</ul>`:``}
</li>`;
count--;
});
return str;
};
$this.html(bindHTML(data));
//=>基于事件委托实现点击操作
$this.click(function (ev) {
let target = ev.target,
$target = $(target),
$next = $target.next('ul');
if (target.tagName === 'EM') {
$target.toggleClass('open');
$next.stop().slideToggle(100);
}
});
}
// 向JQ中扩展插件
$.fn.extend({
ztree: ztree
});
}(jQuery);
// $tree1.ztree(从data.json中获取的数据)