[inula-dev-tools]<feat> 兼容低版本浏览器的窗口监听器

This commit is contained in:
13659257719 2023-11-01 09:08:53 +08:00
parent bf813cecff
commit 8a562c44a2
1 changed files with 95 additions and 0 deletions

View File

@ -0,0 +1,95 @@
/*
* Copyright (c) 2023 Huawei Technologies Co.,Ltd.
*
* openInula is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
*
* ResizeObserver IE
* dom
* window resize object
* window object dom dom dom
* dom window window
* dom
*
* <div id='test>
* <object> --> div
* <html></html> --> resize
* </object>
* </div>
*
*/
function timeout(func) {
return setTimeout(func, 20);
}
function requestFrame(func) {
const raf = requestAnimationFrame || timeout;
return raf(func);
}
function cancelFrame(id) {
const cancel = cancelAnimationFrame || clearTimeout;
cancel(id);
}
// 在闲置帧触发回调事件,如果在本次触发前存在未处理回调事件,需要取消未处理回调事件
function resizeListener(event) {
const win = event.target;
if (win.__resizeRAF__) {
cancelFrame(win.__resizeRAF__);
}
win.__resizeRAF__ = requestFrame(function () {
const observeElement = win.__observeElement__;
observeElement.__resizeCallbacks__.forEach(function (func) {
func.call(observeElement, observeElement, event);
});
});
}
function loadObserver(this: any) {
// 将待观测元素传递给 object 标签的 window 对象,这样在触发 resize 事件时可以拿到待观测元素
this.contentDocument.defaultView.__observeElement__ = this.__observeElement__;
// 给 html 的 window 对象添加 resize 事件
this.contentDocument.defaultView.addEventListener('resize', resizeListener);
}
export function addResizeListener(element: any, func: any) {
if (!element.__resizeCallbacks__) {
element.__resizeCallbacks__ = [func];
element.style.position = 'relative';
const observer = document.createElement('object');
observer.setAttribute(
'style',
'display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden; pointer-events: none; z-index: -1;'
);
observer.data = 'about:blank';
observer.onload = loadObserver;
observer.type = 'text/html';
observer['__observeElement__'] = element;
element.__observer__ = observer;
element.appendChild(observer);
} else {
element.__resizeCallbacks__.push(func);
}
}
export function removeResizeListener(element, func) {
element.__resizeCallbacks__.splice(element.__resizeCallbacks__.indexOf(func), 1);
if (!element.__resizeCallbacks__.length) {
element.__observer__.contentDocument.defaultView.removeEventListener('resize', resizeListener);
element.removeChild(element.__observer__);
element.__observer__ = null;
}
}