Vue 注冊(cè) clickOutside事件

clickoutside.js 文件

const CLICK = 'click';
const captureInstances = Object.create(null);
const nonCaptureInstances = Object.create(null);
const instancesList = [captureInstances, nonCaptureInstances];

/**
 * The common event handler for bot capture and non-capture events.
 *
 * @param {!Object} context - The event context.
 * @param {!Object} instances - The capture or non-capture registered instances.
 * @param {Event} event - The event object.
 */
const commonHandler = function _onCommonEvent(context, instances, event) {
    const {target} = event;

    const itemIteratee = function _itemIteratee(item) {
        const {el} = item;

        if (el !== target && !el.contains(target)) {
            const {binding} = item;

            if (binding.modifiers.stop) {
                event.stopPropagation();
            }

            if (binding.modifiers.prevent) {
                event.preventDefault();
            }

            binding.value.call(context, event);
        }
    };

    const keysIteratee = function _keysIteratee(eventName) {
        return instances[eventName].forEach(itemIteratee);
    };

    Object.keys(instances).forEach(keysIteratee);
};

/**
 * Event handler for capture events.
 *
 * @param {Event} event - The event object.
 */
const captureEventHandler = function onCaptureEvent(event) {
    /* eslint-disable-next-line babel/no-invalid-this */
    commonHandler(this, captureInstances, event);
};

/**
 * Event handler for non-capture events.
 *
 * @param {Event} event - The event object.
 */
const nonCaptureEventHandler = function onNonCaptureEvent(event) {
    /* eslint-disable-next-line babel/no-invalid-this */
    commonHandler(this, nonCaptureInstances, event);
};

/**
 * Get the correct event handler: Capture or non-capture.
 *
 * @param {boolean} useCapture - Indicate which handler to use; 'true' to use
 *  capture handler or 'false' for non-capture.
 * @returns {Function} - The event handler.
 */
const getEventHandler = function _getEventHandler(useCapture) {
    return useCapture ? captureEventHandler : nonCaptureEventHandler;
};

/**
 * The directive definition.
 * {@link https://vuejs.org/v2/guide/custom-directive.html|Custom directive}
 *
 * @namespace
 * @property {!Object} $_captureInstances - Registered capture instances.
 * @property {!Object} $_nonCaptureInstances - Registered non-capture instances.
 * @property {Function} $_onCaptureEvent - Event handler for capture events.
 * @property {Function} $_onNonCaptureEvent - Event handler for non-capture events.
 * @property {Function} bind - Called only once, when the directive is first
 *  bound to the element.
 * @property {Function} unbind - Called only once, when the directive is unbound
 *  from the element.
 * @property {string} version - The version number of this release.
 */
export const directive = Object.defineProperties(
    {},
    {
        $_captureInstances: {
            value: captureInstances,
        },

        $_nonCaptureInstances: {
            value: nonCaptureInstances,
        },

        $_onCaptureEvent: {
            value: captureEventHandler,
        },

        $_onNonCaptureEvent: {
            value: nonCaptureEventHandler,
        },

        bind: {
            value: function bind(el, binding) {
                if (typeof binding.value !== 'function') {
                    throw new TypeError('Binding value must be a function.');
                }

                const arg = binding.arg || CLICK;
                const normalisedBinding = {
                    ...binding,
                    ...{
                        arg,
                        modifiers: {
                            ...{
                                capture: false,
                                prevent: false,
                                stop: false,
                            },
                            ...binding.modifiers,
                        },
                    },
                };

                const useCapture = normalisedBinding.modifiers.capture;
                const instances = useCapture ? captureInstances : nonCaptureInstances;

                if (!Array.isArray(instances[arg])) {
                    instances[arg] = [];
                }

                if (instances[arg].push({el, binding: normalisedBinding}) === 1) {
                    if (typeof document === 'object' && document) {
                        document.addEventListener(
                            arg,
                            getEventHandler(useCapture),
                            useCapture,
                        );
                    }
                }
            },
        },

        unbind: {
            value: function unbind(el) {
                const compareElements = function _compareElements(item) {
                    return item.el !== el;
                };

                const instancesIteratee = function _instancesIteratee(instances) {
                    const instanceKeys = Object.keys(instances);

                    if (instanceKeys.length) {
                        const useCapture = instances === captureInstances;

                        const keysIteratee = function _keysIteratee(eventName) {
                            const newInstance = instances[eventName].filter(compareElements);

                            if (newInstance.length) {
                                instances[eventName] = newInstance;
                            } else {
                                if (typeof document === 'object' && document) {
                                    document.removeEventListener(
                                        eventName,
                                        getEventHandler(useCapture),
                                        useCapture,
                                    );
                                }

                                delete instances[eventName];
                            }
                        };

                        instanceKeys.forEach(keysIteratee);
                    }
                };

                instancesList.forEach(instancesIteratee);
            },
        },

        /* Note: This needs to be manually updated to match package.json. */
        version: {
            enumerable: true,
            value: '3.5.6',
        },
    },
);

/**
 * @typedef {Function} Vue - The constructor.
 * @property {Function} directive - You can register a global custom directive
 *  with the Vue.directive() method, passing in a directiveID followed by a
 *  definition object.
 */

/**
 * A Vue.js plugin should expose an install method. The method will be called
 * with the Vue constructor as the first argument, along with possible options.
 * {@link https://vuejs.org/v2/guide/plugins.html#Writing-a-Plugin|Writing a plugin}.
 *
 * @param {Vue} Vue - The Vue function.
 */
export default directive;

使用

    import clickOutside from './directives/clickoutside'
<div class="theme-wrap" ref="theme-warp" @mouseover="hoverTheme" @mouseout="outTheme" v-click-outside="test" >
   directives: {
            clickOutside:clickOutside
        },
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末三妈,一起剝皮案震驚了整個(gè)濱河市指郁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖蝌箍,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異暂吉,居然都是意外死亡陆蟆,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)凤藏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)奸忽,“玉大人,你說(shuō)我怎么就攤上這事揖庄±醪耍” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵蹄梢,是天一觀的道長(zhǎng)疙筹。 經(jīng)常有香客問(wèn)我,道長(zhǎng)禁炒,這世上最難降的妖魔是什么腌歉? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮齐苛,結(jié)果婚禮上翘盖,老公的妹妹穿的比我還像新娘。我一直安慰自己凹蜂,他們只是感情好馍驯,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著玛痊,像睡著了一般汰瘫。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上擂煞,一...
    開(kāi)封第一講書(shū)人閱讀 51,578評(píng)論 1 305
  • 那天混弥,我揣著相機(jī)與錄音,去河邊找鬼对省。 笑死蝗拿,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蒿涎。 我是一名探鬼主播哀托,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼劳秋!你這毒婦竟也來(lái)了仓手?” 一聲冷哼從身側(cè)響起胖齐,我...
    開(kāi)封第一講書(shū)人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎嗽冒,沒(méi)想到半個(gè)月后呀伙,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡添坊,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年区匠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片帅腌。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡驰弄,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出速客,到底是詐尸還是另有隱情戚篙,我是刑警寧澤,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布溺职,位于F島的核電站岔擂,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏浪耘。R本人自食惡果不足惜乱灵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望七冲。 院中可真熱鬧痛倚,春花似錦、人聲如沸澜躺。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)掘鄙。三九已至耘戚,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間操漠,已是汗流浹背收津。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留浊伙,地道東北人撞秋。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像吧黄,于是被迫代替她去往敵國(guó)和親部服。 傳聞我的和親對(duì)象是個(gè)殘疾皇子唆姐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355