百行代码实现js事件监听实现跨页面数据传输

百行代码实现js事件监听实现跨页面数据传输

使用场景

类似消息队列的使用场景,支持同页面和跨页面通信,发送消息和接收消息

技术原理

  • 跨页面通信:
    基于事件监听,通过监听 storage事件监听回调机制,实现跨页面通信,让每个只操作自身页面的操作
  • 同页面事件监听:
    发送事件时,查找回调函数,触发回调

使用效果

在这里插入图片描述

使用示例

// 注册事件
eventListener.addEventListener('showMessage', function (message) {
    console.debug("接收到的消息")
})
// 发送事件
eventListener.sendEvent('showMessage', 111)

源码

/**
 * js 事件监听
 *
 *
 * useage:
 * 1. 注册事件监听
 * EventListener.addEventListener('xxx-success',function(xxvalue){
 *    refreshList();
 * });
 * 发送事件
 * 2.EventListener.sendEvent('xxx-success','xxvalue')
 */
/**
 * 回调队列
 * 结构:{
 *     eventKey:'xxx',
 *     callback:[]
 * }
 */
let EventListener = function () {
    this.callback = [];
    this.sendEvent = function (eventKey, eventValue) {
        /**
         * 同一页面,localStorage.setItem 不触发 storage ,发送时 自动触发
         * uuid 保证变更,都能触发 storage事件
         */
        let newEventKey = 'evt_' + eventKey;
        let uuid = _uuid(8, 16);
        let newEventValue = uuid + '_' + (eventValue == undefined ? '' : eventValue);
        //手动触发本页面事件
        this.triggerCallback(newEventKey, newEventValue);
        localStorage.setItem(newEventKey, newEventValue);

    }
    this.addEventListener = function (eventKey, callback) {
        let callbackObject = _findCallbackObject(this, eventKey);
        if (callbackObject == undefined) {
            callbackObject = {eventKey: eventKey, callback: [callback]};
            this.callback.push(callbackObject);
        } else {
            callbackObject.callback.push(callback);
        }
    }
    /**
     * 触发事件对应的回调
     * removeItem setItem 都会触发
     * removeItem eventValue==null 不触发
     */
    this.triggerCallback = function (eventKey, eventValue) {
        if (_isEventKey(eventKey) && _isNotNull(eventValue)) {
            let originalEventKey = _resolveEventKey(eventKey);
            let callbackObject = _findCallbackObject(this, originalEventKey);
            if (callbackObject != undefined) {
                let callbackQueue = callbackObject.callback;
                if (callbackQueue.length > 0) {
                    eventValue = _resolveEventValue(eventValue);
                    for (let index in callbackQueue) {
                        let callback = callbackQueue[index];
                        try {
                            callback(eventValue);
                        } catch (e) {
                            console.error("执行事件" + callbackObject.eventKey + "的函数失败", e)
                        }
                    }
                }
                //触发后删除
                localStorage.removeItem(eventKey);
            }
        }
    }

    /**
     * 查找到事件key对应的监听对象
     */
    function _findCallbackObject(_this, eventKey) {
        if (_this.callback.length > 0) {
            for (let index in _this.callback) {
                let callbackObject = _this.callback[index];
                if (callbackObject.eventKey == eventKey) {
                    return callbackObject;
                }
            }
        }
    }

    function _resolveEventKey(eventKey) {
        return eventKey.split('_')[1];

    }

    function _isEventKey(eventKey) {
        if (eventKey.indexOf('evt_') < 0) {
            return false;
        }
        return true;
    }


    function _resolveEventValue(eventValue) {
        let start = eventValue.indexOf('_') + 1;
        let end = eventValue.length;
        return eventValue.substring(start, end);
    }

    function _isNotNull(value) {
        if (value == undefined || value == null) {
            return false;
        }
        return true;
    }


    function _uuid(len, radix) {
        let chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
        let uuid = [], i;
        radix = radix || chars.length;
        if (len) {
            for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
        } else {
            let r;
            uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
            uuid[14] = '4';
            for (i = 0; i < 36; i++) {
                if (!uuid[i]) {
                    r = 0 | Math.random() * 16;
                    uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
                }
            }
        }
        return uuid.join('');
    };
}
let eventListener = new EventListener();
//注册监听,不同页面也可触发监听事件
window.addEventListener('storage', function (event) {
    eventListener.triggerCallback(event.key, event.newValue);
})

仓库地址: 链接

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值