JavaScript

JavaScript

运行JS

在HTML中使用<script>标签

<script>标签可以插在<head>或者<body>标签中,内部的内容就是js代码。

<script>
function myFunction()
{
    document.getElementById("demo").innerHTML="我的第一个JavaScript函数";
}
</script>

外链引入

方式是使用<script>标签的src属性来引入外部的js文件

<head>
    ...
    <script src="./4-1.js"></script>
    ...
</head>

对于较大的项目一般推荐使用引入外链的方式

了解JS输出内容的方式

alert()函数

调用alert()函数将会弹出一个窗口并将传入的参数打印出来。

<body>
<script>
    alert("Hello World!!")
</script>
</body>

alert()可以打印绝大多数的数据类型,包括数组和对象在内

console.log()函数

这个函数会把接受的变量以及详细的类型打印到浏览器的控制台中。打开页面后查看控制台,就可以看到结果了

<body>
<script>
    var obj={
        name: "mark",
        sex: "male"
    };
    console.log(obj);
</script>
</body>

变量的定义与数据类型

  • 没有类型,任何变量可存储任何类型的数据
  • 无需提前声明就可以直接使用

语法规范

  1. 变量必须以字母开头或$_开头
  2. 大小写敏感

当您向变量分配文本值时,应该用双引号或单引号包围这个值。

声明变量使用var关键字,可以储存任意类型的数据

var myInt=123;
var myDecimal=12.1;
var myString="Hello JS";
var myArray=[1,"Hello",12.3,{name:"lux"}];
var myObject={name:"kux",sex:"male",age:"18"}
var myFunction=function(){return "this is a function"}

变量可以随意转换类型,也可不声明直接用(不推荐)

let允许你声明一个作用域被限制在块级中的变量、语句或者表达式。在Function中局部变量推荐使用let变量,避免变量名冲突。)

你应该特别留意数组和对象两种类型,它们的作用方式和静态语言存在很大的不同

strict模式

JavaScript在设计之初,为了方便初学者学习,并不强制要求用var申明变量。这个设计错误带来了严重的后果:如果一个变量没有通过var申明就被使用,那么该变量就自动被申明为全局变量
使用var申明的变量则不是全局变量,它的范围被限制在该变量被申明的函数体内(函数的概念将稍后讲解),同名变量在不同的函数体内互不冲突。

为了修补JavaScript这一严重设计缺陷,ECMA在后续规范中推出了strict模式,在strict模式下运行的JavaScript代码,强制通过var申明变量,未使用var申明变量就使用的,将导致运行错误。

启用strict模式的方法是在JavaScript代码的第一行写上:

'use strict';

几个特殊的变量

NaN

Nan这个特殊的值与所有其他值都不相等,包括自己
唯一能判断NaN的方法是通过isNaN()函数

isNaN(NaN);//true
null和undefined

null表示一个“空”值,与0''不同,0是一个数值,''表示长度为0的字符串,而null表示“空”。
有一个和null类似的undefined,它表示“未定义”。
JavaScript的设计者希望用null表示一个空的值,而undefined表示值未定义。事实证明,这并没有什么卵用,区分两者的意义不大。大多数情况下,我们都应该用nullundefined仅仅在判断函数参数是否传递的情况下有用。

Object

JavaScript 对象是拥有属性方法的数据。
对象也是一个变量,但对象可以包含多个值(多个变量)

定义一个对象

JavaScript用一个{...}表示一个对象,键值对以xxx: xxx形式申明,用,隔开。注意,最后一个键值对不需要在末尾加,,如果加了,有的浏览器(如低版本的IE)将报错。

var car={type:"Fiat",model:500,color:"white"};

如果属性名包含特殊字符,就必须用”括起来:

var xiaohong={
    name:'小红',
    'middle-school':'No.1 Middle School'
};

xiaohong的属性名middle-school不是一个有效的变量,就需要用''括起来。访问这个属性也无法使用.操作符,必须用['xxx']来访问:

xiaohong['middle-school']; // 'No.1 Middle School'
xiaohong['name']; // '小红'
xiaohong.name; // '小红'

也可以用xiaohong['name']来访问xiaohongname属性,不过xiaohong.name的写法更简洁。我们在编写JavaScript代码的时候,属性名尽量使用标准的变量名,这样就可以直接通过object.prop的形式访问一个属性了。

实际上JavaScript对象的所有属性都是字符串,不过属性对应的值可以是任意数据类型。

如果访问一个不存在的属性会返回什么呢?JavaScript规定,访问不存在的属性不报错,而是返回undefined

由于JavaScript的对象是动态类型,你可以自由地给一个对象添加或删除属性:

var xiaoming={
    name:'小明'
}
xiaoming.age=18;//新增一个age属性
delete xiaoming.age;//删除age属性
delete xiaoming['name'];//删除name属性
delete xiaoming.school;//删除不存在的属性不会报错

如果我们要检测对象是否拥有某一属性,可以用in操作符:

var xiaoming={
    name:xiaoming
};
'name' in xiaoming;//true
'grade' in  xiaoming;//false

小心,如果in判断一个属性存在,这个属性不一定是xiaoming的,它可能是xiaoming继承得到的:

'toString' in xiaoming;//true

因为toString定义在object对象中,而所有对象最终都会在原型链上指向object,所以xiaoming也拥有toString属性。
要判断一个属性是否是xiaoming自身拥有的,而不是继承得到的,可以用hasOwnProperty()方法:

var xiaoming={
    name:'小明'
};
xiaoming.hasOwnProperty('name');//true
xiaoming.hasOwnProperty('toString');//false

总之,JavaScript 对象是属性变量的容器。
JavaScript 对象是键值对的容器
键值对通常写法为name : value(键与值以冒号分割)。
键值对在 JavaScript 对象通常称为 对象属性。

对象方法

对象的方法定义了一个函数,并作为对象的属性存储
对象方法通过添加()调用

name=person.fullName();//访问了 person 对象的 fullName() 方法
name=person.fullName;//访问 person 对象的 fullName 属性,它将作为一个定义函数的字符串返回
Date 日期对象

日期对象可以储存任意一个日期,并且可以精确到毫秒数。
定义一个时间对象 :

var Udate=new Date(); 

注意:使用关键字newDate()的首字母必须大写。

使 Udate 成为日期对象,并且已有初始值:当前时间(当前电脑系统时间)。

如果要自定义初始值,可以用以下方法:

var d = new Date(2012, 10, 1);  //2012年10月1日
var d = new Date('Oct 1, 2012'); //2012年10月1日

我们最好使用下面介绍的“方法”来严格定义时间。

访问方法语法:“<日期对象>.<方法>”

Date对象中处理时间和日期的常用方法:

方法功能
get/setDate()返回/设置日期
get/setFullYear()返回/设置年份(4位数表示)
get/setYear()返回/设置年份
get/setMonth()返回/设置月份 0:一月,1:二月……
get/setHours()返回/设置小时,24小时制
get/setMinutes()返回/设置分钟数
get/setSeconds()返回/设置秒钟
get/setTime()返回/设置时间(单位:毫秒)
get/setDay()返回星期,返回的是0-6的数字,0 表示星期天。
Math对象

提供对数据的数学运算

<script type="text/javascript">
  var mypi=Math.PI; //3.141592653589793
  var myabs=Math.abs(-15);//15
  document.write(mypi);
  document.write(myabs);
</script>

注意:Math 对象是一个固有的对象,无需创建它,直接把 Math 作为对象使用就可以调用其所有属性和方法。这是它与Date,String对象的区别。

Math对象属性
属性说明
E自然对数底数
LN22的自然对数
LOG2E以2为底e的对数
PIπ
SQRT1_22的平方根的倒数
SQRT22的平方根
Math对象方法
方法说明
ceil()向上取整
exp()返回e的指数
floor()向下取整
random()返回0~1之间的随机数
round()把数四舍五入为最接近的整数
toSource()返回该对象的源代码
valueOf()返回Math对象的原始值

Array

创建一个数组
  1. 常规方式
var mrCars=new Array();
myCars[0]="Saab";
myCars[1]="Volvo";
myCars[2]="BMW";
  1. 简洁方式
var myCars=new Array("Saab","Volvo","BMW");
  1. 字面
var myCars=["Saab","Volvo","BMW"];

所有的JavaScript变量都是对象。数组元素是对象。函数是对象。
因此,你可以在数组中有不同的变量类型。
你可以在一个数组中包含对象元素、函数、数组:

myArray[0]=Date.now;
myArray[1]=myFunction;
myArray[2]=myCars;

直接给Arraylength赋一个新的值会导致Array大小的变化:

var arr=[1,2,3];
arr.length;//3
arr.length=6;//arr变为[1,2,3,undefined,undefined,undefined]
arr.length=2;//arr变为[1,2]

如果通过索引赋值时,索引超过了范围,同样会引起Array大小的变化:

var arr=[1,2,3];
arr[5]='x';//arr变为[1,2,3,undefined,undefined,'x'];
数组的方法和属性

完整数组对象参考手册

属性/方法说明
length数组中元素的数量
indexOf()括号内对象的索引值
concat()合并数组
pop()删除数组的最后一个元素
push()数组的末尾添加新的元素
reverse()反转顺序
shift()删除数组第一个元素并返回删除的元素
slice(a,b)选择索引值为a~(b-1)的元素
sort()排序
toString转换数组到字符串
unshift("a","b")向数组之前添加元素ab,(不适用IE8之前的版本)
slice()

截取Array的部分元素,然后返回一个新的Array

var arr = ['A', 'B', 'C', 'D', 'E', 'F', 'G'];
arr.slice(0, 3); // 从索引0开始,到索引3结束,但不包括索引3: ['A', 'B', 'C']
arr.slice(3); // 从索引3开始到结束: ['D', 'E', 'F', 'G']
sort()
array.sort(方法函数);
  1. 如果不指定<方法函数>,则按unicode码顺序排列。
  2. 如果指定<方法函数>,则按<方法函数>所指定的排序方法排序。

注意: 该函数要比较两个值,然后返回一个用于说明这两个值的相对顺序的数字。比较函数应该具有两个参数 a 和 b,其返回值如下:
若返回值<=-1,则表示 A 在排序后的序列中出现在 B 之前。
若返回值>-1 && <1,则表示 A 和 B 具有相同的排序顺序。
若返回值>=1,则表示 A 在排序后的序列中出现在 B 之后。

排序函数栗子如下

<script type="text/javascript">
    function sortNum(a,b){
        return a-b;//升序;降序为b-a
    }
</script>

字符串

字符串不可变,如果对字符串的某个索引赋值,不会有任何错误,但是,也没有任何效果

多行字符串

用反引号`表示

`这是
一个多行
字符串`
模板字符串

如果有很多变量需要连接,用+号就比较麻烦。ES6新增了一种模板字符串,表示方法和上面的多行字符串一样,但是它会自动替换字符串中的变量:

var name='小明';
var age=20;
var message='你好,${name},你今年${age}岁了!'
alert(message);
字符串常用方法
toUpperCase()

把字符串变成大写

var s='Hello';
s.toUpperCase();
toLowerCase

把字符串变成小写
(同toUpperCase

charAt(index)

charAt()方法可返回指定位置的字符。返回的字符是长度为 1 的字符串。

indexOf(substring,startpos)

搜索指定字符串出现的位置
substring必要,startpos不必要

substring()

返回指定索引的字串

var s='hello world';
s.substring(0,5);//从索引0开始到5(不包括5)
s.substring(7);//从索引7开始到结束
substr()

从字符串中提取从 startPos位置开始的指定数目的字符串。

stringObject.substr(startPos,length);

startPos,必需,提取字串的开始位置
length,可选,提取字符串的长度,若忽略,从startPos到结尾
注意:如果参数startPos是负数,从字符串的尾部开始算起的位置。也就是说,-1 指字符串中最后一个字符,-2 指倒数第二个字符,以此类推。
如果startPos为负数且绝对值大于字符串长度,startPos为0。

split()
stringObject.split(separator,limit);

separator必需,从该参数指定的位置开始分隔字符串
limit可选,分隔的次数,返回的字串不会多于该参数限定的数组;若无参数则不限次数
注意:若把空字符用作separator,则每个字符间都会被分割
如:

var mystr='www.baidu.com';
document.write(mystr.split('.',2)+'<br />');//www,baidu
document.write(mystr.split('.'));//www,baidu,com

Windows对象

方法说明
alert()警告框
prompt()可提示用户输入的对话框
confirm()确认框
open()打开新浏览器窗口或查找一个已命名的窗口
close()关闭浏览器窗口
print()打印当前窗口内容
focus()把键盘焦点给予一个窗口
计时器方法
方法说明
setTimeout()指定的延迟时间后执行代码
clearTimeout()取消setTimeout()设置
setInterval()每隔指定时间执行代码
clearInterval()取消setInterval()设置
setInterval()
setInterval(代码,交互时间);

说明:交互时间以毫秒计算
返回值:可以传递给clearInterval()从而取消对“代码”周期性执行的值

//我们设置一个计时器,每隔100毫秒调用clock()函数,并将时间显示出来,代码如下:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>计时器</title>
<script type="text/javascript">
  var int=setInterval(clock, 100)
  function clock(){
    var time=new Date();
    document.getElementById("clock").value = time;
  }
</script>
</head>
<body>
  <form>
    <input type="text" id="clock" size="50"  />
  </form>
</body>
</html>
setTimeout()

setTimeout()计时器,在载入后延迟指定时间后,去执行一次表达式,仅执行一次。
参数与setInterval()相同

History对象

history对象记录了用户曾经浏览过的页面(URL),并可以实现浏览器前进与后退相似导航的功能。

注意:从窗口被打开的那一刻开始记录,每个浏览器窗口、每个标签页乃至每个框架,都有自己的history对象与特定的window对象关联。

运算符

比较运算符

特别注意相等运算符==。JavaScript在设计时,有两种比较运算符:
第一种是==比较,它会自动转换数据类型再比较,很多时候,会得到非常诡异的结果;
第二种是===比较,它不会自动转换数据类型,如果数据类型不一致,返回false,如果一致,再比较。
由于JavaScript这个设计缺陷,不要使用==比较,始终坚持使用===比较。

条件判断

JavaScript把nullundefined0NaN和空字符串''视为false,其他值一概视为true

循环

For/In循环

for/in循环遍历对象的属性

var person={fname:"John",lname:"Doe",age:25};

for(x in person)
{
    txt=txt+person[x];
}

由于Array也是对象,而它的每个元素的索引被视为对象的属性,因此,for ... in循环可以直接循环出Array的索引:

var a=['A','B','C'];
for(var i in a){
    console.log(i);//'0','1','2'
    console.log(a[i]);'A','B','C'
}

注意for ... inArray的循环得到的是String而不是Number

Map和Set

JavaScript的默认对象表示方式{}可以视为其他语言中的MapDictionary的数据结构,即一组键值对。

但是JavaScript的对象有个小问题,就是键必须是字符串。但实际上Number或者其他数据类型作为键也是非常合理的。

为了解决这个问题,最新的ES6规范引入了新的数据类型Map

Map

Map是一组键值对的结构,具有极快的查找速度。
举个例子,假设要根据同学的名字查找对应的成绩,如果用Array实现,需要两个Array

var name=['M','B','T'];
var score=[95,75,89];

给定一个名字,要查找对应的成绩,就先要在names中找到对应的位置,再从scores取出对应的成绩,Array越长,耗时越长。

如果用Map实现,只需要一个“名字”-“成绩”的对照表,直接根据名字查找成绩,无论这个表有多大,查找速度都不会变慢。用JavaScript写一个Map如下:

var m=new Map([['M',90],['B',80],['T',70]]);
m.get('M');//90

初始化Map需要一个二维数组,或者直接初始化一个空Map
Map具有以下方法:

var m=new Map();
m.set('A',90);//添加新的key-value
m.has('A');//是否存在key:'A'? true
m.get('A');//90
m.delete('A');
m.get('A');//undefined

由于一个key只能对应一个value,所以,多次对一个key放入value,后面的值会把前面的值覆盖掉

Set

SetMap类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在Set中,没有重复的key
要创建一个Set,需要提供一个Array作为输入,或者直接创建一个空Set

var s1=new Set();
var s2=new Set([1,2,3]);

重复元素在Set中自动被过滤

通过add(key)方法可以添加元素到Set中,通过delete(key)方法可以删除元素

Map和Set是ES6标准新增的数据类型,请根据浏览器的支持情况决定是否要使用。

iterable

遍历Array可以采用下标循环,遍历Map和Set就无法使用下标。为了统一集合类型,ES6标准引入了新的iterable类型,Array、Map和Set都属于iterable类型。

具有iterable类型的集合可以通过新的for … of循环来遍历。

for … of循环是ES6引入的新的语法。
用法如下:

var a=['A','B','C'];
var s=new Set(['A','B','C']);
var m=new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
for(var x of a){
    console.log(x);
}
for(var x of s){
    console.log(x);
}
for(var x of m){
    console.log(x[0]+'='+x[1]);
}

for … of循环和for … in循环的区别

for … in循环由于历史遗留问题,它遍历的实际上是对象的属性名称。一个Array数组实际上也是一个对象,它的每个元素的索引被视为一个属性。

当我们手动给Array对象添加了额外的属性后,for … in循环将带来意想不到的意外效果:

var a = ['A', 'B', 'C'];
a.name = 'Hello';
for (var x in a) {
    console.log(x); // '0', '1', '2', 'name'
}

for … in循环将把name包括在内,但Array的length属性却不包括在内。

for … of循环则完全修复了这些问题,它只循环集合本身的元素:

var a = ['A', 'B', 'C'];
a.name = 'Hello';
for (var x of a) {
    console.log(x); // 'A', 'B', 'C'
}

这就是为什么要引入新的for … of循环。

然而,更好的方式是直接使用iterable内置的forEach方法,它接收一个函数,每次迭代就自动回调该函数。以Array为例:

var a=['A','B','C'];
a.forEach(function(element,indexmarrat)){
    // element: 指向当前元素的值
    // index: 指向当前索引
    // array: 指向Array对象本身
    console.log(element+',index='+index);
}

注意,forEach()方法是ES5.1标准引入的
Set与Array类似,但Set没有索引,因此回调函数的前两个参数都是元素本身

var s=Set(['a','b','c']);
s.forEach(function(element,sameElement,set)){
    console.log(element);
}

Map的回调函数参数依次为value、key和map本身

var m=new Map([[1,'x'],[2,'y'],[3,'z']]);
m.forEach(function(value,key,map)){
    console.log(value);
};

如果对某些参数不感兴趣,由于JavaScript的函数调用不要求参数必须一致,因此可以忽略它们。例如,只需要获得Array的element:

var a = ['A', 'B', 'C'];
a.forEach(function (element) {
    console.log(element);
});

函数

JS是一门函数式编程的语言
特征:
1. 函数可以作变量
2. 函数可以作为另一个函数的参数或返回值

基本定义

函数一定要用function关键字声明,另外由于变量没有类型,所以函数也不用指定参数的类型和返回值的类型

function 函数名(参数1,参数2,...){
    函数代码
    return 返回值
}

函数可以没有名称,这样的函数被称为匿名函数,它可以保存到变量

如果没有return语句,函数执行完毕后也会返回结果,只是结果为undefined
由于JavaScript允许传入任意个参数而不影响调用,因此传入的参数比定义的参数多也没有问题,虽然函数内部并不需要这些参数

避免收到undefined,可以对参数进行检查:

function abs(x) {
    if (typeof x !== 'number') {
        throw 'Not a number';
    }
    if (x >= 0) {
        return x;
    } else {
        return -x;
    }
}

用变量储存函数

//用变量调用匿名函数
//addMe相当于函数指针,指向了这个匿名函数
var addMe=function(var1,var2){
    return var1+var2;
};

var a=1,b=2;

console.log(addMe(a,b));//利用变量来调用,输出为3

将函数作为值传递

最常用的情景是把函数当做参数来传递,这样做可以极大的扩充函数的功能

//定义两个匿名函数
var sayHello=function(name){
    console.log("hello,"+name);
}

var sayHi=function(name){
    console.log("hi",+name);
}

var arr=["Mark","Ann","Ouxu","Molybdenum","Ruby"];

//一个用于对arr数组进行操作的函数,第一个参数是要操作的数组,第二个参数是需要对数组中的元素所应用的函数

function operateArr(func){
    for(var i=0;i<5;++i){
        func(arr[i]);//这里的func相当于函数模板
    }
}

//传入不同的函数来执行
operateArr(sayHello);

operateArr(sayHi);

其中,sayHi和sayHello两个函数称为回调函数。

总之,函数可以说是编写js代码的最小结构块

arguments

JavaScript还有一个免费赠送的关键字arguments,它只在函数内部起作用,并且永远指向当前函数的调用者传入的所有参数。arguments类似Array但它不是一个Array:

function foo(x) {
    console.log('x = ' + x); // 10
    for (var i=0; i<arguments.length; i++) {
        console.log('arg ' + i + ' = ' + arguments[i]); // 10, 20, 30
    }
}
foo(10, 20, 30);

实际上arguments最常用于判断传入参数的个数。你可能会看到这样的写法:

// foo(a[, b], c)
// 接收2~3个参数,b是可选参数,如果只传2个参数,b默认为null:
function foo(a, b, c) {
    if (arguments.length === 2) {
        // 实际拿到的参数是a和b,c为undefined
        c = b; // 把b赋给c
        b = null; // b变为默认值
    }
    // ...
}

要把中间的参数b变为“可选”参数,就只能通过arguments判断,然后重新调整参数并赋值。

rest参数

由于JavaScript函数允许接收任意个参数,于是我们就不得不用arguments来获取所有参数。

function foo(a, b) {
    var i, rest = [];
    if (arguments.length > 2) {
        for (i = 2; i<arguments.length; i++) {
            rest.push(arguments[i]);
        }
    }
    console.log('a = ' + a);
    console.log('b = ' + b);
    console.log(rest);
}

为了获取除了已定义参数a、b之外的参数,我们不得不用arguments,并且循环要从索引2开始以便排除前两个参数,这种写法很别扭,只是为了获得额外的rest参数,有没有更好的方法?

ES6标准引入了rest参数,上面的函数可以改写为:

function foo(a, b, ...rest) {
    console.log('a = ' + a);
    console.log('b = ' + b);
    console.log(rest);
}

foo(1, 2, 3, 4, 5);
// 结果:
// a = 1
// b = 2
// Array [ 3, 4, 5 ]

foo(1);
// 结果:
// a = 1
// b = undefined
// Array []

rest参数只能写在最后,前面用…标识,从运行结果可知,传入的参数先绑定a、b,多余的参数以数组形式交给变量rest,所以,不再需要arguments我们就获取了全部参数。

如果传入的参数连正常定义的参数都没填满,也不要紧,rest参数会接收一个空数组(注意不是undefined)。

rest参数是ES6新标准

小心!

JavaScript引擎有一个在行末自动添加分号的机制,所以正确的多行写法是

function foo(){
    return{
        name:'foo'
    };
}

代码的执行

脚本语言和编译语言不同,不需要编译成可执行的二进制文件之后运行,它是解释运行的。

它工作的原理是由JS执行器读取JS文件后,一行一行代码的读取并执行,不会产生任何中间文件,程序运行的过程,就是由执行器读取代码文件的过程,脱离了执行器(也叫解释器或者代码引擎)代码就和纯文本没有任何区别了

一个典型的情况是,即便你的脚本中存在错误,只要执行的过程中没有执行到错误所在的地方,它都还能正常运行。

使用JS和用户交互

DOM节点

JS是通过HTMLDOM模型来控制HTML内容的,首先我们来了解一下什么是DOM

DOMDocument Object Model的缩写,也就是文档对象模型HTMLDOM就是整个页面元素的逻辑结构,包含了元素和元素之间的层级关系,你可以简单把它理解成一颗元素树。
DOM节点树
所有的HTML都可以整理成这样的一棵DOM节点树。JS可以对DOM节点进行各种操作:查找,获取,修改属性,内容,响应事件….

在JS中我们通常使用document对象来获取整个页面的DOM

JS获取页面元素的手段

下面介绍的函数都是document对象提供的方法,你可以像document.getElementById("main")这样使用。

根据id查找

id属性是一个元素的唯一标识符。

使用getElementById()方法
可以用一个变量保存查找到的DOM节点对象:

var x=document.getElementById("card1");//获取id为cad1的dom元素
根据类名(class)查找

使用getElementsByClassName()方法,注意方法名中Element为复数。因为同一class可能有多个元素,该方法返回该class所有元素的集合

注意:如果你是在body中书写js代码,一定要把这段代码放在你能获取的DOM节点后面,否则由于页面的解析是从上到下的,在你执行代码时将无法得到想要的DOM节点。

根据标签名查找

使用getElementsByTagName()方法,该方法返回的同样是集合,由于同名标签在整个页面中非常多,所以这个方法经常用于嵌套取出某个DOM节点内的指定标签

var x=document.getElementById("card1");//x是card1
var y=x.getElementsByTagName("p");//y是card1里的p标签

操作DOM

改变HTML内容

可以使用document.write()直接在script标签,也就是代码执行的位置直接写入内容

<body>
    <div>
        <script>
            document.write("<p>这是一段由JS创建的文字</p>")
        </script>
    </div>
</body>

更为常见的做法是,通过上面所述的方法获取DOM节点后,使用innerHTML属性来访问和修改对应节点的内容

<body>
    <h1 id="header">这是老标题内容...</h1>
    <script>
        var header =document.getElementById("header");
        header.innerHTML = "这是新标题内容..."; // 修改h1标签里的文字
    </script>
</body>
改变元素的样式

可以使用DOM对象的style属性来访问和修改对应元素的样式,你可以发现js中DOM对象的属性和对应html的元素的属性存在着对应的关系

<body>
    <p id="para1" style="color:red">其实我是蓝色文字</p>
    <p id="para2" style="font-size:2px">我的字很大</p>
    <script>
        document.getElementById("para1").style.color = 'blue';
        document.getElementById("para2").style.fontSize = '30px';
    </script>
</body>
事件和回调函数

事件编程
事件就是在操作页面过程可能发生的诸多动作,比如:点击一个按钮,拖动一个元素,将光标移动到某个元素上…你可以把这些事件理解成开关或者触发器,我们一般会绑定函数到某个事件上,当事件被触发的时候,该函数就会被自动调用,我们也把这种函数成为事件的回调函数
例子:通过点击一个按钮来弹出一个警告框

<body>
    <script>
        function alertSth(){
            alert("你点我干啥");
        } // 定义回调函数
    </script>
    <button onclick="alertSth()">点我试试</button>
    <!--通过onclick属性把alertSth()函数绑定到该按钮的点击事件上-->
</body>

事件例子:
1. 当用户点击鼠标时
2. 当网页已加载时
3. 当图像已加载时
4. 当鼠标移动到元素上时
5. 当输入字段被改变时
6. 当提交 HTML 表单时
7. 当用户触发按键时

HTML事件属性
<button onclick="displayDate()">Click here!</button>//向 button 元素分配 onclick 事件,名为 displayDate 的函数将在按钮被点击时执行。
使用HTML DOM来分配事件
<script>
    document.getElementById("myBtn").onclick=function(){displayDate()};//向 button 元素分配 onclick 事件,名为 displayDate 的函数被分配给 id="myBtn" 的 HTML 元素。按钮点击时Javascript函数将会被执行。
</script>
onload 和 onunload 事件

onloadonunload 事件会在用户进入或离开页面时被触发。
onload 事件可用于检测访问者的浏览器类型和浏览器版本,并基于这些信息来加载网页的正确版本。
onloadonunload 事件可用于处理 cookie

<body onload="checkCookies()">
<script>
function checkCookies(){
    if (navigator.cookieEnabled==true){
        alert("Cookies 可用")
    }
    else{
        alert("Cookies 不可用")
    }
}
</script>
<p>弹窗-提示浏览器 cookie 是否可用。</p>
</body>
onchange事件

onchange 事件常结合对输入字段的验证来使用。
如下,当用户改变输入字段的内容时,会调用 upperCase() 函数

<head>
<script>
        function myFunc(){
            var x=document.getElementById("t");
            x.value=x.value.toUpperCase();
        }
    </script>
</head>
<body>
    <input type="text" id="t" onchange="myFunc()" />//当你离开输入框后,函数将被触发,将小写字母转为大写字母。
</body>
onmouseover 和 onmouseout 事件

onmouseoveronmouseout 事件可用于在用户的鼠标移至 HTML 元素上方或移出元素时触发函数。

<head>
    <script>
        function mOver(obj){
            obj.innerHTML="Thank you!";
        }

        function mOut(obj){
            obj.innerHTML="Mouse over me";
        }
    </script>
</head>
<body>
    <div onmouseover="mOver(this)" onmouseout="mOut(this)" style="background-color:#d94a38;width:120px;height:20px;padding:40px;">Mouse over me</div>
</body>
onmousedown、onmouseup 以及 onclick 事件

onmousedown, onmouseup 以及onclick 构成了鼠标点击事件的所有部分。首先当点击鼠标按钮时,会触发 onmousedown 事件,当释放鼠标按钮时,会触发 onmouseup 事件,最后,当完成鼠标点击时,会触发 onclick 事件。

<head>
    <script>
        function OMD(obj){
            obj.innerHTML="Release me";
        }
        function OMU(obj){
            obj.innerHTML="Click me";
        }
    </script>
</head>
<body>
    <div id="d" onmousedown="OMD(this)" onmouseup="OMU(this)" style="background-color:#d94a38;width:120px;height:20px;padding:40px;">Oops</div>
</body>
DOM节点属性
getElementsByTagName()

返回带有指定标签名的节点对象的集合(数组)。返回元素的顺序是它们在文档中的顺序。

getElementsByName()

Name 是他的名字,可以重复。所以通过getElementsByName获取名字相同的人集合(数组)。

getAttribute()

通过元素节点的属性名称获取属性的值。

var node=document.getElementById("idName");
setAttribute()
var node=document.getElementById("idName");
node.setAttribute("属性",值);
DOM节点属性

DOM节点有三个属性
1. nodeName: 节点名称
2. nodeValue: 节点的值
3. nodeType: 节点类型

nodeName属性

节点的名称,只读
1. 元素节点的nodeName属性与标签名相同
2. 属性节点的nodeName是属性的名称
3. 文本节点的nodeName永远是#text
4. 文档节点的nodeName永远是#document

nodeValue属性

节点的值
1. 元素节点的nodeValue是undefined或null
2. 文本节点的nodeValue是文本自身
3. 属性节点的nodeValue是属性的值

nodeType属性

节点属性,只读。
常用节点类型

元素类型节点类型
元素1
属性2
文本3
注释8
文档9
访问子节点childNodes

访问选定元素节点下的所有子节点的列表,返回的值可以看作是一个数组,他具有length属性。

注意:如果选定的节点没有子节点,则该属性返回不包含节点的 NodeList。

var nodes=node.childNodes;
访问子节点的第一项firstChild

返回childNodes数组的第一个子节点

访问子节点的最后一项lastChild

返回childNodes数组的最后一个节点

插入节点appendChild()

在指定节点的最后一个子节点列表之后添加一个新的子节点。

<body>

<ul id="test">
  <li>JavaScript</li>
  <li>HTML</li>
</ul> 

<script type="text/javascript">

  var otest = document.getElementById("test");  
  var child=document.createElement("li");
  child.innerHTML="PHP";

  otest.appendChild(child);
</script> 

</body>
插入节点insertBefore()
parentNode.insertBefore(newnode,node);
删除节点removeChild()

removeChild() 方法从子节点列表中删除某个节点。如删除成功,此方法可返回被删除的节点,如失败,则返回 NULL。

parentNode.removeChild(node)
replaceChild()

replaceChild 实现子节点(对象)的替换。返回被替换对象的引用。

parentNode.replace(newnode,oldnode);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值