iframe or document listening to scroll events does not work

Sometimes we encounter the situation that listening to the scrolling event of iframe or document does not work. In the case of excluding code errors, we should consider whether the document can be slid at this time.

1. Why can't document monitor sliding?

It's very strange, obviously there are scroll bars on the page, why do you say that the document cannot be slid?

Because some document.scrollingElement itself is not slidable, it is its child elements that can be slidable, not document.scrollingElement itself, document.scrollingElement itself has no overflow problem, its child elements have overflow problems and produce scrollbar

 A DEMO showing that the document cannot be scrolled:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>document不能滑动,滑动的是它的子元素</title>
		<style>
			html,
			body {
				padding: 0;
				margin: 0;
			}
		</style>
	</head>

	<body>
		<div style="width: 100%;height: 100vh;overflow: auto;">
			<h1>这是1号标题</h1>
			<p>这是一个段落。</p>
			<p>这是一个段落。</p>
			<p>这是一个段落。</p>

			<h2>这是2号标题</h2>
			<p>这是一个段落。</p>
			<p>这是一个段落。</p>
			<p>这是一个段落。</p>

			<h3>这是3号标题</h3>
			<p>这是一个段落。</p>
			<p>这是一个段落。</p>
			<p>这是一个段落。</p>

			<h4>这是4号标题</h4>
			<p>这是一个段落。</p>
			<p>这是一个段落。</p>
			<p>这是一个段落。</p>

			<h5>这是5号标题</h5>
			<p>这是一个段落。</p>
			<p>这是一个段落。</p>
			<p>这是一个段落。</p>

			<h6>这是6号标题</h6>
			<p>这是一个段落。</p>
			<p>这是一个段落。</p>
			<p>这是一个段落。</p>
		</div>
	</body>

	<script>
		window.onload = function() {
			document.onscroll = function() {
				//获取滚动条的位置
				var scrollTop =
					document.documentElement.scrollTop ||
					document.body.scrollTop;
				console.log("滚动条的位置:", scrollTop);
			};
		};
	</script>

</html>

2. What is document.scrollingElement

scrollingElement (read-only property of Document) returns a reference to the Element object that scrolls the document. In standards mode, this is the document's root element, document.documentElement.

When in quirks mode, the scrollingElement property returns the HTML body element (or null if none exists).

3. Why is there document.scrollingElement?

As we all know, getting the browser height is compatible. When we need to set the position of the scroll bar, in general:

document.documentElement.scrollTop = 100; // PC端

document.body.scrollTop = 100; // mobile terminal

When we have document.scrollingElement, we don’t need to deal with compatibility issues, and both ends are common

document.scrollingElement = 100; // Common to both ends

Polyfill:https://github.com/mathiasbynens/document.scrollingElement

The introduction of scrollingelement.js is compatible to the next version

4. Use js code to test whether the element can slide

// 判断是否可滑动
function isScrollable(ele) {
	const hasScrollableContent = ele.scrollHeight > ele.clientHeight;
	const overflowYStyle = window.getComputedStyle(ele).overflowY;
	const isOverflowHidden = overflowYStyle.indexOf('hidden') !== -1;
	return hasScrollableContent && !isOverflowHidden;
}

5. Monitor the scrolling case of iframe

5.1 document can slide

demo.html

<!DOCTYPE html>
<html>

	<head>
		<meta charset="utf-8" />
		<title>iframe或document监听滚动事件</title>
	</head>

	<body>
		<iframe id="myframeId" src="./iframe.html" width="90%" height="200px">
			<p>你的浏览器不支持iframes。</p>
		</iframe>
	</body>

	<script>
		// 判断是否可滑动
		function isScrollable(ele) {
			const hasScrollableContent = ele.scrollHeight > ele.clientHeight;
			const overflowYStyle = window.getComputedStyle(ele).overflowY;
			const isOverflowHidden = overflowYStyle.indexOf('hidden') !== -1;
			return hasScrollableContent && !isOverflowHidden;
		}

		window.onload = function() {
			let result = isScrollable(document.scrollingElement);
			console.log("demo是否可滑动:", result)

			var frameWidow = document.getElementById("myframeId").contentWindow;
			console.log(frameWidow);

			// 两端通用
			// frameWidow.document.scrollingElement.scrollTop = 100
			// 适用PC端
			// frameWidow.document.documentElement.scrollTop = 200
			// 适用移动端
			// frameWidow.document.body.scrollTop = 300
			// scrollTo()方法
			frameWidow.scrollTo(0, 400)

			//监听
			frameWidow.onscroll = function() {
				//获取滚动条的位置
				var scrollTop =
					frameWidow.document.documentElement.scrollTop ||
					frameWidow.document.body.scrollTop;
				console.log("frame滚动条的位置:", scrollTop);
				
				// window.pageYOffset (支持IE9+)
				// var scrollTop = frameWidow.pageYOffset;
				
				// var scrollTop = frameWidow.document.scrollingElement.scrollTop;
			};
		};
	</script>

</html>

frame.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>iframe或document监听滚动事件</title>
		<style>
			html,
			body {
				padding: 0;
				margin: 0;
			}
		</style>
	</head>

	<body>
		<h1>这是1号标题</h1>
		<p>这是一个段落。</p>
		<p>这是一个段落。</p>
		<p>这是一个段落。</p>

		<h2>这是2号标题</h2>
		<p>这是一个段落。</p>
		<p>这是一个段落。</p>
		<p>这是一个段落。</p>

		<h3>这是3号标题</h3>
		<p>这是一个段落。</p>
		<p>这是一个段落。</p>
		<p>这是一个段落。</p>

		<h4>这是4号标题</h4>
		<p>这是一个段落。</p>
		<p>这是一个段落。</p>
		<p>这是一个段落。</p>

		<h5>这是5号标题</h5>
		<p>这是一个段落。</p>
		<p>这是一个段落。</p>
		<p>这是一个段落。</p>

		<h6>这是6号标题</h6>
		<p>这是一个段落。</p>
		<p>这是一个段落。</p>
		<p>这是一个段落。</p>
	</body>

	<script>
		// 判断是否可滑动
		function isScrollable(ele) {
			const hasScrollableContent = ele.scrollHeight > ele.clientHeight;
			const overflowYStyle = window.getComputedStyle(ele).overflowY;
			const isOverflowHidden = overflowYStyle.indexOf('hidden') !== -1;
			return hasScrollableContent && !isOverflowHidden;
		}

		window.onload = function() {
			console.log(document.scrollingElement)
			let result = isScrollable(document.scrollingElement);
			console.log("frame是否可滑动:", result)

			setTimeout(() => {
				// 两端通用
				// document.scrollingElement.scrollTop = 100
				// 适用PC端
				// frameWidow.document.documentElement.scrollTop = 200
				// 适用移动端
				// frameWidow.document.body.scrollTop = 300
				// scrollTo()方法
				// frameWidow.scrollTo(0, 400)
			})
		};
	</script>

</html>

5.2 The document itself cannot be slid

Demo.html is not modified, and frame.html is modified as follows:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>iframe或document监听滚动事件</title>
		<style>
			html,
			body {
				padding: 0;
				margin: 0;
			}
		</style>
	</head>

	<body>
		<div style="width: 100%;height: 100vh;overflow: auto;">
			<h1>这是1号标题</h1>
			<p>这是一个段落。</p>
			<p>这是一个段落。</p>
			<p>这是一个段落。</p>

			<h2>这是2号标题</h2>
			<p>这是一个段落。</p>
			<p>这是一个段落。</p>
			<p>这是一个段落。</p>

			<h3>这是3号标题</h3>
			<p>这是一个段落。</p>
			<p>这是一个段落。</p>
			<p>这是一个段落。</p>

			<h4>这是4号标题</h4>
			<p>这是一个段落。</p>
			<p>这是一个段落。</p>
			<p>这是一个段落。</p>

			<h5>这是5号标题</h5>
			<p>这是一个段落。</p>
			<p>这是一个段落。</p>
			<p>这是一个段落。</p>

			<h6>这是6号标题</h6>
			<p>这是一个段落。</p>
			<p>这是一个段落。</p>
			<p>这是一个段落。</p>
		</div>
	</body>

	<script>
		// 判断是否可滑动
		function isScrollable(ele) {
			const hasScrollableContent = ele.scrollHeight > ele.clientHeight;
			const overflowYStyle = window.getComputedStyle(ele).overflowY;
			const isOverflowHidden = overflowYStyle.indexOf('hidden') !== -1;
			return hasScrollableContent && !isOverflowHidden;
		}

		window.onload = function() {
			console.log(document.scrollingElement)
			let result = isScrollable(document.scrollingElement);
			console.log("frame是否可滑动:", result)

			setTimeout(() => {
				// 两端通用
				// document.scrollingElement.scrollTop = 100
				// 适用PC端
				// frameWidow.document.documentElement.scrollTop = 200
				// 适用移动端
				// frameWidow.document.body.scrollTop = 300
				// scrollTo()方法
				// frameWidow.scrollTo(0, 400)
			})
		};
	</script>

</html>

Guess you like

Origin blog.csdn.net/qq_39998026/article/details/129283201