web前端之javascript

Posted Atmoyxic

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了web前端之javascript相关的知识,希望对你有一定的参考价值。

开始之前

  1. 拖了这么久才更新hhh,先是拿几天准备期中考试,然后是几天的颓废大学生活,本来已经写完了基本的教程,但是觉得最好在每篇后面加一个实际操作例子,又鼓捣了几天。

  2. 刚开始本来想把前端的学习路线通拉一遍,现在觉得没必要,因为我不准备走前端,可能很大一部分人也不走前端,如果全部拉完的话有点儿浪费时间,所以我就按搭建一个完整网站的路线来更新吧。

  3. 编程知识很多,真没有必要第一次全部学完,实际操作中需要什么就去学什么,只要你知道怎么使用就好。

  4. web端之后决定开始ai的更新,因为接下来会花大量时间去学习ai方向的知识,所以决定先跳过安卓端。

  5. 专业的游戏开发不准备涉及,算法会不定时更新,先把专业课学到的算法整理一遍,因为到了大二发现这个遗忘率好像挺高的。




javascript

  • javascript和java在语言上没有直接关系,就是名字取得相近。

  • javascript实现网页的动作,要知道操作谁,怎么操作。

  • javascript是真正意义上的编程语言,跟c语言一样需要声明变量,有函数等等,html和css算是另一种意义上的语言。

  • 建议大家先去学一学Developer Tools,它是浏览器自带的调试工具,最好用chrome的,它能够让你直观的看到很多信息,比如某个标签的盒子模型,某个js函数是否出错,包括之后部署到服务器上会遇到的一系列问题,学会之后还能直接看到别人网站的代码,学会之后跟着一起操作效果会更好




插入形式

文件

用法:<script type="text/javascript">

           ……

           </script>


外部文件

将javascript代码全部写到.js文件中,再在原文件中进行调用

用法:<script ></script>


那具体插入到哪里呢?

你可能检查了很久,觉得自己的代码没有问题,但是结果不是预期

那可能就是javascript插入的位置不对

简单理解就是浏览器是按照你写的顺序编译代码

很多时候你的js代码会用到一个标签,但你的标签还没有加载进来

浏览器没有选择保留它,等标签加载进来才运行

而是直接跳过了

css也会使用标签,但却没有这种困扰

一般来说我会把css放到head里,js放到body的最后




假设你现在只有c语言的基础

c语言是面向过程编程,而javascript是面向对象编程

你需要先去了解区别这两个概念

知道面向对象编程中的类、对象、实例分别是什么,怎么调用

才能看懂接下来有些东西

在了解的过程中顺便学点c++和java的基础知识也是可以的

和c语言一样的东西我就不讲了,比如if else语句




DOM

DOM全称文档对象模型(Document Object Model)

我们先来回忆一下数据结构学到的树结构

有多个节点,这些结点可能有根节点,可能有子节点(节点结点都行)

如果把标签的嵌套关系用树结构的父子方式来表达

那么将会是这个样子

这些通通称为元素节点

元素节点又有自己的子节点,分别是文本节点和属性节点

文本节点就是标签内带的东西

属性节点就是css改变的东西

这么做有什么用?

就像一个仓库一样,把所有物品有结构的摆放好,并提供找到物品的接口




声明

变量

用法:var 变量名=赋值;

说明:和c不同的是,不需要声明int,float之类的表示变量的数据类型,只需要用var。变量得赋值才能调用,变量的作用域真的很重要,一开始注意这个问题,会让你的代码减少很多bug


数组

用法:var 数组名=new Array();

说明:希望你刚才去了解过面向对象编程了,你才明白这里为什么这么写,有个程序员相关的笑话就是没有对象怎么了,new一个就好了嘛。数组的长度可以先不声明,直接像c语言那样添加数组成员就能扩充数组,声明的时候也可以顺便声明数组成员,像这样,var a=new Array(1,2);通过数组名.length可以得到数组长度,这同样也是面向对象编程里的用法,二维数组,多维数组就自己搜索尝试一下吧


函数

用法:function 函数名(参数,可以为空){

           ……

           }

说明:有时候我们需要函数给我们返回一个结果,c语言中需要声明返回结果的类型,javascript不需要,可以直接return,javascript也有很多自带的函数,有需求的可以自行谷歌




操作

document.getElementById

用法:var 变量=document.getElementById("标签id名");

例:<div id="nav"></div>

       var a=document.getElementById("nav")

说明:有时候你想具体操作某个标签的某个变量,可能你会想到学c语言时讲的函数中的传参,没错,js专门定义了获取标签对象的方法,上面的方法就是通过id名来获取标签对象,你也可以使用class名或者name名来传递,但方法名和用法不相同,我个人倾向用这种,感兴趣的可以自己学习一下


onclick、onmouseup、onmousedown

用法:<标签 onclick="调用函数"></标签>

例:<input type="button" value="submit" onclick="add()">

说明:onclick表示鼠标单击时触发的事件,onmouseup表示鼠标抬起时触发的事件,onmousedown表示鼠标按下时触发的事件,相当于后两个是把第一个给拆开了,例子是说点击这个button就会触发add()函数,注意有些标签是没有办法使用这些事件的,有时候方法失效,可能是你取的函数名与js自带的冲突了,当然还有很多其他的事件,比如跟键盘关联的事件,可以自行搜索




响应

输出

用法:document.write(输出内容);

例:var str="abc";

       document.write(str+"def");

说明:输出变量直接写,非变量写在""里,多项内容一起输出用加号拼接,这也是典型面向对象的用法,所以最终输出结果是abcdef,实际操作中你可能会发现当你使用了document.write之后整个页面被重写了,这跟浏览器的解析方式有关,可以用下面讲的修改属性innerHTML来避免这种情况


修改节点属性

用法:获取节点变量.属性=值;

例:<div id="nav">abcdef</div>

       var a=document.getElementById("nav");

       a.innerHTML="123456";

       a.style.color="red";

说明:这里是说修改属性innerHTML将文本从abcdef改成123456,注意一定是修改,不是重新输出一个123456,跟document.write区分开,跟样式有关的修改都要通过style,有一个很容易出错的修改就是事件的修改,比如你想把a的onclick关联函数改成change(),就用a.onclick=change;后面不用加()


修改节点

1.创建新的节点

用法:var 节点变量=document.createElement("节点类型") ;

           var 文本变量=document.createTextNode("文本内容");

           节点变量.appendChild(文本变量);

例:var newNode=document.createElement("div");

       var newText=document.createTextNode("hello");

       newNode.appendChild(newText);

       document.body.appendChild(newNode);

说明:第一步是创建元素节点,但创建元素节点并不会自动生成它的两个子节点,所以第二步是创建文本节点,否则没办法修改innerHTML之类的属性,属性节点则不创建也能修改,appendChild函数的意思是使括号里的节点变成前面节点的子节点,并且放在最后一位,document.body是指body节点,不用像前面一样申请一个变量保存这个节点,可以直接用,所以那句代码的意思是把newNode节点插入到body节点的最后


2.插入节点

用法:节点变量1.insertBefore(新的节点变量,节点变量2(可以不填));

例:<div id="1"><span>a</span><span id="2">b</span></div>

       var fNode=document.getElementById("1");

       var sNode=document.getElementById("2");

       //创建一个新的节点newNode

       fNode.insertBefore(newNode,sNode);

说明:appendChild也属于插入节点,但是因为创建了节点必须放位置,所以在第一点里先讲了,insertBefore和appendChild一样,括号里的节点都是前面节点的子节点,也就是说sNode和newNode都是fNode的子节点,但是要把newNode放在sNode的前面,第二个参数可以不填,不填时表示随机放,而不是放在子节点的第一个,这个要注意,span和div都是没有具体含义用来分区的标签,但是div是块级元素,span是内联元素


3.替换节点

用法:节点变量1.replaceChild(新的节点变量,节点变量2);

例:<div id="1"><span>a</span><span id="2">b</span></div>

       var fNode=document.getElementById("1");

       var sNode=document.getElementById("2");

       //创建一个新的节点newNode

       fNode.newCode(newNode,sNode);

说明:replaceChild和insertBefore的用法基本一样,但是第二个参数必填,必须指明替换哪一个节点


4.删除节点

用法:节点变量1.removeChild(节点变量2);

例:<div id="1"><span>a</span><span id="2">b</span></div>

       var fNode=document.getElementById("1");

       var sNode=document.getElementById("2");

       fNode.removeChild(sNode);

说明:很好理解,将fNode的子节点sNode删除


5.复制节点

用法:新的节点变量=被复制的节点变量.cloneNode(参数,可以不填);

例://已有节点oldNode

       var newNode=oldNode.cloneNode();

说明:复制节点不会复制事件,参数有true和false两种,不填就是默认false,true表示深度复制,即除了复制该节点,还会复制它的子节点


弹出对话框

用法:对话类型(内容);

例:alert("attention!");

       var a=confirm("are you sure you wanna exit?");

       var a=prompt("what's your name?");

说明:对话框就是当你点击关闭某个网页弹出来询问你是否确定要退出的那个东西,主要分三种,第一种alert是单纯的弹出,起提示作用,直接关闭就行,第二种confirm是按钮回复,最常见,可能是确定或取消,是或否,是根据不同的浏览器来的,没办法修改,用户不回复就没办法继续操作,回复会返回布尔值,就可以根据不同的回复调用不同的操作,第三种prompt是文本回复,会给出一个文本框让你提交,回复的值就是用户输入的文本框内容


开启、结束计时

用法:setTimeout("执行代码",时间);

           setInterval("执行代码",时间);

例://获取标签变量a

       var i=0;

       var r1=setTimeout("a.innerHTML='i++'",1000);

       var r2=setInterval("a.innerHTML='i++'",1000);

       clearTimeout(r1);

       clearInterval(r2);

说明:setTimeout表示间隔一段指定的时间再执行代码一次,setInterval表示每隔一段指定的事件就执行一次代码,时间的单位是ms,1000就是1s,这个是js的重难点函数,使用这两个函数的代码经常会出很多bug,比如有人会忘了结束计时,可能导致网页崩溃,这个是比较好debug的,还有一种是因为不清楚这两个函数的运行机制,我这里简单讲解,详细了解可以去查更专业的文档,首先说明js是单线程,就是说它是一个任务一个任务的处理的,前面的任务没有完成不能开始后面的任务,但setTimeout的间隔不是说这段时间完全停止运行,到时间了再调用这段代码,而是将这段代码放在另一个队列里,继续处理后面不需要等待的任务,到时间了如果没有其他任务在执行就重新调用,有其他任务在执行就等它执行完再重新调用,setInterval同理,但是setInterval无论这一次的代码有没有执行完,规定时间到了下一次的代码都会去尝试执行,除非计时器被清理了,而且如果想要动态修改时间间隔,必须得清理计时器再重新启动,因为setInterval一旦设置好,每次的代码都会提前准备好,所以时间还是第一次设置的时间




做一个打地鼠的小游戏

后台回复”打地鼠“即可获得完整代码+资源

我进行了一些改变,比如用朋友的照片当地鼠

不想全部重写的可以看懂了直接修改图片恶搞朋友啊hhh

1.所有页面静态部署

打地鼠游戏就是有一个锤子,地鼠随机出现,又回去,如果打中了就得分,锤子和地鼠都会有动态效果

因为var me=直男();me.审美=null;加上不会photoshop,所以我就直接用别人的css啦,但还是建议大家有机会去学一学ps,不然会像我一样花很久找资源

我们需要的组件有这些

  • 按钮playButton:游戏开始结束都可以用它

  • 准备倒计时数字readyCountDown和变暗背景readyBackground:之前不显示,提醒准备开始的时候整个页面变暗,中间321倒计时

  • 游戏倒计时gameCountDown:60s为一轮

  • 游戏区域playZone:地鼠出现的九宫格区域

  • 得分板score:打中一次一分

需要的资源有锤子不敲和敲下的图,地鼠没被打和被打的图,界面背景图

有些css我也不会,但我觉得我会用会学就ok

html:

//又出现了新的标签table,表示表格,用来构造九宫格游戏区域,自学吧hhh

<div id="score">score:</div>
<div id="gameCountDown">0</div>
<a id="playButton" onclick="gameStart()">Start</a>
<table class="playZone">
<tr>
<th id="1"></th>
<th id="2"></th>
<th id="3"></th>
</tr>
<tr>
<th id="4"></th>
<th id="5"></th>
<th id="6"></th>
</tr>
<tr>
<th id="7"></th>
<th id="8"></th>
<th id="9"></th>
</tr>
</table>
<div id="readyCountDown">3</div>
<div id="readyBackground"></div>
<img id="touch" >

css:

//两个新的知识点

//伪类选择器action,和onclick表达意思一样

//属性z-index,相当于权重,权重大的会放在最上面

//两个新的骚操作

//鼠标变成锤子,鼠标的图片类型有ico,cur,ani,前面两个静态,后面动态

//按钮立体且按下压缩,看得懂,但原理跟美术有关,我不会,我直接用

*{
padding:0;
margin:0;
}
html{cursor:url("hammer-up.ico"),auto;}
html:active{cursor:url("hammer-down.ico"),auto;}
body{background-image:url("c.png");}
#playButton{
color:rgba(255,255,255,1);
background-color:rgba(219,87,5,1);
font-family:'Yanone Kaffeesatz';
font-size:3em;
padding:4px;
border-radius:8px;
box-shadow:0px 9px 0px rgba(219,31,5,1),0px 9px 25px rgba(0,0,0,.7);
display:block;
margin:50px auto;
width:100px;
text-align:center;
}
#playButton:hover{cursor:pointer;}
#playButton:active{box-shadow:0px 3px 0px rgba(219,31,5,1),0px 3px 6px rgba(0,0,0,.9);}
#gameCountDown{
width:90px;
height:90px;
background:black;
float:right;
color:white;
font-size:70px;
padding:4px;
border-radius:8px;
font-family:Microsoft YaHei;
position:relative;
bottom:20px;
right:200px;
text-align:center;
}
#score{
width:160px;
background:black;
float:left;
color:white;
font-size:40px;
padding:4px;
border-radius:8px;
font-family:Microsoft YaHei;
position:relative;
left:150px;
}
.playZone{margin:auto;}
th{
width:100px;
height:100px;
border:solid 1px;
}
#readyCountDown{
position:absolute;
font-family:'Yanone Kaffeesatz';
font-size:100px;
z-index:1;
color:white;
width:150px;
height:100px;
text-align:center;
left:50%;
margin-left:-75px;
top:50%;
margin-top:-50px;
display:none;
}
#readyBackground{
position:fixed;
width:100%;
height:100%;
top:0;
opacity:0.8;
background:black;
display:none;
}
#touch{
display:none;
vertical-align:middle;
}

<link href='http://fonts.googleapis.com/css?family=Yanone+Kaffeesatz:700' rel='stylesheet' type='text/css'>

效果图:


2.函数实现

我们先来理清一下整个过程

按钮本来是start,点击鼠标锤子会往下打,按下按钮后,按钮变成stop,准备倒计时背景会显示,倒计时数字动态显示”3,2,1,begin!“,显示结束后背景和数字一起消失,游戏倒计时开始从60递减,九宫格位置随机,时间随机的出现图片,锤子打下去图片会从微笑变成生气,得分+1,一定时间之后或者锤子打中之后图片都会消失,按下按钮stop或者60s倒计时结束游戏都会结束清空

  • gameStart():按下按钮后,判断是否正在游戏,如果不是,启动readyCountDownChange()开始准备倒计时,变成结束按钮,如果在游戏中,就启动gameReset()结束游戏,变成开始按钮

  • readyCount():显示准备倒计时背景和文字,间隔一秒输出“3,2,1,begin!”,输出完毕后启动gameCountDownChange()和show()启动游戏倒计时和游戏区域的开始

  • gameCountDownChange():每隔一秒时间自减并刷新,如果时间小于0,则停止,则启动gameReset()结束游戏

  • show():这里的结构较为难懂,show()的目的是循环调用imgChange()让图片随机出现并间隔一段时间后消失,imgChange()控制的是一个图片出现与消失的时间间隔,show()控制的是图片之间出现的时间间隔,show()要用setInterval,imgChange()只用setTimeout就行,因为show()调用imgChange(),既然show()循环,那么imgChange()一定循环,我们需要一个有范围的随机时间,这个范围就自己拟定吧,肯定会让游戏难度不一样,之前我们说过,setInterval会提前把任务准备好,不能直接修改时间,除非把计时器清空了再重新调用,可以跟着代码模拟一下过程,应该就会懂了

  • imgChange():产生1-9的随机数来定位九宫格,复制微笑的图片并插入到格子里,一定时间会自动消失,为什么要复制呢,因为我只给了一张图,很容易产生两条语句同时修改图片的情况,还有一种解决方法就是给9张图,随机数决定哪张图显示,这里的时间我设置为show()里产生的随机时间的一半,只要设置为全局变量就可以调用,至于为什么是一半,我现在忘了哈哈哈,记得当时还做了几次实验,如果图片被打中了会变成生气的图片,然后消失,并且启动scoreNumberChange()改变得分板

  • scoreNumberChange():被调用一次分数就自增一次,并且刷新显示

  • gameReset():清空所有的计时器,把按钮变回开始按钮,清空得分和倒计时

javascript:

//都是用的我上面讲过的东西

var lbplayButton=document.getElementById("playButton");
var lbreadyCountDown=document.getElementById("readyCountDown");
var lbreadyBackground=document.getElementById("readyBackground");
var lbgameCountDown=document.getElementById("gameCountDown");
var lbimg=document.getElementById("touch");
var lbscore=document.getElementById("score");
var randomTime;
var ison=false;
var countDownNumber=60;

var newImg;
var r,r1;
var scoreNumber=0;
function gameStart(){
if(ison==false){
ison=true;
lbplayButton.innerHTML="Stop";
readyCountDownChange();
}
else{
ison=false;
gameReset();
}
}
function readyCountDownChange(){
lbreadyCountDown.style.display="block";
lbreadyBackground.style.display="block";
setTimeout("lbreadyCountDown.innerHTML='2'",1000);
setTimeout("lbreadyCountDown.innerHTML='1'",2000);
setTimeout("lbreadyCountDown.innerHTML='begin!'",3000);
setTimeout("lbreadyCountDown.style.display='none';lbreadyBackground.style.display='none';gameCountDownChange();show();",4000);
}
function gameCountDownChange(){
lbgameCountDown.innerHTML=countDownNumber;
countDownNumber=countDownNumber-1;
if(countDownNumber<0){
gameReset();
}
r=setTimeout("gameCountDownChange()",1000);
}
function show(){
clearInterval(r1);
randomTime=Math.floor(Math.random()*1800+600);
imgChange();
r1=setInterval("show()",randomTime);
}
function imgChange(){
var randomId=Math.floor(Math.random()*9+1);
var pst=document.getElementById(randomId);

newImg=lbimg.cloneNode();
newImg.onmousedown=function(){newImg.src="rnm.jpg";};
newImg.onmouseup=function(){newImg.src="smile.jpg";newImg.style.display="none";scoreNumberChange();};
pst.appendChild(newImg);
newImg.style.display="block";
setTimeout("newImg.style.display='none'",randomTime/2);
}
function scoreNumberChange(){
scoreNumber++;
lbscore.innerHTML="score:"+scoreNumber;
}
function gameReset(){
clearTimeout(r);
clearInterval(r1);
lbplayButton.innerHTML="Start";
lbgameCountDown.innerHTML=0;
scoreNumber=0;
lbscore.innerHTML="score:";
}

效果图:

可以看出,我这手速是吃不了鸡的

这个代码可以进一步改进,比如保存分数加个排行榜什么的

以上是关于web前端之javascript的主要内容,如果未能解决你的问题,请参考以下文章

web前端优化之常规优化

[Web 前端] 前端频道之团队维护聚合订阅

Python 之WEB前端插件

测试开发之前端篇-Web前端简介

Web前端面试之HTML

大巧不工-WEB前端设计修炼之道pdf