动态加载css详解

这次给大家带来动态加载css详解,动态加载css的注意事项有哪些,下面就是实战案例,一起来看一下。

一、方法引用来源和应用

此动态加载css方法 loadCss,剥离自Sea.js,并做了进一步的优化(优化代码后续会进行分析)。

因为公司项目需要用到懒加载来提高网站加载速度,所以将非首屏渲染必需的css文件进行动态加载操作。

二、优化后的完整代码

/** @function 动态加载css文件* @param {string} options.url -- css资源路径* @param {function} options.callback -- 加载后回调函数* @param {string} options.id -- link标签id*/function loadCss(options){    var url = options.url,        callback = typeof options.callback == "function" ? options.callback : function(){},        id = options.id,        node = document.createElement("link"),        supportOnload = "onload" in node,        isOldWebKit = +navigator.userAgent.replace(/.*(?:AppleWebKit|AndroidWebKit)\/?(\d+).*/i, "$1")  protectNum){            isLoaded = true;            // 清空node引用            node = null;            callback();            return;        }        if(isOldWebKit){            // for WebKit < 536            if(sheet){                isLoaded = true;            }        }else if(sheet){            // for Firefox < 9.0            try{                if(sheet.cssRules){                    isLoaded = true;                }            }catch(ex){                // 火狐特殊版本,通过特定值获知是否下载成功                // The value of `ex.name` is changed from "NS_ERROR_DOM_SECURITY_ERR"                // to "SecurityError" since Firefox 13.0. But Firefox is less than 9.0                // in here, So it is ok to just rely on "NS_ERROR_DOM_SECURITY_ERR"                if(ex.name === "NS_ERROR_DOM_SECURITY_ERR"){                    isLoaded = true;                }            }        }        setTimeout(function() {            if(isLoaded){                // 延迟20ms是为了给下载的样式留够渲染的时间                callback();            }else{                pollCss(node, callback, step);            }        }, 20);    }}

三、解析代码

一、参数

本方法支持三个参数,可进行扩展。

1.1 opations.url

 url是需要引入的css资源路径,也即标签的href属性内容。

1.2 options.id

 id是标签的id属性。这个参数为非必要参数,可不传。主要作用是标记当前标签,方便js进行查找,以确定是否已加载某个css文件。

1.3 options.callback

 callback是css文件加载完成后会调用的回调函数。也存在特殊场景下,文件加载失败,回调函数仍旧执行的情况。

二、生成标签,并插入头部head,进行加载资源

var url = options.url,    callback = typeof options.callback == "function" ? options.callback : function(){},    id = options.id,    node = document.createElement("link");node.rel = "stylesheet";node.type = "text/css";node.href = url;if( typeof id !== "undefined" ){    node.id = id;}document.getElementsByTagName("head")[0].appendChild(node);

生成一个dom节点,然后配置好rel、type、href等必需的属性值,以便浏览器能正常解析链接的资源。

接着,查找到head节点,将节点插入。

三、实现css资源下载状态监控的pollCss方法

 pollCss方法的职责是判断插入的link节点,也即node变量反馈资源是否已加载完成。

3.1 判断的主要依据

浏览器加载css资源,会给该link节点生成sheet属性,可以根据浏览器不同,读取sheet属性相关内容,来判断是否已经加载完成。所以第一句语句var sheet = node.sheet首先要做的就是获取sheet属性值。

3.2 普通浏览器判断

try{    if(sheet.cssRules){        isLoaded = true;    }}catch(ex){    // 火狐特殊版本,通过特定值获知是否下载成功    // The value of `ex.name` is changed from "NS_ERROR_DOM_SECURITY_ERR"    // to "SecurityError" since Firefox 13.0. But Firefox is less than 9.0    // in here, So it is ok to just rely on "NS_ERROR_DOM_SECURITY_ERR"    if(ex.name === "NS_ERROR_DOM_SECURITY_ERR"){        isLoaded = true;    }}

如果读取sheet.cssRules有值,证明css资源已经链接进页面,并开始解析。此时可以判断资源加载成功。

如果读取失败,则根据抛错内容,判断是否有特定name属性ex.name === “NS_ERROR_DOM_SECURITY_ERR”。存在,则代表是低版本火狐(9.0以前),且资源已经加载成功。

3.3 旧webkit内核浏览器判断

var isOldWebKit = +navigator.userAgent.replace(/.*(?:AppleWebKit|AndroidWebKit)\/?(\d+).*/i, "$1") < 536; // webkit旧内核做特殊处理if(isOldWebKit){    // for WebKit < 536    if(sheet){        isLoaded = true;    }}

如果是webkit旧内核浏览器,则只需要判断sheet属性值存在,则代表资源加载完成。

3.4 增加多次循环检测

setTimeout(function() {    if(isLoaded){        // 延迟20ms是为了给下载的样式留够渲染的时间        callback();    }else{        pollCss(node, callback, step);    }}, 20);

触发pollCss方法后,可能第一次检测sheet值,会检测不到。也就代表还没加载完成。所以需要进行轮询。这里是隔20ms进行一次问询,直到资源加载完成为止。

3.5 轮询容错(针对Sea.js源码的优化)

 css资源加载也有可能出错的时机存在,而且存在不触发onerror方法的可能性。如果不加一个保护,则轮询可能一直持续下去,所以需要有一个极限阈值。

var protectNum = 300000, // 阈值10分钟,一秒钟执行pollCss 500次    step = 0;// 很多代码....step += 1;// 保护,大于10分钟,则不再轮询if(step > protectNum){    isLoaded = true;    // 清空node引用    node = null;    callback();    return;}

这里的阈值是轮询10分钟,如果10分钟后,仍然不符合条件,则默认资源已下载完成,执行callback方法,并清空node引用。

四、确定触发pollCss检查的时机

 4.1 pollCss轮询的应用场景

当浏览器内核是旧的webkit内核时,或者不支持节点触发onload方法时,才使用pollCss进行轮询。

// for Old WebKit and Old Firefoxif (isOldWebKit || !supportOnload) {    // Begin after node insertion    setTimeout(function() {        pollCss(node, callback, 0);    }, 1);    return;}

五、现代浏览器直接用onload和onreadystatechange做判断

现代浏览器用这种方式判断,可以避免轮询的弊端。判断也更加准确及时。

 5.1 onload方法

function onload() {    // 确保只跑一次下载操作    node.onload = node.onerror = node.onreadystatechange = null;    // 清空node引用,在低版本IE,不清除会造成内存泄露    node = null;    callback();}

 onload方法触发执行后,应立即将多个相关方法进行重置,以避免callback多次触发。

 node = null;将node重置为null,是为了避免低版本的IE出现内存溢出问题,及时清除没用的dom节点。

最后,执行callback方法。

5.2 支持onload方法浏览器的处理

if(supportOnload){    node.onload = onload;    node.onerror = function() {        // 加载失败(404)        onload();    }}

5.3 不支持onload方法浏览器的处理

if(supportOnload){    // 代码...}else{    node.onreadystatechange = function() {        if (/loaded|complete/.test(node.readyState)) {            onload();        }    }}

四、后记

选择剥离Sea.js方法进行改造的原因:因为该js库使用人群很广泛,如果出问题,作者也会及时修复。所以,以此代码为蓝本进行改造契合公司的用户群,避免大面积出现问题。

相信看了本文案例你已经掌握了方法,更多精彩请关注创想鸟其它相关文章!

推荐阅读:

CSS实现一级导航栏

html+css中的四种隐藏方式

CSS3中nth-child与nth-of-type的区别以及使用技巧

以上就是动态加载css详解的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1609667.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月24日 00:54:16
下一篇 2025年12月24日 00:54:27

相关推荐

  • CSS3实现扇形动画菜单流程详解

    这次给大家带来CSS3实现扇形动画菜单流程详解,CSS3实现扇形动画菜单的注意事项有哪些,下面就是实战案例,一起来看一下。 原文章请点击这里 简化版完整实例 CSS3扇形动画菜单*{padding: 0; margin: 0;}body{background:#b1b1b1;margin:0px;p…

    好文分享 2025年12月24日
    000
  • css3+js实现3D行星运转

    这次给大家带来css3+js实现3D行星运转,css3+js实现3D行星运转的注意事项有哪些,下面就是实战案例,一起来看一下。 HTML部分 这里用前三个类为x、y、z的p来画的每一个星球的x、y、z轴,然后这些星球之间是可以嵌套的,就是像上面的代码一样,里面的星球是外面星球的卫星。 css部分 .…

    2025年12月24日
    000
  • HTML5+CSS3加载进度条与下载进度条实现

    这次给大家带来HTML5+CSS3加载进度条与下载进度条实现,HTML5+CSS3加载进度条与下载进度条实现的注意事项有哪些,下面就是实战案例,一起来看一下。 效果图: 1、html结构: 0%  简单分析下: p.loadBar代表整个进度条 p.loadBar p 设置了圆角表框 ,p.load…

    2025年12月24日
    000
  • CSS3制作粉红色登录界面

    这次给大家带来CSS3制作粉红色登录界面,CSS3制作粉红色登录界面的注意事项有哪些,下面就是实战案例,一起来看一下。 心血来潮,想学学 material design 的设计风格,就尝试完成了一个登录页面制作. 这是整体效果. 感觉还不错吧,结尾会附上代码 在编写的过程中,没有使用任何图片或者字体…

    2025年12月24日 好文分享
    000
  • css3视觉特效的实现

    这次给大家带来css3视觉特效的实现,实现css3视觉特效的注意事项有哪些,下面就是实战案例,一起来看一下。 一、单侧阴影 1、box-shadow属性的应用,格式:h-shadow v-shadow blur spread color inset属性取值介绍 h-sahdow:水平阴影的位置,允许…

    2025年12月24日 好文分享
    000
  • CSS实现书签图案的效果

    这次给大家带来css实现书签图案的效果,css实现书签图案的注意事项有哪些,下面就是实战案例,一起来看一下。 示例代码如下: border制作书签(图形) .p2:before { /*做一个书签效果*/ position: absolute; /*必须*/ top: 50px; left: 20p…

    好文分享 2025年12月24日
    000
  • CSS实现3d半透明立方体

    这次给大家带来CSS实现3d半透明立方体,CSS实现3d半透明立方体的注意事项有哪些,下面就是实战案例,一起来看一下。 效果图如下: 示例代码: new document //css部分html{font-size:62.5%;}img{width:300px;height:300px;} #sta…

    2025年12月24日
    000
  • css3实现动画自行车效果

    这次给大家带来css3实现动画自行车效果,css3实现动画自行车效果的注意事项有哪些,下面就是实战案例,一起来看一下。 首先来看看实现的效果图(静态): 实例源码: 自行车 * { margin: 0; padding: 0 } ol, ul { list-style: none/*去掉圆点或数字*…

    2025年12月24日
    000
  • CSS画出红色爱心

    这次给大家带来CSS画出红色爱心,CSS画出红色爱心的注意事项有哪些,下面就是实战案例,一起来看一下。 第一步: 先画一个正方形。如图: css画桃心 .heart-body { width: 500px; margin: 100px auto; position: relative; } .hea…

    2025年12月24日 好文分享
    000
  • css3的新属性box-sizing详解

    这次给大家带来css3的新属性box-sizing详解,css3属性box-sizing的注意事项有哪些,下面就是实战案例,一起来看一下。 在了解box-sizing之前,让我们来稍稍回顾一下盒子模型,模型分为:标准盒模型+IE盒模型。那这有什么区别呢?见图所示: 从上图可以看到标准 w3c 盒子模…

    2025年12月24日 好文分享
    000
  • CSS3实现鼠标悬停时边框旋转特效

    这次给大家带来CSS3实现鼠标悬停时边框旋转特效,CSS3实现鼠标悬停时边框旋转特效的注意事项有哪些,下面就是实战案例,一起来看一下。 纯CSS3实现的鼠标悬停时边框旋转的效果: 实现代码如下,代码中注释已经比较详细,就不再多说了: Document body { width: 40rem; hei…

    2025年12月24日
    000
  • css样式中的border-image使用详解

    这次给大家带来css样式中的border-image使用详解,使用css样式中border-image的注意事项有哪些,下面就是实战案例,一起来看一下。 border-image-source 属性设置边框的图片的路径[none | ] p { border: 20px solid #000; bo…

    好文分享 2025年12月24日
    000
  • CSS与HTML常见的使用误区

    这次给大家带来CSS与HTML常见的使用误区,CSS与HTML使用的注意事项有哪些,下面就是实战案例,一起来看一下。 误区一.多p症  Home About Concact 上述使用使用多余的p标签现状,就称为“多p症”,理应简化成下 Home About Concact 误区二.多类class症 …

    2025年12月24日
    000
  • html+css中的四种隐藏方式

    这次给大家带来html+css中的四种隐藏方式,html+css中隐藏方式的注意事项有哪些,下面就是实战案例,一起来看一下。 1.opacity:0只是把元素隐藏起来了 ,但是还是占有布局,所以还是对布局有影响 snda:opacity:0只是把元素隐藏起来了 ,但是还是占有布局,所以还是对布局有影…

    好文分享 2025年12月24日
    000
  • CSS实现一级导航栏

    这次给大家带来CSS实现一级导航栏,CSS实现一级导航栏的注意事项有哪些,下面就是实战案例,一起来看一下。 第一步:引入css样式表,新建一个id为nav的层,使用、、标签来制作完成效果。 首页 首页 首页 首页 首页 第二步设置CSS样式: 1.设置nav的属性 #nav{ width: 500p…

    2025年12月24日
    000
  • CSS有几种实现三栏布局的方法

    这次给大家带来CSS有几种实现三栏布局的方法,CSS实现三栏布局的注意事项有哪些,下面就是实战案例,一起来看一下。 前言 其实不管是三栏布局还是两栏布局都是我们在平时项目里经常使用的,也许你不知道什么事三栏布局什么是两栏布局但实际已经在用,或许你知道三栏布局的一种或两种方法,但实际操作中也只会依赖那…

    好文分享 2025年12月24日
    000
  • 用css实现浮雕效果

    这次给大家带来用css实现浮雕效果,用css实现浮雕效果的注意事项有哪些,下面就是实战案例,一起来看一下。 前言 最近在看百度地图看到了一个效果,感觉这个效果用在网页上应该蛮赞的,于是就学习了一下。 效果图如下: 浮雕效果需要用到伸缩盒的知识(flex) flex在chrome是完全支持的,要加-w…

    2025年12月24日
    000
  • CSS怎么处理浏览器的默认样式

    这次给大家带来CSS怎么处理浏览器的默认样式,CSS处理浏览器的默认样式注意事项有哪些,下面就是实战案例,一起来看一下。 发现 最近在调整网页的格式发现网页底部总是有一个10像素左右的空格。 通过用Chrome流浪器的审查元素发现有一个叫user agent stylesheet设置整个form的m…

    2025年12月24日
    000
  • css中px、em和rem使用详解

    相信每位前端工程师们都有这么一个体会,国内的设计师大都喜欢用px,而国外的网站大都喜欢用em和rem,那么三者有什么区别,又各自有什么优劣呢?下面这篇文章小编就来给大家详细介绍关于css中px、em和rem的区别,需要的朋友可以参考借鉴,下面来一起看看吧。 前言 em 和 rem 都是灵活可扩展的单…

    好文分享 2025年12月24日
    000
  • CSS3实现点击放大的动画实例

    这次给大家带来CSS3实现点击放大的动画实例,CSS3实现点击放大动画实例的注意事项有哪些,下面就是实战案例,一起来看一下。 前言 最近在工作中遇到一个需求,实现的效果是当点击商品图片右上的收藏按钮触发放大动画,后来通过查找相关的资料,发现利用css3:@keyframes animation即可实…

    2025年12月24日
    000

发表回复

登录后才能评论
关注微信