网页换肤的基本原理:
使用 JS 切换对应的 CSS 样式表。例如导航网站 Hao123 的右上方就有网页换肤功能。除了切换 CSS 样式表文件之外,通常的网页换肤还需要通过 Cookie或者H5的session技术 来记录用户之前更换过的皮肤,这样下次用户访问的时候,就可以自动使用上次用户配置的选项。
工作流程就出来了:访问网页——JS 读取 Cookie || session ——如果没有,使用默认皮肤——如果有,使用指定皮肤;用户点击换肤选项——JS 控制替换对应的 CSS 样式表——将皮肤选项写进 Cookie | | session 保存。
逻辑思维图:
全局:global.css
全局样式为全站公用,为页面样式基础,页面中必须包含。
结构:layout.css
页面结构类型复杂,并且公用类型较多时使用。多用在首页级页面和产品类页面中。
私有:style.css
独立页面所使用的样式文件,页面中必须包含。
模块 module.css
产品类页面应用,将可复用类模块进行剥离后,可与其它样式配合使用。
主题 themes.css
实现换肤功能时应用。
用于存放测试接口数据,用于前后台对接之前测试功能。通长用json格式文件模拟
用于存放框架
JS文件以功能切割js文件代码
App.js:存放页面MVC框架
Controller:存放功能模块的控制器
Directive:存放操作dom的指令
Filter:过滤器操作
Service:公用服务类
Less:文件目录用于存放控制全局的基础样式,如需变更颜色字体等将会在less中修改一次性装换为CSS.
用于存放静态资源:图片,背景等。
如果是单页面应用将会存放:文档片段代码。
非单页面应用:将会存放分页html.
不同的项目可能定制不同的主题皮肤,虽有不同但又共通点,要实现换肤功能在不同项目之间反复使用,需要前期规划号CSS方向。
相同点:
1、所有项目项目之间引用相同的模板初始化化文件。统一所有浏览器的基础样式
2、定义相同的class类名,即使不同项目,样式不同,但其中的web组件相同,通过定义web组件名从而通过名称控制CSS样式。达到样式的复用。
如:手风琴组件 class名称统一为accordion 公共CSS文件中定义accordion的基础样式,在各自的项目中也可以操作accordion CSS从而定制不同颜色,背景。
不同点:
1、各个项目之间的样式风格不统一,每个项目都有自己不同的themes css文件,根据客户的要求进行样式调整。
2、Web项目布局不统一,如手风琴导航与面包屑导航,对不同的项目应当合理引入组件CSS,而不能为了省事加载所有公共类样式,这样只会增加不必要的请求书与客户端内存的压力。
多工程目录
commonProject为公共基础目录
里面的css文件下
Common放入的是全局静态的CSS如页面初始化
webAppSubgroup文件夹下放入是web基础组件,如accordion与slide等基础组件
ProjiectA与ProjectB结构相同 目录功能参考单个项目
项目与项目之间的引入可以通过require.js或者依赖javaWeb基础类库实现,
达到按需载入的目的。
HTML代码如下:
<p>前端开发是我的一个职业目标,我喜欢前端开发,热爱前端开发,喜欢制作各种各样的页面效果p><inputtype="button" data-value="default" class="targetElem" value="default"/><inputtype="button" data-value="green" class="targetElem" value="green"/><inputtype="button" data-value="red" class="targetElem" value="red"/><inputtype="button" data-value="orange" class="targetElem" value="orange"/>
CSS代码
default.css 代码如下:
@charset "utf-8";/* CSS Document */
*{padding:0;margin:0;}
h2{color:#00C;}
p{color:#006;}
orange.css代码如下:
@charset "utf-8";/* CSS Document */
*{padding:0;margin:0;}
h2{color:#C60;}
p{color:#C33;}
green.css代码如下:
@charset "utf-8";/* CSS Document */
*{padding:0;margin:0;}
h2{color:#060;}
p{color:#060;}
red.css代码如下:
@charset "utf-8";/* CSS Document */
*{padding:0;margin:0;}
h2{color:#F00;}
p{color:#F00;}
JS代码如下:
/**
* JS实现换肤功能
*/// Google Chrome只支持在线网站的cookie的读写操作,对本地html的cookie操作是禁止的。
// name1=value1;name2=value2;name3=value3;name4=value4
function Skin(options) {
this.config = {
targetElem : '.targetElem',
link : '#link'
};
this.cache = {
defaultList : ['default','green','red','orange']
};
this.init(options);
}
Skin.prototype = {
constructor: Skin,
init: function(options) {
this.config = $.extend(this.config,options || {});
var self =this,
_config = self.config;
$(_config.targetElem).each(function(index,item) {
$(item).unbind('click');
$(item).bind('click',function(){
var attr = $(this).attr('data-value');
self._doSthing(attr);
});
});
//判断是否是谷歌游览器 谷歌游览器因为不支持cookie在本地上存储 所以引入了HTML5
if(window.navigator.userAgent.indexOf("Chrome") !== -1) {
var tempCookeie = self._loadStorage("skinName"),
t;
if(tempCookeie != "null") {
t = tempCookeie;
}else {
t = 'default';
}
self._setSkin(t);
}else {
var tempCookeie = self._getCookie("skinName");
self._setSkin(tempCookeie);
}
},
/*
* 进行判断 来设置css样式
*/
_doSthing: function(attr) {
var self =this,
_config = self.config,
_cache = self.cache;
if(window.navigator.userAgent.indexOf("Chrome") !== -1) {
self._doStorage(attr);
var istrue = localStorage.getItem(attr);
self._setSkin(attr);
}else {
var istrue = self._getCookie(attr);
if(istrue) {
for(var i = 0; i < _cache.defaultList.length; i++) {
if(istrue == _cache.defaultList[i]) {
self._setSkin(_cache.defaultList[i]);
}
}
}
}
},
/*
* 改变样式
*/
_setSkin: function(skinValue){
var self =this,
_config = self.config;
if(skinValue) {
$(_config.link).attr('href',"style/"+skinValue+".css");
}
if(window.navigator.userAgent.indexOf("Chrome") !== -1) {
self._saveStorage(skinValue);
}else {
self._setCookie("skinName",skinValue,7);
}
},
/*
* 重新
*/
_doStorage: function(attr) {
var self =this;
self._saveStorage(attr);
},
/*
* html5获取本地存储
*/
_loadStorage: function(attr) {
var str = localStorage.getItem(attr);
return str;
},
/*
* HTML5本地存储
*/
_saveStorage:function(skinValue) {
var self =this;
localStorage.setItem("skinName",skinValue);
},
/*
* getCookie
*/
_getCookie: function(name) {
var self =this,
_config = self.config;
var arr = document.cookie.split("; ");
for(var i = 0; i < arr.length; i+=1) {
var prefix = arr[i].split('=');
if(prefix[0] == name) {
return prefix[1];
}
}
return name;
},
/*
* _setCookie
*/
_setCookie: function(name,value,days) {
var self =this;
if (days){
var date =new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
}else {
var expires = "";
}
document.cookie = name+"="+value+expires+"; path=/";
},
/*
* removeCookie
*/
_removeCookie: function(name) {
var self =this;
//调用_setCookie()函数,设置为1天过期,计算机自动删除过期cookie
self._setCookie(name,1,1);
}
};
// 初始化
$(function(){
new Skin({});
});
只修改要定制的主题样式属性,id ,class,标签 名称要与global.css保持一致.
Ex:
/*bad*/
//global文件下的CSS
.a{
display:inline-bloak;//global.css
text-align:center
}
//themes文件下的css
.b{
background:#ddd;//themes.css
}
错误原因:class名称不一致 更换样式不代表更换页面标签 跟换主题时页面标签中的class是a,所有themes.css及使加载也不会重新渲染DOM
/*good*/
//global文件下的CSS
.a{
display:inline-bloak;//global.css
text-align:center;
}
//themes文件下的css
.a{
background:#ddd;//themes.css
}
如果是本地启动的项目,因为没有放到任何服务器下面所以我直接放在桌面上 点击页面打开,突然发现 "谷歌游览器不支持cookie在本地存储"。所以针对这个问题在谷歌游览器下没有用cookie存储,而是用了上面介绍的HTML5中的localStorage作本地存储功能。通过setItem设置key名 然后通过getItem获取key名 进而获取值。
cookie sessionStorage及localStorage共同点及区别
共同点:
都是在浏览器端存储的数据,且同源的。
区别:
1. 存储大小不一样: cookie存储数据有限制 做多只能是4KB而sessionStorage和localStorage可以存储5MB甚至更多数据。
2. cookie 数据始终在同源的http请求中携带,即cookie在浏览器和服务器间来回传递。而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。
3. 数据有效期不同: sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持; localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。
4. 作用域不同, sessionStorage不在 不同的浏览器窗口中共享,即使是同一个页面; localStorage在所有同源窗口中都是共享的;cookie也是在 所有同源窗口中都是共享的。