逐步解决动态添加样式导致的元素闪烁 阿星小栈

2024-05-09 20:38

本文主要是介绍逐步解决动态添加样式导致的元素闪烁 阿星小栈,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 

元素闪烁很丑,难解决。

修改 Class 而不是 Style

我在不久前做过一个导航栏,要求其滚动到屏幕顶端后固定。很常见。开始的时候没问题,很快就可以搞定。

nav {position: absolute;top: 60px;
}
var scroll=0;
var nav=$("nav");
var navST=60; //该元素距离网页顶端60px$(window).scroll(function(){if($(document).scrollTop()>navST && scroll==0){nav.css({position: "fixed",top: "0"});scroll=1;}else if($(document).scrollTop()<=navST && scroll==1){nav.removeAttr("style");scroll=0;}
});

运行很流畅。

做好,我自然就忙着网页内容去了。没曾想,随着页面 JS 的不断增加,导航栏在固定时出现了可怕的闪动。

唔,就是 一下看得见 一下看不见 的东西!

应该有不少人和我一样。百度,无果。谷歌,看不懂,翻译也不行。
不知道真相的我,眼泪 流下来。

哦!一道莫名的亮光从我的眼前闪过!这道亮光里,有希望,,有兴奋,,组成了四个大字:

元素重绘

就在这千万分之一秒,亿万分之一秒 里,我理解了:

nav.css({position: "fixed",top: "0"});

这一句 JS 产生了两次 DOM 写入,影响浏览器渲染页面两次。

使用 $.addClass 语句可以解决。

nav {position: absolute;top: 60px;
}
.fixed {position: fixed;top: 0;
}
var scroll=0;
var nav=$("nav");
var navST=60; //该元素距离网页顶端60px$(window).scroll(function(){if($(document).scrollTop()>navST && scroll==0){nav.addClass("fixed");scroll=1;}else if($(document).scrollTop()<=navST && scroll==1){nav.removeClass("fixed");scroll=0;}
});

闪烁问题得到了临时解决。

采用不可见元素减少 DOM 变更产生的运算

“临时” 说法的原因是当 JS 数量再次增加,达到又一新高度后,闪烁问题再现。
原因大概是 $.addClass 时浏览器需要重新计算该元素位置, JS 数量过多使计算过程明显。
不多说,在 HTML 里多放一个包含 .fixed 的宽高为 0 的元素即可解决。

<div class="fixed"></div>
<nav>something...</nav>

别让这个 div.fixed 显示出来。

至此,全面解决 “动态添加样式导致的元素闪烁” 。

原生 JS 进一步加快速度避免闪烁

jQuery 是个好东西。原生 JS 更是个好东西。

有些 jQuery 代码,被转化为好多条原生 JS 才实现效果。
然而其实只需要一条。
将 jQuery 代码转化为原生 JS 是个加快速度,避免闪烁的不二选择。

var scroll=0;
var navST=60; //该元素距离网页顶端60pxwindow.onscroll = function(){if(document.documentElement.scrollTop || document.body.scrollTop>navST && scroll==0){document.getElementsByTagName("nav")[0].classList.add("fixed");scroll=1;}else if(document.documentElement.scrollTop || document.body.scrollTop<=navST && scroll==1){document.getElementsByTagName("nav")[0].classList.remove("fixed");scroll=0;}
};

谢谢阅读!

 

原文链接:https://segmentfault.com/a/1190000006216880

这篇关于逐步解决动态添加样式导致的元素闪烁 阿星小栈的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/974444

相关文章

qt5cored.dll报错怎么解决? 电脑qt5cored.dll文件丢失修复技巧

《qt5cored.dll报错怎么解决?电脑qt5cored.dll文件丢失修复技巧》在进行软件安装或运行程序时,有时会遇到由于找不到qt5core.dll,无法继续执行代码,这个问题可能是由于该文... 遇到qt5cored.dll文件错误时,可能会导致基于 Qt 开发的应用程序无法正常运行或启动。这种错

SpringBoot排查和解决JSON解析错误(400 Bad Request)的方法

《SpringBoot排查和解决JSON解析错误(400BadRequest)的方法》在开发SpringBootRESTfulAPI时,客户端与服务端的数据交互通常使用JSON格式,然而,JSON... 目录问题背景1. 问题描述2. 错误分析解决方案1. 手动重新输入jsON2. 使用工具清理JSON3.

MySQL 设置AUTO_INCREMENT 无效的问题解决

《MySQL设置AUTO_INCREMENT无效的问题解决》本文主要介绍了MySQL设置AUTO_INCREMENT无效的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参... 目录快速设置mysql的auto_increment参数一、修改 AUTO_INCREMENT 的值。

关于跨域无效的问题及解决(java后端方案)

《关于跨域无效的问题及解决(java后端方案)》:本文主要介绍关于跨域无效的问题及解决(java后端方案),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录通用后端跨域方法1、@CrossOrigin 注解2、springboot2.0 实现WebMvcConfig

Go语言中泄漏缓冲区的问题解决

《Go语言中泄漏缓冲区的问题解决》缓冲区是一种常见的数据结构,常被用于在不同的并发单元之间传递数据,然而,若缓冲区使用不当,就可能引发泄漏缓冲区问题,本文就来介绍一下问题的解决,感兴趣的可以了解一下... 目录引言泄漏缓冲区的基本概念代码示例:泄漏缓冲区的产生项目场景:Web 服务器中的请求缓冲场景描述代码

解决JSONField、JsonProperty不生效的问题

《解决JSONField、JsonProperty不生效的问题》:本文主要介绍解决JSONField、JsonProperty不生效的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录jsONField、JsonProperty不生效javascript问题排查总结JSONField

github打不开的问题分析及解决

《github打不开的问题分析及解决》:本文主要介绍github打不开的问题分析及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、找到github.com域名解析的ip地址二、找到github.global.ssl.fastly.net网址解析的ip地址三

MySQL版本问题导致项目无法启动问题的解决方案

《MySQL版本问题导致项目无法启动问题的解决方案》本文记录了一次因MySQL版本不一致导致项目启动失败的经历,详细解析了连接错误的原因,并提供了两种解决方案:调整连接字符串禁用SSL或统一MySQL... 目录本地项目启动报错报错原因:解决方案第一个:第二种:容器启动mysql的坑两种修改时区的方法:本地

Java调用C#动态库的三种方法详解

《Java调用C#动态库的三种方法详解》在这个多语言编程的时代,Java和C#就像两位才华横溢的舞者,各自在不同的舞台上展现着独特的魅力,然而,当它们携手合作时,又会碰撞出怎样绚丽的火花呢?今天,我们... 目录方法1:C++/CLI搭建桥梁——Java ↔ C# 的“翻译官”步骤1:创建C#类库(.NET

RedisTemplate默认序列化方式显示中文乱码的解决

《RedisTemplate默认序列化方式显示中文乱码的解决》本文主要介绍了SpringDataRedis默认使用JdkSerializationRedisSerializer导致数据乱码,文中通过示... 目录1. 问题原因2. 解决方案3. 配置类示例4. 配置说明5. 使用示例6. 验证存储结果7.