• BaseClass


     
    const events = Symbol.for('events');
        const check = Symbol.for('check');
    /**
     * 事件存储的位置 
     * @example
     * this[delegate] = {
     *      [事件类型]: {
     *          [选择器类型]: Function
     *      }
     * }
     * 事件类型 代表 [click | mouseover | mousemove | touch ...]
     * 选择器类型暂时只有 label和class两个值
     */
    const delegate = Symbol.for('delegate');
    const props = Symbol.for('props');
    //获取selector类型,是class选择器还是标签选择器
    const getSelectorType = Symbol.for('getSelectorType');
    const noDelegation = Symbol.for('noDelegation')
    const truelyHandler = Symbol.for('truelyHandler');
    const checkStrategies = {
        class: function(selector, childNode, parentNode) {
            const classname = childNode.className;
            if(classname && classname.split){
                const ary = classname.split(' ');
                if(~ ary.indexOf(selector) ){
                    return true;
                } else if( childNode == parentNode || childNode == document.querySelector('html') ) {
                    return false;
                } else if( !childNode.parentNode ){    
                    return false;
                } else {
                    return checkStrategies.class(selector, childNode.parentNode, parentNode)
                }
    
            } else {
                if( childNode == parentNode || childNode == document.querySelector('html') ) {
                    return false;
                }
                return checkStrategies.class(selector, childNode.parentNode, parentNode)
            }
        },
        id: function(selector, childNode, parentNode) {
            const id = childNode.getAttribute('id');
            if(id && id == selector){
                return true;
            } 
            if( childNode == parentNode || childNode == document.querySelector('html') ){
                return false;
            }
            
            return checkStrategies.id(selector, childNode.parentNode, parentNode);
            
        },
        label: function(selector, childNode, parentNode) {
            const label = childNode.tagName.toLowerCase();
            if(label == selector){
                return true;
            }
            if( childNode == parentNode || childNode == document.querySelector('html') ){
                return false;
            }
            return checkStrategies.label(selector, childNode.parentNode, parentNode);
        }
    }
    class Base {
        constructor(props) {
            /**
             * @member {Map} Symbol.for('events') - 用来保存事件的
             */
            this[events] = {};
            this[delegate] = {};
            this[truelyHandler] = {};
            this[props] = ['after', 'before', 'listen', 'trigger', 'remove', '$', 'on', 'off', 'destroy'];
            if(props && props.$el){
                this.$el = props.$el;
            }
        }
        
        /**
         * aop after
         * @param {String} fn - 方法名字
         * @param {Function} callback - 回调方法
         */
        after(fn, callback) {
            const f = this[fn];
            const me = this;
            if(~this[props].indexOf(fn)){
                return ;
            }
            me[fn] = function() {
                const ret = f.apply(me, arguments);
                callback.apply(me, arguments);
                return ret;
            }
        }
        /**
         * aop before
         * @param {String} fn - 方法名字 
         * @param {Function} callback - 回调方法 
         */
        before(fn, callback) {
            const f = this[fn];
            const me = this;
            if(~this[props].indexOf(fn)){
                return ;
            }
            me[fn] = function() {
                callback.apply(me, arguments);
                const ret = f.apply(me, arguments);
                return ret;
            }
        }
        /**
         * 监听事件
         * @param {String} name - 事件名称 
         * @param {Funciton} handler - 处理器
         * @example
         * this.listen('event-click', clickMe);
         * var clickMe = function(){ console.log('I was clicked') }
         */
        listen(name, handler) {
            const me = this;
            const ary = this[events];
            if( !ary[name] ){
                ary[name] = []
            }
            ary[name].push(handler);
            return me;
        }
        /**
         * 触发器
         * @param {String} name - 事件名称
         * @example
         * this.trigger('event-click');
         */
        trigger(name, ...arg) {
            const me = this;
            const ary = me[events];
            if(!ary[name]){
                return me;
            }
            const handlers = ary[name].slice(0);
            let fn = null;
            while(fn = handlers.shift()) {
                fn.apply(me, arg);
            }
            return me;
        }
        /**
         * 移除事件
         * @param {String} name - event name
         */
        remove(name) {
            const me = this;
            me[events][name] = []
            return me;
        }
        /**
         * 选择$el内部dom
         * @param {String} selector - 选择器,只能是classname
         * @return {DOM}
         */
        $(selector) {
            const me = this;
            return me.$el && me.$el.querySelectorAll(selector);
        }
        /**
         * 获取子选择器类型
         * @return {Map} - {type: 'class', selector: 'js-selector'}
         */
        [getSelectorType] (selector) {
            if(/^./.test(selector)){
                return {
                    type: 'class',
                    selector: selector.slice(1)
                }
    
            } else if(/^#/.test(selector)) {
                return {
                    type: 'id',
                    selector: selector.slice(1)
                }
    
            } else {
                return {
                    type: 'label',
                    selector: selector
                }
            }
        }
        /**
         * 事件绑定
         * @param {String} name - event name
         * @param {Function} handler - function
         * @param {String} targetSelector - 子选择器
         * @return {this}
         * @example
         * this.on('click', handler, '.js-target');
         */
        on(name, handler, targetSelector) {
            const me = this;
            const _handler = handler;
            let ret = null;
            const fn = (e, ...arg) => { 
                const target = e.target;
                const eventName = e.type.toLowerCase();
                //如果未缓存事件,退出
                if(!me[delegate][eventName]){
                    return ;
                }
                const handlers = me[delegate][eventName];
                for(let key in handlers){
                    if(key === me[delegate][name][noDelegation]){
                        handlers[key].forEach((fn) => {
                            fn(e, ...arg);
                        })
                    } else {
                        handlers[key].forEach((fn) => {
                            ret = me[getSelectorType](key)
                            const recursion = checkStrategies[ret.type]
                            if(recursion && recursion( ret.selector, target, me.$el )){
                                fn(e, ...arg);
                            }
                        })
                    }
                }
                
            };
            if( !me[truelyHandler][name] ){
                me[truelyHandler][name] = fn; 
                me.$el.addEventListener(name, fn, false);
            }
            if(!me[delegate][name]){
                me[delegate][name] = {};
            }
            if(targetSelector){
                if(!me[delegate][name][targetSelector]){
                    me[delegate][name][targetSelector] = [];
                }
                me[delegate][name][targetSelector].push(_handler.bind(me));
            } else {
                if(!me[delegate][name][noDelegation]){
                    me[delegate][name][noDelegation] = [];
                }
                me[delegate][name][noDelegation].push(_handler.bind(me));
            }
            
            return me;
        }
        /**
         * 解绑
         * @param {String} name - event name
         * @param {[String]} selector - 操作
         */
        off(name, selector) {
            const me = this;
            if( !(me[delegate][name]) ) {
                return me;
            }
            if(!selector) {
                if(me[truelyHandler][name]){
                    me.$el.removeEventListener(name, me[truelyHandler][name], false);
                    me[truelyHandler][name] = null;
                }
                me[delegate][name] = null;
                return me;
            } else {
                if(me[delegate][name] && me[delegate][name][selector]){
                    delete me[delegate][name][selector]
                }
            }
            
            return me;
        }

    export default Base

    功能:

    1、aop

    2、自定义事件

    3、dom event

  • 相关阅读:
    信息和熵
    【算法】欧几里得算法与青蛙约会oj
    【算法】并查集模板与练习
    Kaggle-房价预测
    【pytorch】pytorch-backward()的理解
    【pytorch】pytorch-LSTM
    【计算机网络】数据链路层总结
    【Code】numpy、pytorch实现全连接神经网络
    【MT】牛津的MT教程
    【计算机网络】物理层基础知识
  • 原文地址:https://www.cnblogs.com/hellolol/p/9584480.html
Copyright © 2020-2023  润新知