html:
<head>
<link rel="stylesheet" href="https://codepen.io/levonlin/pen/XXLPrX.css" id="theme_link">
</head>
<div class="header">
<ul id="skin" class="clear">
<li id="red"></li>
<li id="green" class="active"></li>
<li id="black"></li>
</ul>
<ul id="nav" class="clear">
<li><a href="javascript:void(0);">新闻</li>
<li><a href="javascript:void(0);">娱乐</li>
<li><a href="javascript:void(0);">体育</li>
<li><a href="javascript:void(0);">电影</li>
<li><a href="javascript:void(0);">音乐</li>
<li><a href="javascript:void(0);">旅游</li>
</ul>
</div>
css:
*{
padding:0;
margin:0;
}
ul{
list-style:none;
}
.clear:after{
clear:both;
content:'';
display:block;
visibility:hidden;
height:0;
}
.header{
width:499px;
margin:0 auto;
}
#skin{
margin:10px 0;
}
#skin li{
float:left;
width: 8px;
height: 8px;
margin-right: 10px;
}
#red{
border:solid 4px #F00;
background:#F00;
}
#green{
border:solid 4px #080;
background:#080;
}
#black{
border:solid 4px #000;
background:#000;
}
#skin li.active{ //li与.active之间不要有空格
background:#fff;
}
#skin li:hover {
cursor: pointer;
}
#nav li{
float:left;
width:82px;
line-height:25px;
text-align:center;
border-right:solid 1px #fff;
}
#nav li a{
color:#fff;
text-decoration:none;
}
#nav li a:hover{
text-decoration:underline;
}
js:
var skins = document.getElementById('skin');
var themesURL = {
RED: 'https://codepen.io/levonlin/pen/pgXOjz.css',
GREEN: 'https://codepen.io/levonlin/pen/XXLPrX.css',
BLACK: 'https://codepen.io/levonlin/pen/ZQdMGG.css'
};
//事件委托函数
function delegateEvent(delegateElement, targetTag, eventName, handler) {
delegateElement.addEventListener(eventName, function(event) {
var target = event.target;
if (targetTag.toLowerCase() === target.nodeName.toLowerCase()) {
return handler(event);
}
}, false);
}
//hasClass
function hasClass(element, className) {
return (new RegExp('(\\s|^)' + className + '(\\s|$)')).test(element.className);
}
//addClass
function addClass(element, newClassName) {
if (!hasClass(element, newClassName)) {
element.className = element.className ? (element.className + " " + newClassName) : newClassName;
}
}
//removeClass
function removeClass(element, oldClassName) {
if (hasClass(element, oldClassName)) {
element.className = element.className.replace(new RegExp('(\\s|^)' + oldClassName + '(\\s|$)'), " ").trim();
}
}
//转换背景主题函数
function changeThemeTo(theme){
var link = document.getElementById('theme_link');
switch(theme){
case 'red':
link.href=themesURL.RED;
break;
case'green':
link.href=themesURL.GREEN;
break;
case'black':
link.href=themesURL.BLACK;
break;
}
}
//转换样式函数(包括了转换背景主题函数)
function changeStyle(event){
var target = event.target; //这里的event是click。我们点击了li,li就是target
var theme = target.id;//这是li的id
var siblings = target.parentNode.children;//li的父节点ul的孩子集合
for(var i = 0,len=siblings.length;i<len;i++){
removeClass(siblings[i],'active');//当我们为li添加样式时,先移除最开始的样式
}
addClass(target,'active');//把这个样式添加到我们点击的目标li上
changeThemeTo(theme);//根据li的id转换主题
}
delegateEvent(skins, 'li', 'click', changeStyle);
思路:
如果采用for循环来一个个给li绑定事件函数就太费了,这里采用了事件委托机制。所谓事件委托就是利用了事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。我们可以给列表ul添加一个事件,由于所有表项都是这个元素的子节点,而且他们的事件会冒泡,不必给每个li绑定事件。
关于事件委托机制,这位博主说得很好:
js中的事件委托或是事件代理详解 - 凌云之翼 - 博客园 https://www.cnblogs.com/liugang-vip/p/5616484.html