最近,一个同事跟我求助,说在页面点击按钮,向一个 div 添加 select 标签,根据 select 选中项取值,但取不到!如下:
<button id="btn">btn</button>
<div id="box"></div>
怎么办?
我们先来做几个测试:
1、点击 button,向 div 里添加多个未来按钮,点击某个未来按钮,删除本身!
按照常规操作,应该就是这样写的:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>click & addEventListener</title>
</head>
<body>
<button id="demo1">button</button>
<div id="box1"></div>
<button id="demo2">button</button>
<div id="box2"></div>
<script src="https://code.jquery.com/jquery-3.0.0.min.js"></script>
<script>
//demo1
$("#demo1").click(function(){
$("#box1").append("<button>click 未来元素</button>")
});
$("#box1 button").click(function(){
$(this).remove();
});
//demo2
var btnWrap = document.getElementById("demo2");
btnWrap.onclick = function(){
var elem = document.createElement("button");
elem.innerText = "onclick 未来元素";
document.getElementById("box2").appendChild(elem);
};
var btns = btnWrap.getElementsByTagName("button");
for (var i = 0; i < btns.length; i++) {
btns[i].parentNode.removeChild(btns[this.index]);
};
</script>
</body>
</html>
结果,能添加未来按钮,但点击这些按钮无效!
先不急答案,再换个思路测试下!
2、换个思路,点击按钮,向父元素添加未来按钮,点未来按钮,添加更多按钮
与上例不同的是,在点击按钮时,将事件绑定到父元素上,想想有什么不一样!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>click & addEventListener</title>
<body>
<div id="demo3"><button>button</button></div>
<div id="demo4"><button>button</button></div>
<script src="https://code.jquery.com/jquery-3.0.0.min.js"></script>
<script>
//demo3 这里不能直接用 click,避免点击空白区域,错误添加。
$("#demo3").on("click","button",function(){
$(this).parent().append("<button>on 未来元素"+$("#demo3 button").length+"</button>");
//这里的this,指的是当前点击的button
});
//demo4
var btnWrap2 = document.getElementById("demo4");
btnWrap2.onclick =function(e){ //同样:btnWrap2.addEventListener("click",function(e){ ... }
if(e.target === btnWrap2){ //点击空白区域,返回
return;
}
var elem = document.createElement("button");
elem.innerText = "onclick 未来元素"+ btnWrap2.children.length;
this.appendChild(elem);
}
</script>
</body>
</html>
结果,可行!
子元素也是父元素的一部分,点击父元素时返回,子元素时执行操作!
3、再回到第一个测试,同样将事件绑定到父元素上。行了!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>click & addEventListener</title>
</head>
<body>
<button id="demo5">button</button>
<div id="box5"></div>
<button id="demo6">button</button>
<div id="box6"></div>
<script src="https://code.jquery.com/jquery-3.0.0.min.js"></script>
<script>
//demo5
$("#demo5").on("click",function(){
$("#box5").append("<button>click未来元素"+ $("#box5 button").length +"</button>");
});
$("#box5").click(function(e){ //同样:$("#box5").on("click","button",function(e){
e.target.remove(); //同样可以:this.remove();
});
//demo6
var btnWrap3 = document.getElementById("demo6");
var btns3 = document.getElementById("box6");
btnWrap3.onclick = function(){
var elem = document.createElement("button");
elem.innerText = "onclick 未来元素"+btns3.children.length;
document.getElementById("box6").appendChild(elem);
};
btns3.onclick = function(e){//同样:btns3.addEventListener("click",function(e){
for (var i = 0; i < btns3.children.length; i++) {
btns3.children[i].index = i;
};
e.target.parentNode.removeChild(btns3.children[e.target.index]);
};
</script>
</body>
</html>
回到文章开头的问题,是不是有答案了!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>click & addEventListener</title>
<style>
.item div{display: inline-block;}
</style>
</head>
<body>
<div class="item">
<button id="btn1">btn</button>
<div id="box1"></div>
<span id="tip1"></span>
</div>
<div class="item">
<button id="btn2">btn</button>
<div id="box2"></div>
<span id="tip2"></span>
</div>
<script src="https://code.jquery.com/jquery-3.0.0.min.js"></script>
<script>
// jQuery
var cities = "<select><option selected='selected'>北京</option><option>上海</option><option>广州</option><option>深圳</option></select>";
$("#btn1").click(function(){
$("#box1").append(cities);
})
$("#box1").on("change","select",function(e){
var ret = $(this).find("option:selected").val(); //this 指 select
//同样:var ret = $(e.target).find("option:selected").val();
//同样:var ret = $(e.currentTarget).find("option:selected").val();
$("#tip1").text(ret);
})
//JS
var box = document.getElementById("box2");
document.getElementById("btn2").onclick = function(){
var elem = document.createElement("select");
elem.options.add(new Option("北京","1"));
elem.options.add(new Option("上海","2"));
elem.options.add(new Option("广州","3"));
elem.options.add(new Option("深圳","4"));
box.appendChild(elem) ;
}
box.onchange= function(e){
//同样: box.addEventListener("change",function(e){ //e.target 指 select ,this、e.currentTarget 指 box2
var ret = e.target.options[e.target.selectedIndex].text;
document.getElementById("tip2").innerText = ret;
};
</script>
</body>
</html>
最后说一下,jQuery 1.7 起,用 on 方法替代了 bind、live 和 delegate 方法,所以测试的 jQuery 绑定只用了 on 方法。