Monitor the size change of a DOM element through iframe

Monitor the size change of a DOM element through iframe

A common problem encountered during the development process is how to monitor the size changes of a div. For example, if I use canvas to draw a chart, when the size of canvas changes, I need to redraw the content inside. At this time, I need to listen to the resize event for processing. Although there is a resize event listener on the window, this cannot meet our needs, because in many cases, the size of the div changes, and the actual window.resize event is not triggered.

There are many ways to monitor the resize event of a div, such as timer checking, scroll events, etc. This article mainly introduces how to monitor through the iframe element.

However, we can indirectly use the window's resize event listener to implement the resize event listener for a certain div. Please see the specific implementation below.

2. Implementation Principle

  • Dynamically create an iframe tag and append it to the container, with the width and height inheriting 100% of the container;
  • Get the window in the iframe through the contentWindow attribute;
  • Since the width and height of the iframe are inherited from the parent node, when the width of the parent container changes, the resize event in the iframe will naturally be triggered;

Use the iframeWindow.resize event to monitor DOM size changes, thereby achieving a monitoring of the resize event;

example

document.querySelector("#ifarme_id").contentWindow.addEventListener('resize', () => {
    console.log('size Change!');
}, false)

3. Call

<!DOCTYPE html>
<html>
    <head>
	<meta charset="utf-8">
	<title>DIV width and height monitoring</title>
    <style type="text/css">
        #content {
        overflow:auto;
			}
		</style>
	</head>
	<body>
	<div id="content">
            Zhong Nanshan: If Africa takes good precautions, the epidemic will decrease when the weather is hot. In addition, a foreigner asked at the meeting: If you go to Africa now, what would you do first?
        	Zhong Nanshan said: What we need to do now is protection, and preventing the spread is the most important thing.
        	In Africa, if good prevention is taken during this period, the epidemic situation may decline when the weather gets hot.
		</div>

		<button id="change-size">Change width and height</button>

		<script type="text/javascript">
			var eleResize = new ElementResize('#content');
			eleResize.listen(function() {
				console.log('size change!')
			})

			//Change width and height document.querySelector('#change-size').addEventListener('click', function() {
				let cont = document.querySelector('#content');
				cont.style.width = Math.floor((Math.random() * (document.documentElement.clientWidth - 500)) + 500) + 'px';
				cont.style.height = Math.floor(Math.random() * 300) + 'px';
			}, false)
		</script>
	</body>
</html>

Complete code

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>DIV width and height monitoring</title>
		<style type="text/css">
			#content {
				overflow:auto;
			}
		</style>
	</head>
	<body>
		<div id="content">
			Zhong Nanshan: If Africa takes good precautions, the epidemic will decrease when the weather is hot. In addition, a foreigner asked at the meeting: If you go to Africa now, what would you do first?

			Zhong Nanshan said: What we need to do now is protection, and preventing the spread is the most important thing.

			In Africa, if good prevention is taken during this period, the epidemic situation may decline when the weather gets hot.
		</div>
		<button id="change-size">Change width and height</button>

		<script type="text/javascript">
			(function() {
				let self = this;
				/**
				 * Element width and height monitoring * @param {Object} el monitoring element selector */
				function ElementResize(eleSelector) {
					if (!(this instanceof ElementResize)) return;
					if (!eleSelector) return;
					this.eleSelector = eleSelector;
					this.el = document.querySelector(eleSelector);
					this.queue = [];
					this.__init(); //globel init
				}

				// Initialization ElementResize.prototype.__init = function() {
					let iframe = this.crateIElement();
					this.el.style.position = 'relative';
					this.el.appendChild(iframe)
					this.bindEvent(iframe.contentWindow);
				}

				/**
				 * Set element style * @param {HTMLObject} el
				 * @param {Object} styleJson
				 */
				ElementResize.prototype.setStyle = function(el, styleJson) {
					if (!el) return;
					styleJson = styleJson || {
						opacity: 0,
						'z-index': '-1111',
						position: 'absolute',
						left: 0,
						top: 0,
						width: '100%',
						height: '100%',
					};
					let styleText = '';
					for (key in styleJson) {
						styleText += (key + ':' + styleJson[key] + ';');
					}
					el.style.cssText = styleText;
				}

				/**
				 * Create element * @param {Object} style
				 */
				ElementResize.prototype.crateIElement = function(style) {
					let iframe = document.createElement('iframe');
					this.setStyle(iframe);
					return iframe;
				}

				/**
				 * Binding event * @param {Object} el
				 */
				ElementResize.prototype.bindEvent = function(el) {
					if (!el) return;
					var _self = this;
					el.addEventListener('resize', function() {
						_self.runQueue();
					}, false)
				}

				/**
				 * Run queue */
				ElementResize.prototype.runQueue = function() {
					let queue = this.queue;
					for (var i = 0; i < queue.length; i++) {
						(typeof queue[i]) === 'function' && queue[i].apply(this);
					}
				}

				/**
				 * External monitoring * @param {Object} cb callback function */
				ElementResize.prototype.listen = function(cb) {
					if (typeof cb !== 'function') throw new TypeError('cb is not a function!');
					this.queue.push(cb);
				}

				self.ElementResize = ElementResize;
			})()
			
			//Create a listening instance var eleResize = new ElementResize('#content');
			eleResize.listen(function() {
				console.log('I am a listener')
			})

			//Switch width and height document.querySelector('#change-size').addEventListener('click', function() {
				let cont = document.querySelector('#content');
				cont.style.width = Math.floor((Math.random() * (document.documentElement.clientWidth - 500)) + 500) + 'px';
				cont.style.height = Math.floor(Math.random() * 300) + 'px';
			}, false)
		</script>
	</body>
</html>

More features are being updated...

This is the end of this article about monitoring the size changes of a DOM element through iframe. For more relevant DOM element changes, please search 123WORDPRESS.COM’s previous articles or continue to browse the following related articles. I hope you will support 123WORDPRESS.COM in the future!

<<:  Several common redirection connection example codes in html

>>:  Solve the problem of data synchronization when vue-seamless-scroll scrolls and likes

Recommend

Summary of ten Linux command aliases that can improve efficiency

Preface Engineers working in the Linux environmen...

Nginx solves cross-domain issues and embeds third-party pages

Table of contents Preface difficulty Cross-domain...

JS 4 super practical tips to improve development efficiency

Table of contents 1. Short circuit judgment 2. Op...

A brief analysis of how to use border and display attributes in CSS

Introduction to border properties border property...

Detailed explanation of Nginx's rewrite module

The rewrite module is the ngx_http_rewrite_module...

Writing a web calculator using javascript

This article mainly records the effect of using j...

JS Object constructor Object.freeze

Table of contents Overview Example 1) Freeze Obje...

Tomcat maxPostSize setting implementation process analysis

1. Why set maxPostSize? The tomcat container has ...

vsftpd virtual user based on MySql authentication

Table of contents 1. MySQL installation 1.2 Creat...

jQuery implements font size adjustment case

This article shares the specific code of jQuery t...

Detailed explanation of webpage screenshot function in Vue

Recently, there is a requirement for uploading pi...

Use of VNode in Vue.js

What is VNode There is a VNode class in vue.js, w...