iframe或document监听滚动事件不起作用

有时候我们会遇到监听iframe或document的滚动事件不起作用的情况,在排除代码写错的情况下,我们应该考虑此时的document是否可以滑动。

1、为什么document不能监听滑动?

就很奇怪,明明页面时有滚动条的,为什么说document不可滑动呢?

因为有的document.scrollingElement本身就不可滑动,可滑动的是它的子元素,而不document.scrollingElement本身,document.scrollingElement本身没有溢出问题,它的子元素有溢出问题并产生的scrollbar

 展示document不能滚动的DEMO:

<!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、什么是document.scrollingElement

scrollingElement(Document 的只读属性)返回滚动文档的 Element 对象的引用。在标准模式下,这是文档的根元素, document.documentElement。

当在怪异模式下,scrollingElement 属性返回 HTML body 元素(若不存在返回 null)。

3、为什么要有document.scrollingElement?

众所周知,获取浏览器高度是有兼容的,当我们需要设置滚动条的位置时,一般情况下:

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

document.body.scrollTop = 100; // 移动端

当有了document.scrollingElement后我们就不需要处理兼容问题了,两端通用

document.scrollingElement = 100; // 两端通用

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

引入scrollingelement.js可以兼容到下一个版本

4、用js代码测试元素是否可滑动

// 判断是否可滑动
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、监听iframe的滚动案例

5.1 document可滑动

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 document本身不可滑动

demo.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>
		<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>

猜你喜欢

转载自blog.csdn.net/qq_39998026/article/details/129283201
今日推荐