網頁中有很多常見的下拉彈窗,比如下圖所示的使用者資訊彈窗:
點選使用者頭像和名稱,會彈出一個下拉選單,然後點選頁面中其它空白區域(除了彈窗本身外),彈窗就關閉了。本示例就用自定義指令來實現這樣的需求。
先來分析一下如何實現。
該示例有兩個特點,一是點選下拉選單本身是不會關閉的,二是點選下拉選單以外的所有區域都要關閉。點選所有區域,可以在 document 上繫結 click 事件來實現,同時只要過濾出是否點選的是目標元素內部的元素即可。
程式碼如下,只適用於 Vue.js 2.x:
- index.html:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>可從外部關閉的下拉選單</title> <link rel="stylesheet" type="text/css" href="style.css"> </head> <body> <div id="app" v-cloak> <div class="main" v-clickoutside="handleClose"> <button @click="show = !show">點選顯示下拉選單</button> <div class="dropdown" v-show="show"> <p>下拉框的內容,點選外面區域可以關閉</p> </div> </div> </div> <script src="https://unpkg.com/vue/dist/vue.min.js"></script> <script src="clickoutside.js"></script> <script src="index.js"></script> </body> </html>複製程式碼
index.js:
var app = new Vue({ el: '#app', data: { show: false }, methods: { handleClose: function () { this.show = false; } } });複製程式碼
clickoutside.js:
Vue.directive('clickoutside', { bind (el, binding, vnode) { function documentHandler (e) { if (el.contains(e.target)) { return false; } if (binding.expression) { binding.value(e); } } el.__vueClickOutside__ = documentHandler; document.addEventListener('click', documentHandler); }, unbind (el, binding) { document.removeEventListener('click', el.__vueClickOutside__); delete el.__vueClickOutside__; } });複製程式碼
- style.css:
[v-cloak] { display: none; } .main{ width: 125px; } button{ display: block; width: 100%; color: #fff; background-color: #39f; border: 0; padding: 6px; text-align: center; font-size: 12px; border-radius: 4px; cursor: pointer; outline: none; position: relative; } button:active{ top: 1px; left: 1px; } .dropdown{ width: 100%; height: 150px; margin: 5px 0; font-size: 12px; background-color: #fff; border-radius: 4px; box-shadow: 0 1px 6px rgba(0,0,0,.2); } .dropdown p{ display: inline-block; padding: 6px; }複製程式碼