前端实习:实现一个侧边栏弹窗 + GPU加速优化动画 + 事件委托优化

前文

今天我们来一起学习如何实现一个侧边栏弹窗并且使用GPU加速优化动画和事件委托机制优化代码

一、需求分析

平台左侧需要一个点击的出现的侧边栏

关闭状态:

打开状态:

代码实现:

xml 复制代码
<template>
	<!-- 侧边栏容器,捕获DOM节点 -->
	<div ref="donateContentDiv" class="homeSidebar-container">
		<!-- 标题栏 -->
		<div class="homeSidebar-container-title" @click="toggleDonateContentDiv">
			<!-- 箭头图标旋转特效 -->
			<span class="container-title-text" :class="{ 'rotate-icon': isContentDivVisible }"><CaretRight /></span>
		</div>

		<!-- 内容栏 -->
		<div class="homeSidebar-container-content" @click="itemJump">
			<!-- 数据项 -->
			<div class="container-content-item" v-for="item in dataArr" :key="item.url" :data-vid="item.id">{{item.title}}</div>
		</div>
	</div>
</template>

<script setup>
import { ref } from 'vue';

// DOM节点引用
const donateContentDiv = ref(null);
// 控制内容栏显示与隐藏
const isContentDivVisible = ref(false);

// 数据数组
const dataArr = ref([
	{ id:1, url: 'xxx', title:"xxx"},
	{ id:2, url: 'xxx', title:"xxx"},
	{ id:3, url: 'xxx', title:"xxx"},
	{ id:4, url: 'xxx', title:"xxxx"},
	{ id:5, url: 'xxx', title:"xxx"},
	{ id:6, url: 'xxx', title:"xxx"},
	{ id:7, url: 'xxx', title:"xxx"},
	{ id:8, url: 'xxx', title:"xxx"},
	{ id:9, url: 'xxx', title:"xxx"},
]);

// 切换内容栏显示与隐藏
const toggleDonateContentDiv = () => {
	const leftValue = donateContentDiv.value.style.left;
	donateContentDiv.value.style.left = leftValue === '0px' ? '-245px' : '0px';
	isContentDivVisible.value = !isContentDivVisible.value;
};

// 处理数据项点击事件
const itemJump = (e) => {
	const customIdValue = e.target.dataset.vid;
	alert(customIdValue);
};
</script>

<style lang="scss" scoped>
// 必须设置hover ,否则will-change: transform;属性不会生效
.homeSidebar-container:hover {
        /* GPU加速优化动画 */
	-webkit-will-change: transform;
	will-change: transform;
}

.homeSidebar-container {
	/* 侧边栏容器样式 */
        /* GPU加速优化动画 */
	-webkit-transform: translateZ(0);
	z-index: 3;
	opacity: 1;
	width: 245px;
	height: 60%;
	padding: 20px;
	box-shadow: 0 0px 5px 2px #44cef6;
	background-color: #fff;
	position: fixed;
	top: 20%;
	left: -245px;
	transition: left 0.35s ease-in-out;

	// 标题栏样式
	.homeSidebar-container-title {
		width: 30px;
		height: 60px;
		background: #fff;
		position: absolute;
		top: 40%;
		left: 246px;

		// 箭头图标旋转效果
		.rotate-icon {
			transition: transform 1s ease-in-out;
			transform: rotate(180deg);
		}

		.container-title-text {
			/* 标题文本样式 */
			margin: 15px 0 0 1px;
			display: inline-block;
			width: 25px;
			height: 25px;
			font-size: 18px;
			text-align: center;
			line-height: 25px;
			border-radius: 100%;
			color: #fff !important;
			background-image: linear-gradient(120deg, #a1c4fd 0%, #c2e9fb 100%);
		}
	}

	// 内容栏样式
	.homeSidebar-container-content {
		display: flex;
		width: 100%;
		height: 100%;
		max-height: 400px;
		overflow: auto;
		flex-wrap: wrap;
		justify-content: space-between;

		// 数据项样式
		.container-content-item {
			padding: 20px 0 0 0;
			text-align: center;
			color: #fff !important;
			background: #44cef6;
			width: 40%;
			height: 15%;
			max-height: 80px;
		}
	}
}
</style>

二、原理分析

(1)动画部分(很简单不再赘述)

(2)GPU加速优化动画(没加之前动画会很卡)

css 复制代码
.homeSidebar-container:hover {
        /* GPU加速优化动画 */
	-webkit-will-change: transform;
	will-change: transform;
}

.homeSidebar-container {
	/* 侧边栏容器样式 */
        /* GPU加速优化动画 */
	-webkit-transform: translateZ(0);
        }

说明:

GPU加速的原理

要理解GPU加速的原理,我们需要了解浏览器渲染流程的基本概念。

1.浏览器在渲染网页时,会经历一系列的步骤,如样式计算、布局、绘制和合成。为了提高性能,浏览器会尽量避免进行不必要的计算和操作。

  1. will-change-webkit-transform: translateZ(0);的作用

will-change的作用就是告诉浏览器某个元素将要发生的变化,从而使浏览器在渲染过程中提前分配和优化相应的资源。

例如,当我们设置了will-change: transform时,浏览器会为该元素创建一个独立的图层,将这个图层标记为"即将变换"。这样,在进行布局和绘制时,浏览器就可以更高效地处理这个元素,而无需重新计算整个渲染树。

浏览器中图层一般包含两大类:渲染图层(普通图层)以及复合图层

怎么看图层:blog.csdn.net/Henry2Ti/ar...

渲染图层,是页面普通的文档流。我们虽然可以通过绝对定位,相对定位,浮动定位脱离文档流,但它仍然属于默认复合层(根层叠上下文),共用同一个绘图上下文对象(GraphicsContext)。 复合图层,又称图形层。它会单独分配系统资源,每个复合图层都有一个独立的GraphicsContext。(当然也会脱离普通文档流,这样一来,不管这个复合图层中怎么变化,也不会影响默认复合层里的回流重绘)

相当于,通过will-change或者-webkit-transform: translateZ(0);属性,提示计算机页面元素即将发生变化,需要计算机协调GPU来帮助计算,不占用CPU的资源,自然就会变得不卡顿

3.需要注意的点:

一些低版本的浏览器不支持will-change属性

这个时候需要使用-webkit-transform: translateZ(0);属性(hack加速) 触发hack加速的元素

css 复制代码
.haorooms_element {
    -webkit-transform: translateZ(0);
    -moz-transform: translateZ(0);
    -ms-transform: translateZ(0);
    -o-transform: translateZ(0);
    transform: translateZ(0); 
    /**或者**/
    transform: rotateZ(360deg);
    transform: translate3d(0, 0, 0);
}

使用will-change属性时,会消耗额外的内存,注意不要滥用will-change属性,内存会爆炸的

使用will-change属性时,需要在css绑定:hover这类选择器,提示计算机

错误示例:(在此,当我们通知浏览器时,已经在进行更改,从而完全抵消了will-change属性的全部内容。 如果我们希望浏览器提前知道什么时候会发生更改,则必须在适当的时候通知它。)

css 复制代码
.homeSidebar-container: {
  will-change: transform;
  transition: transform 0.3s;
  transform: scale(1.5);
}

正确示例:

css 复制代码
.homeSidebar-container:hover {
        /* GPU加速优化动画 */
	-webkit-will-change: transform;
	will-change: transform;
}

可以看看这篇文章

blog.csdn.net/qiwoo_weekl...

(3)事件委托优化 事件委托又叫事件代理,是指利用事件冒泡的特性,将本应该注册在子元素上事件注册在父元素上,由父元素来处理子元素的事件。这样的好处是:

1.有助于降低DOM操作,提高性能。

2.增加扩展性,子元素可以随意增加,不用再做其他额外的操作,都在父元素上做事件处理操作

3.有助于代码简洁高效性,不用为每个子元素添加事件处理程序,简化了代码处理逻辑。

Html:

xml 复制代码
<div class="homeSidebar-container-content" @click="itemJump">
			<!-- 数据项 -->
			<div class="container-content-item" v-for="item in dataArr" :key="item.url" :data-vid="item.id">{{item.title}}</div>

Js:

ini 复制代码
// 处理数据项点击事件
const itemJump = (e) => {
	const customIdValue = e.target.dataset.vid;
	alert(customIdValue);
};

这里我设置了一个自定义属性,data-vid,点击之后,子元素通过冒泡,传递自己的id到方法中,由此可以实现指定的路由跳转

相关推荐
滚雪球~43 分钟前
npm error code ETIMEDOUT
前端·npm·node.js
沙漏无语44 分钟前
npm : 无法加载文件 D:\Nodejs\node_global\npm.ps1,因为在此系统上禁止运行脚本
前端·npm·node.js
supermapsupport1 小时前
iClient3D for Cesium在Vue中快速实现场景卷帘
前端·vue.js·3d·cesium·supermap
brrdg_sefg1 小时前
WEB 漏洞 - 文件包含漏洞深度解析
前端·网络·安全
胡西风_foxww1 小时前
【es6复习笔记】rest参数(7)
前端·笔记·es6·参数·rest
m0_748254881 小时前
vue+elementui实现下拉表格多选+搜索+分页+回显+全选2.0
前端·vue.js·elementui
星就前端叭2 小时前
【开源】一款基于Vue3 + WebRTC + Node + SRS + FFmpeg搭建的直播间项目
前端·后端·开源·webrtc
m0_748234522 小时前
前端Vue3字体优化三部曲(webFont、font-spider、spa-font-spider-webpack-plugin)
前端·webpack·node.js
Web阿成2 小时前
3.学习webpack配置 尝试打包ts文件
前端·学习·webpack·typescript
jwensh3 小时前
【Jenkins】Declarative和Scripted两种脚本模式有什么具体的区别
运维·前端·jenkins