惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
SegmentFault 最新的问题
博客园 - 三生石上(FineUI控件)
WordPress大学
WordPress大学
博客园 - 【当耐特】
月光博客
月光博客
Vercel News
Vercel News
D
Docker
I
InfoQ
Apple Machine Learning Research
Apple Machine Learning Research
博客园 - 叶小钗
MongoDB | Blog
MongoDB | Blog
GbyAI
GbyAI
有赞技术团队
有赞技术团队
雷峰网
雷峰网
博客园 - 聂微东
小众软件
小众软件
Y
Y Combinator Blog
腾讯CDC
L
LangChain Blog
The GitHub Blog
The GitHub Blog
宝玉的分享
宝玉的分享
Stack Overflow Blog
Stack Overflow Blog
大猫的无限游戏
大猫的无限游戏
T
The Blog of Author Tim Ferriss

张鑫旭-鑫空间-鑫生活

1分钟速度了解text-align match-parent声明 « 张鑫旭-鑫空间-鑫生活 光标的形状也能设置了,就是CSS caret-shape属性 « 张鑫旭-鑫空间-鑫生活 pretext与文字四面环绕效果的实现 « 张鑫旭-鑫空间-鑫生活 JSON.rawJSON方法的作用是什么? « 张鑫旭-鑫空间-鑫生活 如何使用CSS判断鼠标从哪个方向进入元素? « 张鑫旭-鑫空间-鑫生活 借助mediabunny纯JS实现视频水印、剪裁、合成等功能 « 张鑫旭-鑫空间-鑫生活 务必谨慎使用JS WeakRef弱引用 « 张鑫旭-鑫空间-鑫生活 CSS六边形头像的实现与蜂巢布局 « 张鑫旭-鑫空间-鑫生活 CSS corner-shape与背景底纹技术 « 张鑫旭-鑫空间-鑫生活 浅学WebTransport API:下一代Web双向通信技术 « 张鑫旭-鑫空间-鑫生活 HTML dialog元素新支持了closedBy属性 « 张鑫旭-鑫空间-鑫生活 HTML interestfor属性与悬停popover交互效果 « 张鑫旭-鑫空间-鑫生活 CSS3模拟window7炫酷界面效果展示 « 张鑫旭-鑫空间-鑫生活 图片旋转+剪裁js插件(兼容各浏览器) « 张鑫旭-鑫空间-鑫生活 纯js无图片无外链CSS图片幻灯片播放插件 « 张鑫旭-鑫空间-鑫生活 CSS border三角、圆角图形生成技术简介 « 张鑫旭-鑫空间-鑫生活 CSS “渐进增强”在web制作中常见应用举例 « 张鑫旭-鑫空间-鑫生活 让IE6/IE7/IE8浏览器支持CSS3属性 « 张鑫旭-鑫空间-鑫生活 jQuery – 高亮动态显示页面HTML代码插件 « 张鑫旭-鑫空间-鑫生活 翻译 – 逐渐消失的Flash网站 « 张鑫旭-鑫空间-鑫生活 CSS reset的重新审视 – 避免样式重置 « 张鑫旭-鑫空间-鑫生活 新浪微博插入话题后部分文字选中的js实现 « 张鑫旭-鑫空间-鑫生活 JavaScript实现http地址自动检测并添加URL链接 « 张鑫旭-鑫空间-鑫生活 CSS实现兼容性的渐变背景(gradient)效果 « 张鑫旭-鑫空间-鑫生活 CSS content内容生成技术以及应用 « 张鑫旭-鑫空间-鑫生活 CSS gradient渐变之webkit核心浏览器下的使用 « 张鑫旭-鑫空间-鑫生活 CSS渐变之CSS3 gradient在Firefox3.6下的使用 « 张鑫旭-鑫空间-鑫生活 区分IE8/IE7/IE6及其他浏览器-CSS “\9″hack « 张鑫旭-鑫空间-鑫生活 CSS实现跨浏览器兼容性的盒阴影效果 « 张鑫旭-鑫空间-鑫生活 CSS3&HTML5各浏览器支持情况一览表 « 张鑫旭-鑫空间-鑫生活
link rel=alternate网站换肤功能最佳实现 « 张鑫旭-鑫空间-...
张鑫旭,zhangxinxu · 2019-02-25 · via 张鑫旭-鑫空间-鑫生活

by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=8512
本文可全文转载,个人网站无需授权,只要保留原作者、出处以及文中链接即可,任何网站均可摘要聚合,商用请联系授权。

换脸换肤占位图

一、大多数开发人员的实现

大多数前端开发人员实现网站皮肤更换功能大致下面两种方法:

  1. 一个全局class控制样式切换;
  2. 改变皮肤link元素的href地址。例如:
    <link id="skinLink" href="skin-default.css" rel="stylesheet" type="text/css">

    换皮肤的时候JS改变href属性值:

    skinLink.href = 'skin-red.css';

    例如我10年前模拟腾讯网首页的换肤功能做的demo页面就是这么实现的。

都不完美。全局class控制样式提高了样式优先级,如果换肤样式很多,代码会非常啰嗦,不利于维护;使用JS改变href属性会带来加载延迟,样式切换不流畅,体验不佳。

实际上,浏览器有原生特性,非常适合实现网站换肤功能。

二、原生HTML特性下的网站换肤

此方法借助HTML rel属性的alternate属性值实现。示意HTML如下:

<link href="reset.css" rel="stylesheet" type="text/css">
                
<link href="default.css" rel="stylesheet" type="text/css" title="默认">
<link href="red.css" rel="alternate stylesheet" type="text/css" title="红色">
<link href="green.css" rel="alternate stylesheet" type="text/css" title="绿色">

上面4个<link>元素,共出现了3中不同性质的CSS样式文件加载:

  • 没有title属性,rel属性值仅仅是stylesheet的<link>无论如何都会加载并渲染,如reset.css;
  • 有title属性,rel属性值仅仅是stylesheet的<link>作为默认样式CSS文件加载并渲染,如default.css;
  • 有title属性,rel属性值同时包含alternate stylesheet的<link>作为备选样式CSS文件加载,默认不渲染,如red.css和green.css;

这里有个非常有趣的特性,那就是rel="stylesheet"<link>如果有title属性并有值,性质上就变成了一个可以控制其渲染或者不渲染的特殊元素了。

如何控制呢?

一种说是浏览器自己会有样式切换菜单,查看→页面,选择title属性值对应的样式。我猜这是10年前的说法了吧,现在浏览器根本没有这些菜单选项,至少我找了好久,各个浏览器都找了个遍没找到。

另外一种就是使用JS进行控制了,使用JavaScript代码修改<link>元素DOM对象的disabled值为false,可以让默认不渲染的CSS开始渲染。注意,必须是DOM元素对象的disabled属性,而不是HTML元素的disabled属性,<link>元素是没有disabled属性的。

例如:

// 渲染red.css这个皮肤
document.querySelector('link[href="red.css"]').disabled = false;

因此,要实现换肤功能,只要在页面上方几个换肤按钮,点击的时候改变对应<link>元素DOM对象的disabled值就可以了。

眼见为实,我专门做了demo页面,您可以狠狠地点击这里:link rel alternate实现网站换肤功能demo

结果如下GIF截图所示(截自IE浏览器):

换肤效果示意

demo页面是使用单选框模拟实现的,HTML和JS代码如下:

<input id="default" type="radio" name="skin" value="default.css" checked>
<input id="red" type="radio" name="skin" value="red.css">
<input id="green" type="radio" name="skin" value="green.css">
var eleLinks = document.querySelectorAll('link[title]');
var eleRadios = document.querySelectorAll('[type="radio"]');
[].slice.call(eleRadios).forEach(function (radio) {
    radio.addEventListener('click', function () {
        var value = this.value;
        [].slice.call(eleLinks).forEach(function (link) {
            link.disabled = true;
            if (link.getAttribute('href') == value) {
                // 该样式CSS文件生效
                link.disabled = false;
            }
        });
    });
});

三、link rel=alternate方法实现优点

3大优点:

  1. 兼容性非常好。IE9+(IE8我没测,理论也支持),Chrome和Firefox均支持这种更原生的换肤效果实现。
  2. 语义非常好。用户,开发者,尤其搜索引擎或者其他辅助阅读设备能够准确识别网站还有其他替换CSS样式。(alternate的语义就是可替换的)
  3. 交互体验更好。rel=alternate方法实现的换肤功能在网站样式变换的时候是瞬间切换,完全无感知。因为浏览器已经把换肤的CSS文件预加载好了,比JS改变href地址的体验要更好。配合http2.0,几乎可以说是完美无瑕的解决方案了。

为什么之前没有人提过这个方法?

此方法我也是最近在学习rel属性值的时候知道的,看到MDN上关于Alternative_style_sheets文档学到的,之前并不知晓还有这么给力的实现。

Firefox4就开始支持这一特性,说明此方法很久远了,我搜索了下,还是有少数前辈知道并使用这种方法换肤的,但是,至少对于新人前端(如果按照我在例会上的统计)几乎无人知晓。

什么原因造成这种现象呢?

首先,换肤是小众需求;
其次,有符合常规认知的替换方案,最终效果也能接受;
然后,都在学习高大上的东西,什么HTML基础知识根本无人问津;
最后,缺少有影响力的的入口进行科普。

酒香也怕巷子深,好的技术实现也要多多曝光才能让更多人知道,提高整个行业的水平。所以如果你觉得此方法确实不错,可以转发分享让更多人知道。

最后,感谢你的关注和阅读!

本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:https://www.zhangxinxu.com/wordpress/?p=8512

(本篇完)