优秀的编程知识分享平台

网站首页 > 技术文章 正文

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

nanyue 2024-08-10 18:38:50 技术文章 5 ℃

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

使用场景

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

技术原理

  1. 跨页面通信:

基于事件监听,通过监听 storage事件监听回调机制,实现跨页面通信,让每个只操作自身页面的操作

  1. 同页面事件监听:

发送事件时,查找回调函数,触发回调

使用效果

使用示例

// 注册事件

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);

})

仓库地址: [链接](https://github.com/dushitaoyuan/dev_js_docs/tree/main/event-listener)

最近发表
标签列表