公司項目有像上圖中效果的功能需求這也是很常見功能很簡單功能,經過一個小例子和你們聊聊js的事件冒泡和默認事件。ide
先說說通常的實現方式即便用阻止事件冒泡的方式去作,給input綁定一個click事件(並阻止事件冒泡到window)當點擊上input的時候就顯示ul再給window或者document 綁定一個click事件當點擊頁面其餘地方的時候隱藏ul。
這裏還要給ul 添加一個代理點擊事件(事件代理比遍歷li綁定點擊事件性能要高)當點擊到下面的li的時候把li裏面的內容添加到input裏面 而且此時ul 是不能隱藏的 要想ul不隱藏就得阻止事件冒泡防止事件傳播到 window或者document上從而隱藏了ul原理跟給input阻止事件冒泡是同樣的。函數
說說上面實現方式的不足就是給window或document添加點擊事件當用戶每點擊一次頁面的時候都會去執行一下給window綁定是函數(除了點擊到input和ul 阻止了事件冒泡)具體實現代碼以下。性能
<meta charset="UTF-8"> <title>test</title> <style> *{padding:0;margin:0; } ul{ list-style: none; } #test2{ width:170px; } #box{ padding:30px; } #list{ width:170px; border:1px solid #ccc; display:none; } #list li{ padding:5px;cursor:pointer; } </style>
<div id="box" > <input type="text" id="test2" > <ul id="list" > <li>111</li> <li>222</li> <li>333</li> <li>44</li> </ul> </div> <script> var $inp = $('#test2'), $ul = $('#list'),doc = $(document); $inp.on('click',show); doc.on('click',hide); $ul.on('click','li',changeText);//事件代理性能更好 function changeText(e){ e.stopPropagation(); $inp.val($(this).text()); } function show(e){ e.stopPropagation(); //阻止事件冒泡 $ul.show(); } function hide(){ $ul.hide(); } </script>
總結:
優勢兼容性好ie6-ie8都ok。
缺點在window上綁定事件用戶每次點擊頁面都會被觸發綁定事件。this
但我我的認爲最優的實現方案不須要給window綁定click事件(用阻止默認事件的方式去實現), 咱們只需給input綁定一個focus事件一個blur事件當input focus 的時候就顯示ul,當input blur 的時候 就隱藏 ul 在給ul 綁定一個mousedown事件(阻止遊覽器默認事件)。注意:這裏有必要說明一下事件的執行順序和爲何不能給ul添加點擊事件。當點擊ul的時候鼠標鍵上升的時候 mousedown 執行完了input纔會失去焦點blur。 mousedown --> blur 若是直接給ul 添加click事件input 會在失去焦點了blur 纔會觸發ul的click事件 事件執行順序 blur --> click 當input blur了ul就隱藏了故得不到本身想要的效果。代理
按照個人方案基於第一種方案的代碼稍加改動就能夠具體實現的代碼以下:code
<div id="box" > <input type="text" id="test2" > <ul id="list" > <li>111</li> <li>222</li> <li>333</li> <li>44</li> </ul> </div> <script> var $inp = $('#test2'), $ul = $('#list'); $inp.on('focus',show); $inp.on('blur',hide); $ul.on('mousedown','li',changeText);//事件代理性能更好 把mousedown改爲click 能夠驗證我上面說的事件執行順序感興趣的本身動手試下。 function changeText(e){ e.preventDefault(); //把阻止事件冒泡改爲阻止默認事件 $inp.val($(this).text()); } function show(e){ $ul.show(); } function hide(){ $ul.hide(); } </script>
ie8下的效果圖
blog
ie9下的效果
事件
在ie9及以上都ok沒什麼問題 可是ie8下跟咱們想要的效果就不同了每次點擊ul會自動去隱藏了也就是說在ie8下 ul的mousedown是被執行了可是他沒有去阻止掉input blur事件讓input失去了焦點觸發了綁定在blur事件的函數從而隱藏了ul。
總結:
優勢不須要在window上綁定事件少一次事件綁定。
缺點兼容性ie9及以上不兼容ie8(有小問題)。ip