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

 

posted on 2018-09-04 15:02  KyleLjc  阅读(145)  评论(0编辑  收藏  举报

导航