Day1:
学完了html、css和js的基础知识,从今天开始自己结合所学知识跟视频做一个博客的前端
第一步是创建出来index.html和index.css,这个就不详细描述了,直接上代码
html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript" src="js/base.js"></script>
<script type="text/javascript" src="js/index.js"></script>
<link rel="stylesheet" href="css/index.css">
</head>
<body>
<div id="header">
<div class="logo">
<img src="img/logo.gif" alt="">
</div>
<div class="personal">
个人中心
<ul>
<li><a href="#">设置</a></li>
<li><a href="#">换肤</a></li>
<li><a href="#">帮助</a></li>
<li><a href="#">退出</a></li>
</ul>
</div>
</div>
</body>
</html>
css:
body{
padding: 0px;
margin: 0px;
background: url(../img/header_bg.png) repeat-x;
font-size: 12px;
color:#333;
}
ul{
padding: 0px;
margin: 0px;
}
ul li{
list-style-type: none;
}
#header{
width:900px;
height: 30px;
margin: 0 auto;
}
#header .logo{
display: block;
float: left;
}
#header .personal{
background: red;
width: 70px;
height: 30px;
float: right;
line-height:30px;
background: url("../img/arrow.png") no-repeat 55px center;
cursor:pointer;
}
#header ul{
position: absolute;
top:30px;
left:1130px;
background: #FBF7E1;
width: 100px;
height: 110px;
border: 1px solid #999;
border-top: none;
padding:10px 0 0 0;
display: none;
}
#header ul li {
height:25px;
line-height: 25px;
text-indent: 30px;
letter-spacing: 10px;
}
#header ul li a{
text-decoration: none;
color: #333;
display: block;
background: url("../img/arrow3.gif") no-repeat 10px 45%;
}
#header ul li a:hover{
background: #fc0 url("../img/arrow4.gif") no-repeat 10px 45%;
}
以上是博客的顶部条,做出来的效果如下
现在要先封装一个js基础库base.js,用来存放需要多次调用的方法
基础库,创建Base函数,里面定义一个数组用来存放获取的节点,把定义数组放到Base函数里可以达到方法私有化的效果,以后多个节点多次调用互相不影响
//js基础库
function Base(_this) {
this.elements = []; //私有化
if(_this != undefined){
this.elements[0] = _this; //传过来的this有值,则把this本身放在节点数组的第一位,达到了获取节点的目的
}
}
接下来写各种获取节点的方法
1、获取指定id节点
//获取id节点
Base.prototype.getId = function (id) {
this.elements.push(document.getElementById(id));
return this;
};
用.prototype是因为这些方法都放在了基础库外,需要将这个方法放进基础库里,当获取到通过传来的id值获取到指定的节点,然后将节点放进elements数组里,最后返回this,我们就得到指定的节点了,之后的获取节点方法都是这个逻辑
2、获取元素节点
Base.prototype.getTagName = function (tag) {
var tags = document.getElementsByTagName(tag);
for(var i=0;i<tags.length;i++){
this.elements.push(document.getElementsByTagName(tag)[i]);
}
return this;
}
这里用到了一个for循环,因为这次我们是用过指定的元素名来获取节点的,比如我们传过来一个p元素,这时页面可能有许多p元素,那么我们需要加一个循环,tags存放的就是所有的p元素,然后从第一个p开始,每获取一个都将节点放到数组中
3、获取Class节点
Base.prototype.getClass = function (className,idName) {//传指定的节点过来
var node = null; //分区域来设置指定class节点
if(arguments.length == 2){ //将指定的区域传过来
node = document.getElementById(idName); //如果传来了指定区域,执行这里
}else{
node = document; //没有传来指定区域,执行这里
}
var all = node.getElementsByTagName('*'); //先获取所有的节点,这里已经确定了有没有指定区域
for(var i=0;i<all.length;i++){
if(all[i].className == className){ //循环,如果节点为传来的指定节点,将该节点存入数组
this.elements.push(all[i]);
}
}
return this; //返回该数组
}
这里又多了许多东西,首先传至,传来了两个值,第一个是class名,第二个是id名,是因为有些class在唯一的id里,如果想获取这些class,则要先指定这个id。这里先判断,传过来几个值,如果是两个,则node先通过idName获取置顶id,然后把node接到获取class节点的语句前,如果传来一个值,那么node就是document,然后接到获取class节点的语句前。
现在已经判断好是否加id了,然后通过判断结果,获取到了所有class节点,然后执行下面的函数,通过循环放到数组里
4、获取节点数组的某一个节点
//获取节点数组的某一个,(比如需要设置指定的一个class的属性)
Base.prototype.getElement = function (num) {
var element = this.elements[num]; //定义一个变量来存储当前位置
this.elements = []; //将存放位置的数组置空
this.elements[0] = element; //定义数组第一位为当前定位的位置
return this; //返回这个位置
}
有时候我们通过元素或者class等,获取了很多节点,但是我们不想设置他们全部的属性,这时候就用这个方法,锁定一个节点来设置,步骤看注释
获取节点的方法先写到这里,之后有需要的在扩展,接下来写对节点进行操作的方法、
1、设置css样式
Base.prototype.css = function (attr,value) {
for(var i = 0;i<this.elements.length;i++){
if(arguments.length == 1){ //参数长度为1,只传了attr过来,则获取该节点,用来定位
if(typeof window.getComputedStyle != 'undefined'){ //w3c 获得计算后的样式
return window.getComputedStyle(this.elements[i],null)[attr];
}
else if(typeof this.elements[i].currentStyle != 'undefined'){ //ie 获得计算后的样式
return this.elements[i].currentStyle[attr];
}
return this.elements[i].style[attr];
}
else{
this.elements[i].style[attr] = value; //正常的设置css样式
}
}
return this;
}
可以传过来两个值,属性名和属性值
for循环是因为你获取了许多节点,通过for循环对每一个节点设置
如果传过来一个,就是属性名,我们想查看某一个节点的某一个属性的具体的值,可以用这个方法,第二个if是用来兼容ie和w3c的
如果传过来两个,就是设置指定属性名的属性值,用this.elements[i].style[attr] = value;这个语句修改指定属性的值
2、添加css样式
//添加外部css样式
Base.prototype.addClass = function(className){ //传要添加的css过来
for(var i=0;i<this.elements.length;i++){
if(!this.elements[i].className.match(new RegExp('(\\s|^)'+className+'(\\s|$)'))){
//判断当前节点有没有这个css样式,没有的话执行以下代码
this.elements[i].className += '' + className; //把传来的css样式添加到当前节点,之前要加一个空格,与其他样式分开
}
}
return this;
}
这个方法是给一个节点添加一个class,先传过来你要添加的class名,然后判断这个class当前节点有没有,如果没有,则执行添加操作
3、删除css样式
//删除外部css样式
Base.prototype.removeClass = function(className){ //传要添加的css过来
for(var i=0;i<this.elements.length;i++){
if(this.elements[i].className.match(new RegExp('(\\s|^)'+className+'(\\s|$)'))){
//判断当前节点有这个css样式,有的话执行以下代码
//把指定的css样式换成空,达到删除css的目的
this.elements[i].className = this.elements[i].className.repeat(new RegExp('(\\s|^)'+className+'(\\s|$)') ,'');
}
}
return this;
}
和上面一个逻辑一样,这个是先判断传来的class名在指定的节点中有没有,有的话执行删除操作,其实就是把目标class名换成空字符
4、设置innerHTML
Base.prototype.html = function (str) {
for(var i = 0;i<this.elements.length;i++){
if(arguments.length == 0){ //若果参数为空,则获取该节点
return this.elements[i].innerHTML;
}
this.elements[i].innerHTML=str;
}
return this;
}
传过来你想在页面显示的文字,然后进入循环,先判断传过来的值是不是空,空的话就是获取这个节点,不是空,执行赋值操作,在指定位置编辑文字
5、设置点击事件
//设置点击事件
Base.prototype.click = function (fn) {
for(var i = 0;i<this.elements.length;i++){
this.elements[i].onclick = fn;
}
return this;
}
传过来一个函数,如果鼠标点击了指定节点,就执行这个函数
到这里最基础的东西已经封装好了
如果前台向调用,则需要一个调用函数
//前台调用
var $ = function(_this) { //实例化,之后调用的时候不用再new了,直接用$().调用就行了,如果不用这个方法,会导致获取多个节点的时候就重复了
//把this传过来
return new Base(_this);
};
//js
我们把Base放到$ 中,以后想用就直接$ ().后跟方法就行了,这里传来了一个_this,是因为前台调用的时候,如果已经指定了节点,然后下一行代码还是对该节点操作,我们还得从头打,这是我们把this放到$()中,把this穿了过去,这个this就是指定节点,然后一步一步传到了Base里,在Base中执行以下代码
if(_this != undefined){
this.elements[0] = _this; //传过来的this有值,则把this本身放在节点数组的第一位,达到了获取节点的目的
}
判断传过来的this有没有,如果有的话,把this本身放到数组第一位,就达到了定位节点的目的
到这里最基础的部分封装好了,接下来根据我们想要的效果,继续封装其他方法
1、设置显示
//设置显示
Base.prototype.show = function () {
for(var i = 0;i<this.elements.length;i++){
this.elements[i].style.display = 'block';
}
return this;
}
我们的页面中个人中心部分是要的效果是鼠标移入就显示,移出就不显示
所以要用到显示和隐藏方法,默认时隐藏的,触发显示后,将指定节点的display=block,就显示了
2、隐藏
//设置隐藏
Base.prototype.hide = function () {
for(var i = 0;i<this.elements.length;i++){
this.elements[i].style.display = 'none';
}
return this;
}
display=none就隐藏了
显示和隐藏写好了,这里我们是通过鼠标移入移出来触发显示和隐藏,所以我们添加一个判断鼠标移入移出方法
//鼠标移入移出方法
Base.prototype.hover = function (over,out) {
for(var i = 0;i<this.elements.length;i++){
this.elements[i].onmouseover = over;
this.elements[i].onmouseout = out;
}
return this;
}
传过来两个值,两个都是函数,函数中放触发时需要的操作,如果鼠标移入就执行第一个函数,如果鼠标移出就执行第二个函数。
前台调用代码:
$().getClass('personal').hover(function () {
//用$(this),是因为出现来代码重复,为了简化,直接将$().getClass('personal')用$(this)来代替,这时候this已经有值了,过去就判断不是undefined,那么会执行base.js里的对应的代码
$(this).css('background','url("img/arrow2.png") no-repeat 55px center');
$().getTagName('ul').show();
},function () {
$(this).css('background','url("img/arrow.png") no-repeat 55px center');
$().getTagName('ul').hide();
});
到这里我们的顶部样式的个人中心就做好了,鼠标移入显示下拉菜单,鼠标移出则隐藏