背景
在開(kāi)發(fā)下拉選擇(picker)組件中遇到疲眷,點(diǎn)擊輸入框出現(xiàn)下拉列表禾蚕,再點(diǎn)擊下拉列表選項(xiàng)后下拉列表自動(dòng)收縮,然而選項(xiàng)值并沒(méi)有選到
一狂丝、blur和click事件簡(jiǎn)述
- blur事件:當(dāng)元素失去焦點(diǎn)時(shí)觸發(fā)blur事件换淆;其為表單事件,blur和focus事件不會(huì)冒泡几颜,其他表單事件都可以倍试。
- click事件:當(dāng)點(diǎn)擊元素時(shí)觸發(fā)click事件;所有元素都有此事件蛋哭,會(huì)產(chǎn)生冒泡县习。
注(往往也是出現(xiàn)問(wèn)題的原因): 點(diǎn)擊某元素導(dǎo)致前一個(gè)元素失去焦點(diǎn),blur事件優(yōu)先于click事件
demo演示:
<input type="text" id="ipt">
<input type="button" id="btn" value="點(diǎn)我">
<script>
var ipt = document.getElementById("ipt");
ipt.addEventListener("blur", function(){
console.log("my input blur");
});
var btn = document.getElementById("btn");
btn.addEventListener("click", function(){
console.log("my button click");
});
</script>
// 輸出結(jié)果:
my input blur
my button click
二谆趾、產(chǎn)生問(wèn)題躁愿,blur與click沖突導(dǎo)致下拉值不能正常選值
實(shí)際開(kāi)發(fā)中,我們會(huì)經(jīng)常遇到某一下拉列表框沪蓬,點(diǎn)擊其他元素消失列表框彤钟;點(diǎn)擊下拉框子元素使其生效的需求。這就會(huì)面臨沖突問(wèn)題跷叉。
demo演示:
<!-- DOM結(jié)構(gòu)示意 -->
<input type="text" placeholder="請(qǐng)選擇" readonly>
<div data-status="hide">
<ul>
<li><a href="javascript:">A</a></li>
<li><a href="javascript:">B</a></li>
<li><a href="javascript:">C</a></li>
<li><a href="javascript:">D</a></li>
</ul>
</div>
/** 說(shuō)明:
* 目前通過(guò)ul外層div自定義屬性“data-status”控制其是否顯示
*/
(function($){
$("input").focus(function(){
// input框獲取焦點(diǎn)逸雹,展示下拉框
$(".search-list").attr("data-status", "show");
}).blur(function(){
// input框失去焦點(diǎn),隱藏下拉框
$(".search-list").attr("data-status", "hide");
});
// 選擇對(duì)應(yīng)選項(xiàng)性芬,并賦值給input框
$(".search-list li a").click(function(){
console.log("執(zhí)行");
$("input").val($(this).text());
});
})(jQuery);
執(zhí)行demo,你會(huì)發(fā)現(xiàn)峡眶,并不能正確獲取下拉框中某值。
這是為什么呢植锉?:前文已知辫樱,blur優(yōu)先于click執(zhí)行,而JavaScript為單線程俊庇,同一時(shí)間只能執(zhí)行處理一個(gè)事件狮暑,這就導(dǎo)致blur事件優(yōu)先觸發(fā)鸡挠,隱藏了下拉框展示區(qū),所以導(dǎo)致其后續(xù)click事件并不會(huì)執(zhí)行搬男。
三拣展、解決方法
方法1:
用setTimeout對(duì)blur事件進(jìn)行延遲,讓click先執(zhí)行
//只提供關(guān)鍵代碼演示
$("input").focus(function(){
// input框獲取焦點(diǎn)缔逛,展示下拉框
$(".search-list").attr("data-status", "show");
}).blur(function(){
// input框失去焦點(diǎn)备埃,隱藏下拉框
setTimeout(()=> { $(".search-list").attr("data-status", "hide");},500)
});
方法2:
使用mousedown代替click讓其優(yōu)先執(zhí)行
mousedown事件:當(dāng)鼠標(biāo)指針移動(dòng)到元素上方,并按下鼠標(biāo)按鍵時(shí)褐奴,會(huì)發(fā)生mousedown事件按脚。
mousedown事件優(yōu)先于click事件