震惊 一文入门Javascript!!!

61 阅读19分钟

Js

在整个HTML页面中,主要由三部分组成

  • HTML:页面的内容、结构
  • CSS:页面的表现形式、部分动画
  • JavaScript:页面的行为、交互、功能

JavaScript是运行在浏览器端的脚本语言,JavaScript主要解决的是前端与用户交互的问题

是一种动态性、弱类型的语言;

他的解释器就在我们的浏览器中,是浏览器的一部分

这门语言对大小写敏感,并会忽略多余的空格,可以使用\进行代码换行,注释使用///**/

JS主要由三部分组成

  • ECMAScript:语言的语法和基本对象
  • 文档对象模型Dom(Document Object Model):处理网页内容的方法和接口
  • 浏览器对象模型Bom(BrowserObjectModel):与浏览器进行交互的方法和接口

JavaScript引入

js的引入主要有三种方式

  • 行间事件: 为某一个具体的元素标签赋予js内容,直接编写在标签处
<input type="button" value="按钮" onclick="alert('点我');">
  • 嵌入引入: 在文档页面通过Script标签嵌入

一般也建议将script标签写在整个html页面的最下方,避免影响dom构建速度

<script type="text/javascript">
    alert("ok!");
    // alert函数用来展示一个提示框
</script>
  • 外部引入: 定义单独js文件,通过script标签进行引入
<script type="text/javascript" src="js/main.js"></script>

JavaScript变量

Js变量定义可以通过关键字var实现,多个变量定义可以使用半角逗号 , 隔开

var x = 1
var y = "2"
var z = 1, n = 3

注意: js中变量均为对象,在js中,每当声明了一个变量,就相当于创建了一个对象


命名规则遵循如下

  1. 区分大小写
  2. 首字符为字母数字下划线_、或美元符号$
  3. 其他字符可以为字母数字下划线美元符号

一些js代码在编写过程中的调试方式

  1. alert: 弹框
  2. console.log(): 浏览器控制台,输出
  3. document.title(): 页面标题

匈牙利命名

为了能够让代码的可读性更加友好,一般建议可以采用变量类型单词的首字母小写作为命名方式

比如一个数组变量users,那么结合其数组Array类型,可以定义为ausers

以下为参考选项:

  • 对象 o (Object):oPerson
  • 数组 a (Array):aUsers
  • 字符串 s (String):sAccount
  • 整数 i (Integer):iScore
  • 布尔值 b (Boolean):bIsLogin
  • 浮点数 f (Float):fPrice
  • 函数 f (Function):fEats
  • 正则 re (RegExp):reIDCard

Js数据类型

基本数据类型

Number

数字类型,可以带小数点,也可以不带

var a = 1
var b = 1.5
String

字符串类型,可以使用单引号双引号

var a = "abc";
var b = "aaaa" + 1
Boolean

布尔类型,只能是true|false

var a = true;
undefined

未定义类型

var a;
null

空对象类型

var a = null;

复合类型

Array

数组,索引从0开始

var people = ['张三','李四','王五'];
var people = new Array('张三','李四','王五');
var people = new Array();

数组对象也可以单独对某个位置上的值进行修改

people[0] = "张三"
people[1] = "李四"
people[2] = "王五"
Object

对象,就像是字典,定义时key值不需要设置类型

var person = {
    name: "张三",
    age: 18,
    sex: "male",
};

获取对象内元素可以通过如下两种方式

person["name"]
person.name

赋值或修改也可以像面向对象的猴子补丁方式去操作

var person = new Object();
person.name = "张三";
person.age = 17;

数据类型获取

如果希望可以查看到某个数据的具体类型,可以通过typeof方法

var x = "abc";
alert(typeof x)

Js类型转换

普通类型转换

toString

字符串转换: toString

toString,支持BooleanNumberString三种主要类型

var x = 1;
var y = "abc";
var z = true;
x.toString() // "1"
y.toString() // "abc"
z.toString() // "true"
parseInt/parseFloat

数字转换: parseIntparseFloat

将只含有数字的字符串变为整形或浮点型,其他类型返回NaN()

如果字符串只是末尾含有字符,那么会将末尾字符去掉,成为数字

var x = "123"
var y = "123.01"
var z = "123aa"
parseInt(x) // 123
parseInt(y) // 123
parseInt(z) // 123

parseFloat(x) // 123
parseFloat(y) // 123.01
parseFloat(z) // 123

注意parseFloat转换的包含浮点数的字符串应该是十进制

八进制或十六进制,该方法会忽略前导0

八进制数字020会被解析为20

十六进制数字0xFF,会返回Nan,因为x符号不是有效字符

强制类型转换

Boolean()

当要转换的值是至少有一个字符的字符串

0数字或对象时,Boolean()函数将返回true

如果该值是空字符串、数字0undefinednull,它将返回false

Boolean(0) // false
Boolean(1) // true
Boolean("1") // true
Boolean("1a") // true
Number()

换与parseInt()parseFloat()方法的处理方式相似,只是它转换的是整个值,而不是部分值

Number(false) // 0
Number(true) // 1
Number(undefined) // NaN
Number(null) // 0
Number("1.2") // 1.2
Number("12") // 12
Number("1.2.3") // NaN
Number(new object()) // NaN
Number(50) // 50
String()

可把任何值转换成字符串

注意:强制转换成字符串和调用toString()方法的唯一不同之处在于,对nullundefined值强制类型转换可以生成字符串而不引发错误

Js数据类型操作

运算符

算术运算符
运算符描述示例结果
+x=y+2x=7
-x=y-2x=3
*x=y*2x=10
/x=y/2x=2.5
%取余x=y%2x=1
++累加x=++yx=6
--递减x=--yx=4

赋值运算符
运算符例子等价于结果
=x=yx=5
+=x+=yx=x+yx=15
-=x-=yx=x-yx=5
*=x*=yx=x*yx=50
/=x/=yx=x/yx=2
%=x%=yx=x%yx=0
  • 注意数字与字符串相加,结果将成为字符串

比较运算符
运算符描述示例
==等于x==8false
===全等(值和类型)x===5truex==="5"false
!=不等于x!=8true
>大于x>8false
<小于x<8true
>=大于或等于x>=8false
<=小于或等于x<=8true
  • 比较运算符常在条件语句中进行使用
var name = "张三";
if (name=="张三") {
    document.write("这个人是张三")
}

逻辑运算符
运算符描述示例
&&and(x < 10 && y > 1)true
``or`(x==5y==5)false`
!not!(x==y)true
条件运算符
var NumCheck = 0; 
var Dis = (NumCheck==0) ? "是数字0":"不是数字0";
  • 如果变量NumCheck0,则Dis的值为:"是数字0";反之为:"不是数字0"

数据类型操作

字符串操作
字符串合并

直接通过加号即可

var a = "abc"
var b = "efg"
a + b // abcefg
字符串切分
String.split(str, num)

字符串按分隔符str进行切分,num参数控制返回结果数组的最大长度

var x = "a,b,c"
x.split(",") // ["a", "b", "c"]
x.split(",", 2) // ["a", "b"]
字符串替换
String.replace([old|/regex/g], new)

将字符串中的old替换为new,返回新的字符串,不会影响原有String

默认只进行第一次匹配的替换,如果希望全局进行替换,可以采用正则,并带上全局标识g

var a = "a,b,c"
a.replace(",","*")  // "a*b,c"
a.replace(/,/g,"*") // "a*b*c"
字符串长度
String.length

直接使用即可,不需要加括号

var a = "a,b,c"
a.length // 5
字符串查询
String.indexOf(str)

对大小写敏感,返回字符串中一个子串第一处出现的索引,找不到返回-1

var a = "a,b,c"
a.indexOf(",") // 1
字符串截取
String.substring(start, end)

start截取至end的前一个,左闭右开取值

参数只能是非负整数

var a = "a,b,c"
a.substring(0,2) // "a,"

String.slice(start, end)

使用与substring相同

但参数可以是负数,比如-1从后往前取第一个

var a = "a,b,c"
a.substr(-1,3) // "c"

String.substr(start, len)

起点为start,截取长度为len个字符

var a = "abcdefg"
a.substr(2,5) // "cdefg"
字符串去空格
String.trim()

去除字符串行首尾的空格

var a = " aa "
a.trim() // "aa"
字符串反转

结合使用数组的reverse函数

var x = "abcd";
x.split("").reverse().join("")	
数组操作方法
数组的定义
var aList = new Array(1,2,3);
var aList = new Array();
aList[0] = "a";
aList[1] = "b";
var aList = [1,2,3,4,"a"];
数组拼接
Array.concat(array1, array2...)

拼接一个或多个数组或值,并返回一个新的数组,不会影响原有数组

var a = new Array(1,2,3);
var b = new Array(4,5,6);
var c = a.concat(b) // [1, 2, 3, 4, 5, 6]
数组长度
Array.length

返回数组长度

var a = [1,2,3]
a.length // 3
数组遍历判断
Array.every(function(currentValue,index,arr))
// currentValue : 当前元素的值
// index: 当前元素的索引值
// arr: 当前元素所属的数组对象

判断数组中每一项是否都满足条件,所有项都满足条件,返回true,反之为false

// 判断数组元素是否均为偶数
var a = [1,2,3]
a.every((currentValue,index,arr)=>{
    return currentValue % 2 == 0
}) // false

与之对应的还有some方法,只要有一个元素满足回调的判断,则返回true

数组过滤重组
Array.filter(function(currentValue,index,arr))
// currentValue : 当前元素的值
// index: 当前元素的索引值
// arr: 当前元素所属的数组对象

过滤数组中符合条件的对象,返回组成一个新的数组

// 将数组中的偶数返回为一个新的数组
var a = [1,2,3,4,5,6]
a.filter((currentValue,index,arr)=>{
    return currentValue % 2 == 0
}) // [2, 4, 6]
数组迭代遍历
Array.forEach(function(currentValue, index, arr))
// currentValue : 当前元素的值
// index: 当前元素的索引值
// arr: 当前元素所属的数组对象

调用数组的每个元素,并将元素传递给回调函数

// 遍历数组中每一个元素,并将其*2
var a = [1,2,3]
a.forEach((currentValue,index,arr)=>{
   	arr[index] = currentValue * 2
}) // [2, 4, 6]
数组包含检查
Array.includes(element)

使用===运算符判断数组中是否包含某元素element

var a = [1,2,3]
a.includes(1) // true
数组元素定位
Array.indexOf(element)

返回数组中某个指定的元素element的位置,查找不到返回-1

var a = [1,2,3]
a.indexOf(2) // 1

还有与之对应的lastIndexOf方法,该方法从后向前搜索,返回指定元素在数组中最后出现的位置,

数组字符串拼接
Array.join(å)

数组元素按照拼接符separator拼接,组合为一个新的字符串

var a = [1,2,3]
a.join("*")) // 1*2*3
数组迭代加工
Array.map(function(currentValue,index,arr))
// currentValue : 当前元素的值
// index: 当前元素的索引值
// arr: 当前元素所属的数组对象

迭代访问数组中每个元素,并经过回调函数加工,返回的值组合为一个新的数组

// 大家都加1
var a = [1,2,3]
a.map((value)=>{
    return value + 1
}) // [2,3,4]
数组末尾返回
Array.pop()

从数组末尾删除并返回元素

var a = [1,2]
a.pop() // 2
a // [1]

与之对应的还有shift方法,可以删除并返回数组的第一个元素

数组末尾添加
Array.push(element)

向数组末尾添加元素,可以一次性添加多个元素

返回此时数组添加元素后的长度

var a = [1]
a.push("a","b") // [1, "a", "c"]
数组元素反转
Array.reverse()

将数组顺序反转,会影响数组本身

var a = [1,2,3,4,5];
a.reverse(); // [5, 4, 3, 2, 1]
数组切片获取
Array.slice(start, end)

左闭右开提取元素,返回新的数组

var a = ["A","B","C"]
a.slice(1,2) // ["B"]
数组添加/删除
Array.splice(index, howmany, items...)
// index: 从何处开始添加/删除元素
// howmany: 删除多少元素,为0时只添加不删除
// items: 添加index位置的元素们

根据howmany参数指定的数量进行删除,并在指定位置index处添加items元素

影响原有数组本身

// 在索引为2的位置删除一个元素,并添加b,c在其后
var a = [1,2,"a",4,5]
a.splice(2,1,"b","c") // [1, 2, "b", "c", 4, 5]

Js分支、循环

分支语句

if条件语句
var iNum = 0;
if (iNum==0){
    ...;
}else if (iNum==1) {
   	条件细分...;
}else{
	不满足以上条件均到这里;   
}
switch条件语句
var day = new Date().getDay(); // 星期日:0  范围:0~6
switch(day){
    case 0:
        alert("今天是星期二");
        break;
    case 1:
        ...
        break;
    ...
}

工作原理:首先设置表达式n(通常是一个变量);随后表达式的值会与结构中的每个case的值做比较。如果存在匹配,则与该case关联的代码块会被执行。请使用break来阻止代码自动地向下一个case运行

循环语句

for循环语句
基本语法
for(var i = 0; i < len; i++){
    ...
}
// for(起点数据; 判断条件; 数据递增或递减){}
语句详解

可以省略循环使用的递进变量的定义

var i = 0;
for( ;i < 10; i++){
	...
}
// 如果循环起始值已经被设置,可以在开头省略

当没有第二个语句时,会实现死循环,同时必须在循环内提供break,否则循环则无法停下来,可能令客户端浏览器崩溃

for(var i = 0; ; i++){
    ...
    if (i==5){
        ...
        break; //终止循环
    }
}

如果没有提供第三个语句,可以在for循环中进行编写数值的变化

for(var i = 0; i < 10; ){
    console.log(i);
    i += 2;
}
for-in

for循环还可以脱离中间索引控制变量,直接进行序列类型数据的迭代访问

for (x in object){
    console.log(x);
}

迭代的对象遵循如下规则:

  • 字符串:x下标
  • 数组:x下标
  • 对象:xkey

一个小例子

var x = "abcdef"  // 0,1,2,3,4,5
var y = [1,2,3,4,"5"] // 0,1,2,3,4
var z = { //  name,age,gender
    name:"张三",
    age:16,
    gender:"male",
}
for (obj in z){
    console.log(obj);
}
while循环语句
基本语法

当满足条件时,循环将继续执行

while (条件){
    执行代码;
}

所以一般可以通过被访问对象实际的值来做while循环的条件

var x = "abcdef";
var i = 0;
while (x[i]){
    console.log(x[i]);
    i++;
}

下标超出范围时不会报错,返回undefined,此时条件为假

do-while

do/while循环是while循环的变体

该循环首先会执行一次循环代码块,然后检查循环条件是否为真,如果条件为真,就会重复这个循环

do{
	循环执行代码
}while (条件);

也就是说,do-while至少会执行一次

var i = 3;
do{
    console.log(i)
    i--;
}while (i > 5);

Js函数

基本语法

js的函数为包裹在花括号中的代码块,使用关键词function定义函数

<button onclick="func()">点击这里</button>
function func(arg1,arg2,...) {
    alert("函数被执行")
    // 执行代码
    return 1; // return是可选的,并且可以不写返回值,单纯只做函数终止
}
// 函数名 func
// 参数 arg1,arg2,...
// 返回值 return 1

函数调用和其他语言一致,加上小括号即可

func() // 函数执行
作用域
局部变量

JavaScript函数内部声明的变量(varlet)是局部变量,

  • 只能在函数内部访问它
  • 该变量的作用域是局部的

生命周期:局部变量会在函数运行以后被删除 (生命期从它们被声明的时间开始)

全局变量

在函数外声明的变量是全局变量

网页上的所有脚本和函数都能访问它

生命周期:全局变量会在页面关闭后被删除 (生命期从它们被声明的时间开始)


局部变量如果希望变为全局变量、可以使用windows.var =的形式赋予给当前窗口

var x = 1;
window.x = x;

function func(x,y){
    return x + y
}
var res = func(1,2)
alert(res)
  • JavaScript函数解析过程:
    1. 预编译function函数提前,并将var定义的变量声明提前,先暂时赋值为undefined
    2. 执行
func() // 弹出提示
alert(iNum) // undefined
alert(abc) // 出错
function func() {
    alert("这个是函数")
}
var iNum = 1

匿名函数

函数可以没有名字,比如直接为某些事件赋值

window.onload = function(){
	var sDate = new Date()
	console.log(sDate)
}
封闭函数

封闭函数常用来创建一个开始就执行而不用命名的函数

注意: 这里的函数需要被括号包裹,否则解释器无法理解函数末尾的()

(function(){
    alert("你好");
})();

也可以在函数定义前加上"~"和"!"等符号来定义匿名函数,并且直接执行

!function(){
    alert("你好");
}();

封闭函数和函数一样,可以创建一个独立的空间

在封闭函数内定义的变量不会影响外部同名的函数和变量,可以避免命名冲突

var x = 1;
!function(){
	var x = "这是同名变量";
    alert(x);
}
alert(x);

Js-Dom操作

元素获取

getElementById: 通过id获取页面的dom元素

getElementsByName: 通过标签的name属性进行获取

getElementsByTagName: 通过标签名进行获取

注意:获取对应元素时,首先要确定页面已经生成所需元素


一般可以使用windows.onload()事件判断是否已经生成页面,这样保证获取操作一定是在dom元素生成的情况下


比如一段html如下

<p id="p">这是一段待获取的文字</p>

可以通过getElementById方法获取某个标签元素,并且打印其标签信息

var sP = document.getElementById('p');

也可以在页面加载时,触发方法获取页面元素

window.onload = function(){
    var sP = document.getElementById('p');
    console.log(sP);
}

属性读取

可以通过id方式获取到对应页面内的元素,就可以对元素的属性进行操作,包括对属性的读和写

读取元素属性: dom.attr

<p id="aaa" style="color: red;">这是一段待获取的文字</p>
var oP = document.getElementById('aaa');
oP // <p id="aaa" style="color: red;">这是一段待获取的文字</p>
oP.id // aaa
oP.style // CSSStyleDeclaration {0: "color", ...}
oP.style.color // "red"

属性修改

通过id获取到的元素对象,直接对属性赋值即可实现修改

修改元素属性: dom.attr = xxx

比如希望可以点击按钮,修改某段文本的颜色样式,可以通过获取style属性,并为其中具体的颜色值进行赋值修改操作

<p id="aaa" style="color: red;">这是一段待获取的文字</p>
<button onclick="blue_font()">按钮</button>

js方法如下

function blue_font(){
    var oP = document.getElementById('aaa');
    oP.style.color = "blue";
    // 修改字体样式属性中的字体颜色为蓝色
}

方法也可以直接为id为某值的元素其对应的点击事件进行赋值

这样就不用在去使用onclick事件赋值到元素上了

<button id="change_color">按钮</button>
<script>
	change_color.onclick = function(){
    	...
    }
</script>

文本操作

对于标签的文本获取及修改,可以通过innerHTML属性进行操作

比如下面的a标签,将会通过点击变为另外的文本

<a id="a" href="https://www.baidu.com">百度</a>
<button onclick="urlChange()">变搜狗</button>

js方法如下

function urlChange(){
    var oA = document.getElementById('a');
    oA.href = "https://www.sougou.com";
    console.log(oA.innerHTML); // 获取标签文本内容
    oA.innerHTML = "搜狗"; //修改标签文本内容
}

表单操作

通过表单的value属性即可获取得到对应的数据

Js事件

Js中的事件可以帮助为用户提供更棒的交互访问

常见的事件如下

  • 用户点击鼠标
  • 网页已加载
  • 图像已加载
  • 鼠标移动某个元素上
  • 输入字段被改变时
  • 提交表单时
  • 用户触发某些按键时

点击事件

dom.onclick

在用户点击鼠标时触发

<p onclick="TextChange(this)">这是文本</p>
<!-- this 代表当前的dom元素 -->

点击某按钮可以修改这个标签元素对应的文本信息

function TextChange(this){
    this.innerHTML = "文本修改"
    //可以直接通过传来的参数进行dom元素的读取及修改
}

鼠标移动

dom.onmouseover // 用户鼠标移入某元素时触发
dom.onmouseout // 当鼠标移出元素时候触发

可以在鼠标移动时切换字体颜色

<p id="aaa">请把鼠标移动过来</p>

通过对dom元素的style属性进行修改

var oP = document.getElementById("aaa");
oP.onmouseover = function(){
    oP.style.color = "green";//可以直接通过传来的参数进行页面元素的读取及修改
}
oP.onmouseout = function(){
    oP.style.color = "red";
}

键盘点按

dom.onkeydown // 某个键被按下
dom.onkeypress // 某个键被按住
dom.onkeyup // 某个键被松开

统计用户按了多少次键盘

<input type="text" onkeydown="calc()">
var num = 1
calc(){
    num += 1
}

Js定时器

Js中定时器非常重要,常常用来定时调用函数、制作动画

比如常见的发送短信后,点击按钮会有60s的冷却时间,就可以通过定时器来完成

反复执行定时器

反复执行的定时器会不停重复的执行方法函数

setInterval_obj = setInterval(code, millisec)
// code: 必须参数, 定时执行的函数,或是一段代码串
// millisec: 必须参数,执行时的时间间隔,毫秒为单位

要注意的是,定时器要有关有开,不能开了不管,所以一般还会搭配定时器关闭方法

clearInterval(setInterval_obj)
// 关闭反复执行的定时器
跑马灯demo
<!--跑马灯效果-->
<h3 id="h3">abcdefg</h3>
<button id="start_button">开始</button>
<button id="stop_button">停止</button>

为了避免点击开始按钮时,有多个跑马灯同时进行,以单例思路进行定时器的开启

// 开启定时事件
start_button.onclick = function(){ 
    if (window.sT) {return;} // 存在跑马定时, 则此次启动无效
    var sT = setInterval(loop,1000);
    window.sT = sT; // 声明此sT定时事件为全局变量,为了之后的定时器关闭工作
}

定义的反复执行方法,会将字符串的头部字符放入字符串的臀部,实现跑马灯的效果

// 跑马灯方法
function loop(){
    var Opstr = document.getElementById('h3');
    Opstr.innerHTML = Opstr.innerHTML.substring(1) + Opstr.innerHTML[0]
    console.log(Opstr.innerHTML)
}

不要忘记当点击停止按钮时,将定时器关闭

// 关闭定时器
stop_button.onclick = function(){ 
    clearInterval(sT)
}

等待执行定时器

等待执行定时器只会执行一次,在等待时间到达时触发函数方法

setTimeout_obj = setTimeout(code, millisec)
// code: 必须参数, 定时执行的函数,或是一段代码串
// millisec: 必须参数,执行时的时间间隔,毫秒为单位

关闭只执行一次的等待计时器

clearTimeout(setTimeout_obj)
等待消失dmeo

比如点击按钮,不是立即让文本内容消失,而是过一段时间,那么可以通过等待执行定时器完成

<h3 id="h3">我是一个内容</h3>
<button id="start_button">让上面的内容消失</button>

js代码如下

start_button.onclick = function(){
    var st = setTimeout(clear,1000)
    window.st = st;
}
function clear(){
    var oH3 = document.getElementById('h3');
    oH3.innerHTML = "";
}