默認只有window支持resize事件,但有時我們需要為div等元素添加resize事件
代碼見下面,原理是在元素內添加一個內嵌html,然后監聽這個內嵌html的resize事件
import { Injectable } from '@angular/core'; @Injectable() export class ResizeEventService { isIE: boolean; constructor() { this.isIE = /Trident/.test(navigator.userAgent); } addResizeListener(element: any, fn: any) { const self = this; if (!element.__resizeListeners__ || element.__resizeListeners__.length === 0) {
element.__resizeListeners__ = []; if (getComputedStyle(element).position === 'static') { element.style.position = 'relative'; } const obj = element.__resizeTrigger__ = document.createElement('object') as any; obj.setAttribute('style', 'display: block; position: absolute; top: 0; left: 0; height: 100%;' + 'width: 100%; overflow: hidden; pointer-events: none; z-index: -1;'); obj.__resizeElement__ = element; obj.onload = function() { this.contentDocument.defaultView.__resizeTrigger__ = this.__resizeElement__; this.contentDocument.defaultView.addEventListener('resize', self.resizeListener); }; obj.type = 'text/html'; if (this.isIE) { element.appendChild(obj); } obj.data = 'about:blank'; if (!this.isIE) { element.appendChild(obj); } } element.__resizeListeners__.push(fn); } removeResizeListener(element: any, fn: any) { if (!element.__resizeListeners__) { return; } element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1); if (!element.__resizeListeners__.length) { element.__resizeTrigger__.contentDocument.defaultView.removeEventListener('resize', this.resizeListener); element.__resizeTrigger__ = !element.removeChild(element.__resizeTrigger__); } } private resizeListener(e: Event) { const win = e.target || e.srcElement as any; if (win.__resizeRAF__) { window.cancelAnimationFrame(win.__resizeRAF__); } win.__resizeRAF__ = window.requestAnimationFrame(function() { const trigger = win.__resizeTrigger__; trigger.__resizeListeners__.forEach(function(fn: any) { fn.call(trigger, e); }); }); } }