功能描述:
1、单击输入框,弹出弹层,再点击弹层隐藏
2、单击空白区,弹层隐藏
3、单击弹层中的地区,把对应值填入到输入框中,弹层隐藏
功能实现:我设置了开关,单击输入框的时候,开关取反,单击弹层内的值时,开关为false,嗯这些都运行正常,和我想要达到的目的也是一样的,但是,在我想要实现功能2时遇到了问题:
问题描述:
1、如果我给document添加点击事件的时候,不把开关设置为false,会产生的问题是:第一次单击输入框的时候,开关为true,然后我直接点击空白区域,弹出层隐藏(此时开关还是true),然后我再次点击输入框,因为开关为true,所以我需要点击输入框两次,弹层才会出现,这很明显和我想要的效果不一样
2、如果我给document添加点击事件的时候,设置了开关为false,会产生的问题是,因为事件流的原因,我们单击输入框的时候,必然会触发document的点击事件,所以就是,不论我们点击多少次输入框,弹出层都是显示状态,只有我们点击输入框以外的地方时,弹出层才会隐藏,显然,这也不是我们想要的效果
解决思路:我们可以另外再定义一个变量off=false,来检测触发document的点击事件的时候,是否触发了输入框的点击事件(因为我给document添加事件的时候阻止了事件捕获),当document的点击事件触发时,如果是因为点击输入框触发的document点击事件,就不让onOff为false,否则就让其为false
具体实现看代码:(有注释哦)
var areaSelect = M('#area')//输入框
var areas = M('.selectorDialog')//弹出层
var area = document.querySelectorAll('.selectorDialog li a')//弹出层中的内容
var len = area.length
var onOff = false;
var off = false;
areaSelect.addEventListener('click',function(){//输入框点击事件处理
off = true
onOff = !onOff;
if(onOff){
areas.style.display = "block"
}else{
areas.style.display = "none"
}
},false)
for(let i=0; i<len; i++){//弹出层内的点击事件处理
area[i].onclick = function(ev){
onOff = false;
ev.preventDefault();
areaSelect.value = this.innerHTML;
}
}
document.addEventListener('click',function(){//document的点击事件处理
if(!off){//判断是否是因为点击输入框而触发的点击事件,如果为off为true时就是,否则不是,
//可以让开关为true
onOff = false;
}
off = false
areas.style.display = "none"
},true)
总结:看似不难,实际上考察的是对js基础的掌握程度,主要的知识点就是事件流的相关知识点喽!
标签:总结,弹层,false,项目,遇到,输入框,点击,document,onOff From: https://blog.51cto.com/u_15983333/6091807