vue+elementUi gets the scroll bar position, determines whether there is a scroll bar, addEventListener, removeEventListener, document, window, scroll, client


1. vue2 gets the scroll bar position

document mode

export default {
    
    
	name: "demo",
	data() {
    
    
		return {
    
    
			scrollTopVal: 0,
			isScroll: 0
		};
	},
	mounted() {
    
    
		this.$nextTick(() => {
    
    
			// 开启滚动条监听
			document.addEventListener("scroll", this.scrollTop, true);
			
			let elVal = document.getElementsByClassName('el-drawer__body')[0];
			this.isScroll = elVal.scrollHeight > elVal.clientHeight;
		});
	},
	beforeDestroy() {
    
    
		document.removeEventListener('scroll', this.scrollTop, true);
	},
	
	methods: {
    
    
		scrollTop() {
    
    
			let elVal = document.getElementsByClassName('el-drawer__body')[0];
			this.scrollTopVal = elVal.scrollTop;
		}
	}
};

window mode

export default {
    
    
	name: "demo",
	data() {
    
    
		return {
    
    
			scrollTopVal: 0,
			isScroll: 0
		};
	},
	mounted() {
    
    
		this.$nextTick(() => {
    
    
			// 开启滚动条监听
			window.addEventListener("scroll", this.scrollTop, true);
			
			let elVal = document.documentElement.scrollTop || document.body.scrollTop || window.pageYOffset;
			this.isScroll = elVal.scrollHeight > elVal.clientHeight;
		});
	},
	beforeDestroy() {
    
    
		window.removeEventListener('scroll', this.scrollTop, true);
	},

	methods: {
    
    
		scrollTop() {
    
    
			let elVal = document.documentElement.scrollTop || document.body.scrollTop || window.pageYOffset;
			this.scrollTopVal = elVal.scrollTop;
		},
	}
};

2. vue3 gets the scroll bar position

Public section

import {
    
     nextTick, ref, onMounted, onBeforeUnmount } from "vue";

let scrollTopVal = ref<number>(0);
let isScroll = ref<boolean>(false);

document mode

onMounted(() => {
    
    
	// 监听滚动条位置
	document.addEventListener("scroll", scrollTop, true);
	
	// 设置对应元素的滚动条
	let elVal: any = document.getElementsByClassName('el-drawer__body')[0];
	// 判断是否存在滚动条
	isScroll.value = elVal.scrollHeight > elVal.clientHeight;
});

// 实时滚动条高度
const scrollTop = () => {
    
    
	nextTick(() => {
    
    
		let elVal: any = document.getElementsByClassName('el-drawer__body')[0];
		scrollTopVal.value = elVal.scrollTop;
	});
};

onBeforeUnmount(() => {
    
    
	// 参数必须和挂载时保持一致
	document.removeEventListener('scroll', scrollTop, true);
});

window mode

onMounted(() => {
    
    
	// 监听滚动条位置
	window.addEventListener('scroll', scrollTop, true);
	
	let elVal: any = document.documentElement.scrollTop || document.body.scrollTop || window.pageYOffset;
	isScroll.value = elVal.scrollHeight > elVal.clientHeight;
});

// 实时滚动条高度
const scrollTop = () => {
    
    
	nextTick(() => {
    
    
		let elVal: any = document.documentElement.scrollTop || document.body.scrollTop || window.pageYOffset;
		scrollTopVal.value = elVal.scrollTop;
	});
};

onBeforeUnmount(() => {
    
    
	// 参数必须和挂载时保持一致
	window.removeEventListener('scroll', scrollTop, true);
});

3. Analysis

1. Get the scroll bar value of the specified element. It needs to be obtained in elementUithe component classbecause idit is a dynamic value.
2. windowWhen using the method, only bodythe scroll bars of the or page window can be detected. However, for elementUipop-up windows and other components, the scroll bar value obtained is 0.
3. addEventListenerThe third parameter represents deep monitoring. In some scenarios, if the third parameter value is not set true, the corresponding event may not be monitored.
4. addEventListenerThe second parameter requires a function value, which can be written directly in the form of a function, but this is not recommended.
5. addEventListenerThe first parameter is the corresponding event name, including scroll events, mouse events and other events.
6. scrollThe event must be destroyed, because it is vuea single-page application. If not destroyed, the event will still exist after leaving the page, affecting the performance of the browser, and an error will be vue3reported directly in the application. Therefore, the global listening event should be destroyed before leaving this page, and the global listening event can be destroyed before the component is destroyed.


4. Determine whether there is a scroll bar

Determining whether there is a need for scroll bars is often used in pop-up plug-ins. Because most pop-up windows will add overflow: hidden;attributes, if the page exceeds one screen, the page will shake after adding this attribute. In order to enhance the user experience, add attributes to offset the subsequent scroll bar position
by determining whether there is a scroll bar .margin-leftoverflow: hidden;


Determine vertical scroll bar

console.log(el.scrollHeight > el.clientHeight);

Determine horizontal scroll bar

console.log(el.scrollWidth > el.clientWidth);

Special case

When the element is specified overflow: hidden;, no scrollbars appear. overflow: hidden;Therefore, it is necessary to judge whether the element is applied .

function hasScrolled(ele, dir = "vertical") {
    
    
  // 判断的方向是否设置了overflow: hidden;
  let style = window.getComputedStyle(ele);
  if (
    (dir == "vertical" && style.overflowY == "hidden") ||
    (dir == "horizontal" && style.overflowX == "hidden")
  )
    return false;

  // 在判断完overflow不为hidden后,再通过两个属性来判断。
  if (dir == "vertical") {
    
    
    return ele.scrollHeight > ele.clientHeight;
  } else {
    
    
    return ele.scrollWidth > ele.clientWidth;
  }
}

However, the above method is not rigorous, and it will also happen when the container has margins merged ele.scrollWidth > ele.clientWidth.


<div class="box">
	<h1>子元素内部内容</h1>
</div>

let box = document.querySelector(".box");

// scrollHeight: 63
console.log("scrollHeight: " + box.scrollHeight);
// clientHeight: 42
console.log("clientHeight: " + box.clientHeight);
// 是否有滚动条: true
console.log("是否有滚动条: ", box.scrollHeight > box.clientHeight);

The perfect way to handle special situations

function hasScrolled(ele, dir = "vertical") {
    
    
	let eleScroll = dir == "vertical" ? "scrollTop" : "scrollLeft";
	
	// 判断scroll数值是否为0,还是其他值
	let result = !!ele[eleScroll];
	// 如果是其他数值(非0)这表示有滚动条
	// 如果是0,则尝试移动一下滚动条,判断是否能够移动
	if (!result) {
    
    
		// 尝试移动滚动条
		ele[eleScroll] = 1;
		// 再次确认数值
		result = !!ele[eleScroll];
		// 恢复原位
		ele[eleScroll] = 0;
	}
	
	// 得出结果
	return result; 
}

How to calculate scroll bar width

Because the scroll bars of mobile browsers are transparent styles that do not occupy the width of the page, in order to further enhance the user experience, we also need to calculate the width of the scroll bar and add a reasonable value according to the situation margin-left.
Create a new element with a scroll bar div, and then calculate the difference between the element offsetWidthand the element clientWidth.

function getScrollbarWidth() {
     
     
	let scrollDiv = document.createElement("div");
	scrollDiv.style.cssText = "width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;";
	document.body.appendChild(scrollDiv);
	let scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
	document.body.removeChild(scrollDiv);
	
	return scrollbarWidth;
}

Guess you like

Origin blog.csdn.net/weixin_51157081/article/details/130524259