需求
開發(fā)過程中經(jīng)常遇到的一個問題就是如何監(jiān)聽一個div的size變化。
比如我用canvas繪制了一個chart,當canvas的size發(fā)生變化的時候,需要重新繪制里面的內(nèi)容,這個時候就需要監(jiān)聽resize事件做處理。
window上雖然可以添加resize事件監(jiān)聽,但這并不能滿足我們的需求,因為很多時候,div的size發(fā)生了變化,但是window的size并沒有改變。
不過我們可以間接利用window的resize事件監(jiān)聽來實現(xiàn)對于某個div的resize事件監(jiān)聽,請看下面具體實現(xiàn)。
對于div的resize事件的監(jiān)聽,實現(xiàn)方式有很多,比如周期性檢查,通過scroll事件等等,本文主要介紹通過object元素來實現(xiàn)監(jiān)聽。
具體實現(xiàn)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
/** * Created by taozh on 2017/5/6. */ var EleResize = { _handleResize: function (e) { var ele = e.target || e.srcElement; var trigger = ele.__resizeTrigger__; if (trigger) { var handlers = trigger.__z_resizeListeners; if (handlers) { var size = handlers.length; for ( var i = 0; i < size; i++) { var h = handlers[i]; var handler = h.handler; var context = h.context; handler.apply(context, [e]); } } } }, _removeHandler: function (ele, handler, context) { var handlers = ele.__z_resizeListeners; if (handlers) { var size = handlers.length; for ( var i = 0; i < size; i++) { var h = handlers[i]; if (h.handler === handler && h.context === context) { handlers.splice(i, 1); return ; } } } }, _createResizeTrigger: function (ele) { var obj = document.createElement( 'object' ); obj.setAttribute( 'style' , 'display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden;opacity: 0; pointer-events: none; z-index: -1;' ); obj.onload = EleResize._handleObjectLoad; obj.type = 'text/html' ; ele.appendChild(obj); obj.data = 'about:blank' ; return obj; }, _handleObjectLoad: function (evt) { this .contentDocument.defaultView.__resizeTrigger__ = this .__resizeElement__; this .contentDocument.defaultView.addEventListener( 'resize' , EleResize._handleResize); } }; if (document.attachEvent) { //ie9-10 EleResize.on = function (ele, handler, context) { var handlers = ele.__z_resizeListeners; if (!handlers) { handlers = []; ele.__z_resizeListeners = handlers; ele.__resizeTrigger__ = ele; ele.attachEvent( 'onresize' , EleResize._handleResize); } handlers.push({ handler: handler, context: context }); }; EleResize.off = function (ele, handler, context) { var handlers = ele.__z_resizeListeners; if (handlers) { EleResize._removeHandler(ele, handler, context); if (handlers.length === 0) { ele.detachEvent( 'onresize' , EleResize._handleResize); delete ele.__z_resizeListeners; } } } } else { EleResize.on = function (ele, handler, context) { var handlers = ele.__z_resizeListeners; if (!handlers) { handlers = []; ele.__z_resizeListeners = handlers; if (getComputedStyle(ele, null ).position === 'static' ) { ele.style.position = 'relative' ; } var obj = EleResize._createResizeTrigger(ele); ele.__resizeTrigger__ = obj; obj.__resizeElement__ = ele; } handlers.push({ handler: handler, context: context }); }; EleResize.off = function (ele, handler, context) { var handlers = ele.__z_resizeListeners; if (handlers) { EleResize._removeHandler(ele, handler, context); if (handlers.length === 0) { var trigger = ele.__resizeTrigger__; if (trigger) { trigger.contentDocument.defaultView.removeEventListener( 'resize' , EleResize._handleResize); ele.removeChild(trigger); delete ele.__resizeTrigger__; } delete ele.__z_resizeListeners; } } } } |
測試代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
<!DOCTYPE html> < html lang = "en" > < head > < meta charset = "UTF-8" > < title >Resize</ title > < script src = "./EleResize.js" ></ script > < style > html, body { margin: 0; padding: 0; width: 100%; height: 100%; } #resizeDiv { width: 60%; height: 60%; border: 1px solid red; margin: 20px; } button { margin: 20px 20px 0; } </ style > </ head > < body > < button onclick = "addListener()" >addListener</ button > < button onclick = "removeListener()" >removeListener</ button > < button onclick = "resize()" >resize</ button > < div id = "resizeDiv" ></ div > < script > var resizeDiv = document.getElementById('resizeDiv'); function resize() { resizeDiv.style.width = "200px"; } var listener = function () { console.log("resize"); }; function addListener() { EleResize.on(resizeDiv, listener); } function removeListener() { EleResize.off(resizeDiv, listener) } </ script > </ body > </ html > |
原理
這里的具體實現(xiàn)分兩類,
- ie9-10
默認支持div的resize事件,可以直接通過div.attachEvent('onresize', handler);的方式實現(xiàn)
- 其它瀏覽器
通過在div中添加一個內(nèi)置object元素實現(xiàn)監(jiān)聽。
設置object元素的style使其填充滿div,這樣當div的size發(fā)生變化時,object的size也會發(fā)生變化。
然后監(jiān)聽object元素的contentDocument.defaultView(window對象)的resize事件。
注:本文提供的是如何監(jiān)聽resize事件,其實在resize時,可能會連續(xù)快速的觸發(fā)(比如拖動瀏覽器),為了提高效率,可以考慮使用批處理的模式。
到此這篇關于JS如何監(jiān)聽div的resize事件的文章就介紹到這了,更多相關JS監(jiān)聽div的resize事件內(nèi)容請搜索服務器之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://www.cnblogs.com/zhtui/p/7059943.html