JavaScript 学习笔记(二)

JavaScript 学习笔记(二)

文章目录


相关链接:

前端精品课

学习笔记(一)

一 JSON

一般来说,网站的前端和后台使用不同的编程语言,前端最常用的语言有HTMLCSSJavaScriptJSP等,后台常用的语言有JavaPythonPHP等。前端和后台之间需要传递数据,不同语言的数据类型一般不同,这就需要一种大家都能接受的文本格式传递数据,JSON是一个很好的选择。

JSON的全称是JavaScript对象表示法(JavaScript Object Notation),是一种文本数据的交换格式,虽然JSON使用了JavaScript的语法,但是在很多语言里面都能使用JSON,比如JavaPHP,这也是它能被用来传递数据的原因。

1. JSON 对象

JSON常用的数据格式有JSON对象、JSON数组和JSON字符串。

什么是JSON对象

JSON对象(通常叫JSON)是一种文本数据的交换格式,用于存储和传输数据。示例如下:

{"name":"Jerry", "age":15}

这就是一个简单的json对象,它的规则是:

  • 数据以键/值对的形式存在;
  • 数据之间用逗号间隔;
  • 大括号表示保存对象;
  • 方括号表示保存数组。
JSON对象与Javascript对象的区别

在实训四里面,我们讲过JavaScript中的自定义对象。而JSON是基于JavaScript语法的,所以JSON中也有对象的概念,但是和JavaScript中的对象有一些小的区别。

定义一个JavaScript对象:

var myObject = {   
    id:1,   
    name:"Peter Bruce",
    "first name":"Bruce", 
    display:function() {   
        console.log(this.name);  
    }}

定义一个JSON对象:

{"id":1,"name":"Peter Bruce","first name":"Bruce"}

三点区别:

  • JSON对象的属性名(key)必须被包含在双引号之中,而JavaScript对象除了有空格的属性名、中间有连字符-的属性名必须在双引号之中外,其它随意;
  • 不能在JSON对象中定义方法,而在JavaScript对象中可以;
  • JSON对象可以被很多语言操作,而JavaScript对象只有JS自己可以识别。

定义JSON对象的方法如下:用一个{}包含在内,内部是若干个属性名和属性值构成的键值对,键值对之间用,隔开,属性名和属性值之间用:隔开,属性值可以是以下任意一种数据类型的数据:数字、字符串、JSON数组、JSON对象、null。如:

 {"a":1,"b":2.12,"c":true,"d":"string","e":null};

属性值是JSON数组或者JSON对象的情况稍复杂,后面的关卡将介绍。

在JavaScript中使用JSON对象

支持JSON的语言都能够使用JSON对象,这里仅介绍在JavaScript中如何使用JSON对象。

  • JavaScript中定义一个JSON对象:
var jsonObject = {"name":"js","number":2};
  • 操作属性,使用.或者[]

    console.log(jsonObject.name);//读属性,输出js
    console.log(jsonObject["name"]);//读属性,输出js
    jsonObject.name = "javascript";//写属性,给name属性赋值javascript
    
  • 删除属性,使用delete

    var jsonObject = {"name":"js","number":2};
    delete jsonObject.name;//删除name属性
    
  • 遍历属性,使用for-in循环:

    var jsonObject = {"name":"js","number":2};
    for(att in jsonObject) { 
        console.log(jsonObject[att]);//依次输出js、2
    }
    
2. JSON数组
JSON属性对应的值(value)是一个数组

JSON键值对中的值(value)可以是一个数组,比如:

{
    "country":"China",
    "population":"1.3billion",
    "bigCity":["Peking","Shanghai","ShenZhen","HongKong"]
}

属性bigCity的值有多个,放在一个数组里面。

上面例子里面,数组的每一个元素都是字符串。其实,数组的每一个元素还可以是另外一个json对象。比如:

{
    "class":"高三一班",
        "studentNumber":70,
            "score":[    {"name":"LiMing","score":128},   
                     {"name":"ZhangHua","score":134}, 
                     {"name":"ShenLu","score":112}]
}

上面的score属性的值是一个数组,这个数组的每一个元素是一个json对象。

数组的一些操作

读写元素:

var myJson = {
    "country":"China",
    "population":"1.3billion",
    "bigCity":["Peking","Shanghai","ShenZhen","HongKong"]
}
console.log(myJson.bigCity[1]);//打印出Shanghai
myJson.bigCity[0] = "GuangZhou";//第一个元素被赋值为GuangZhou

遍历:

var myJson = {
    "country":"China",
    "population":"1.3billion",
    "bigCity":["Peking","Shanghai","ShenZhen","HongKong"]
}
for(var i = 0;i < myJson.bigCity.length;i++) { 
    console.log(myJson.bigCity[i]);//依次输出Peking,Shanghai,ShenZhen,HongKong
}
3. JSON字符串

在前端和后台之间传递数据可以使用JSON,但是实际上传递的是JSON字符串,而JSON对象是不可以直接进行传递的。

JSON字符串

JSON字符串就是在JSON对象两边套上'形成的字符串,如:

var JSONObject  = {"k1":"v1","k2":"v2"};//JSON对象
var JSONString1 = '{"k1":"v1","k2":"v2"}';//JSON字符串

上面的JSONString1就是JSON字符串,可以直接从前端传到后台或者后台传到前端。

JavaScript收到从后台传来的JSON字符串后,怎么把它变成JSON对象方便处理呢?

JSON字符串到JavaScript对象

JSON.parse(a,b)方法将JSON字符串a转换为JavaScript对象。b是一个可选的函数参数。

var JSONString1 = '{"k1":"v1","k2":"v2"}';
console.log(JSON.parse(JSONString1));//输出Object {k1: "v1", k2: "v2"}

函数参数b按从里到外的顺序作用在对象的所有属性上,最后一个作用的是对象本身:

//对象的每一个属性的值加1
var text = '{ "key1":1, "key2":2, "key3":2.2}';
var obj = JSON.parse(text, function (key, value) {    
    if(key === '')//当遇到对象本身时,不进行加1操作
        return value;
    return value+1;//对属性值加1
});
console.log(obj);//输出Object {key1: 2, key2: 3, key3: 3.2}

如上面所示,函数的参数有两个,其中key表示属性的名字,value表示属性的值,当遇到对象本身时,key的值为'',即空字符串。

JSON对象转换为JSON字符串

JSON.stringify(a,b,c)a是待转换的JSON对象,bc为可选参数。

var JSONObject = {"k1":"v1","k2":"v2"};
JSON.stringify(JSONObject);//JSON对象转换为JSON字符串

参数b为函数时,该函数按照从里到外的顺序处理JSON对象的每一个属性,最后一个处理的是JSON对象本身,处理完后再转为JSON字符串:

//对象的所有属性值加1,再转为字符串
var JSONObject = {"k1":1,"k2":2.2};
var JSONString = JSON.stringify(JSONObject,function(k,v){  
    if(k === '')//处理到了JSON对象本身   
        return v;  
    return v+1;//所有的属性的值加1
});
console.log(JSONString);//输出{"k1":2,"k2":3.2}

参数b还可以是数组,数组存储的是属性的名字,用来指定只转换哪些属性:

//转换对象中特定的属性
var JSONObject = {"k1":1,"k2":2.2,"k3":3};
var JSONString = JSON.stringify(JSONObject,["k1","k2"]);
console.log(JSONString);//输出{"k1":1,"k2":2.2}

这里简单介绍一下c

var str = ["name":"Tom","age":16];
var obj1 = JSON.stringify(str);
var obj2 = JSON.stringify(str,null,4);
console.log(obj1);  //输出{"name":"Tom","age":16}
console.log(obj2); //输出//{//    "name": "Tom",//    "age": 16//}

参数c:文本添加缩进、空格和换行符,如果 c 是一个数字,则返回值文本在每个级别缩进指定数目的空格,如果 c 大于 10,则文本缩进 10 个空格。

二 常用类

1. Math类
常用的数

一些常用的无理数的表示方法:

表示意义约等于
Math.Ee2.718
Math.PI圆周率3.14
Math.SQRT22的平方根1.414
Math.LN22的自然对数0.693
console.log(Math.PI);//输出3.141592653589793
console.log(Math.pi == 3.141592653589793);//true
console.log(Math.pi == 3.14);//false
向上取整

Math.ceil(x)实现向上取整,返回大于等于x且离x最近的整数。

console.log(Math.ceil(1.1));//输出2
console.log(Math.ceil(1));//输出1
console.log(Math.ceil(-1.1));//输出-1
向下取整

Math.floor(x)返回小于等于x且离x最近的整数。

console.log(Math.floor(1.1));//输出1
console.log(Math.floor(1));//输出1
console.log(Math.floor(-1.1));//输出-2
随机数

Math.random()返回01之间的一个随机数,包含0不包含1

console.log(Math.random());//输出0.1493135392665863
平方根

Math.sqrt(x)返回x的平方根。

Math.sqrt(4);//2
Math.sqrt(2);//1.4142135623730951
四舍五入

Math.round(x)返回x四舍五入后的整数。

Math.round(1.5);//2
Math.round(1.49);//1
求最值

Math.max(x1,x2,....xn)返回参数的最大值,参数个数不限;

Math.max(1,2,34,100);//100
Math.max(-1,-2,-34,-100);//-1

Math.min(x1,x2,....xn)返回参数的最小值;

Math.min(1,2,34,100);//1
Math.min(-1,-2,-34,-100);//-100
其余方法

Math还有很多的方法,如下面的表格所示:

方法作用
Math.abs(x)求x的绝对值
Math.pow(x,y)计算x的y次幂
Math.exp(x)e的x次方
Math.log(x)x以e为底的对数
Math.sin(x)x的正弦
Math.cos(x)x的余弦
Math.tan(x)x的正切
Math.asin(x)x的反正弦
Math.acos(x)x的反余弦
Math.atan(x)x的反正切(-PI/2到PI/2之间)
Math.atan2(y,x)x轴到点(x,y)的角度 (-PI/2到PI/2之间)
2. Date类

Date类用于处理日期和时间。

构造函数

Date(x)的参数x可以有四种情况:

new Date();//无参数,返回当前时间
new Date(millseconds);//参数为距离1970年1月1日8时0分0秒0毫秒的毫秒数,返回对应的时间
new Date(timeString);//参数为时间字符串,返回这个时间字符串对应的时间
new Date(year,month,day,hour,minute,second,millsecond);//参数为整数序列,分别表示年、月、日、时、分、秒、毫秒,返回这些时间参数对应的一个特定的时间

以上均返回一个对应的时间对象,如下:

console.log(new Date());//输出Sat Apr 07 2018 18:56:00 
console.log(new Date(1000));//输出Thu Jan 01 1970 08:00:01
console.log(new Date("April 7, 2018 18:00:00"));//输出Sat Apr 07 2018 18:00:00
console.log(new Date(2018,4,7,18,0,0,0));//输出Mon May 07 2018 18:00:00

时间对象有一系列获取和设置年、月、日、时、分、秒、毫秒的函数。

获取和设置年月日

为举例方便,我们先定义一个时间。

//1970年1月1日上午8点0分0秒
var date = new Date(0);
  • x.getFullYear()返回x对应的四位数年份,xDate类对象;
console.log(date.getFullYear());//输出1970
  • setFullYear(year,month,day)用于设置年份,monthday可选;
date.setFullYear(2017);
console.log(date);//输出Sun Jan 01 2017 08:00:00
  • x.getMonth()返回x中的月份,结果在0(一月)到11(十二月)之间;
console.log(date.getMonth());//输出0
  • setMonth(month,day)作用是设置月份,0表示一月。1表示二月,依次类推,day可选;
date.setMonth(2);console.log(date);//输出Sun Mar 01 1970 08:00:00
  • x.getDate()返回x对象在一个月的第几天(131),x.getDay()返回x对象在一个星期的第几天(06,0为周日);
console.log(date.getDate());//输出1
console.log(date.getDay());//输出4

由此可见,197011号那个美好的新年第一天是个周四。

  • setDate(day)设置日期对象在一个月的第几天(131);
date.setDate(31);
console.log(date.getDate());//输出31
获取和设置时分秒

获取和设置时、分、秒、毫秒的函数在形式上与上面的函数几乎相同,这里以表格的形式列出:

方法作用参数或者结果的范围
getHours()获取小时0~23
setHours(hour,min,sec,millsec)设置小时023、059、059、0999
getMinutes()获取分钟0~59
setMinutes(min,sec,millsec)设置分钟059、059、0~999
getSeconds()获取秒钟0~59
setSeconds(sec,millsec)设置秒钟059、0999
getMillSeconds()获取毫秒数0~999
setMillSeconds(millsec)设置毫秒数0~999
getTime()获取距1970年1月1日8时0分0秒的毫秒数大于等于0
setTime(millsec)设置距1970年1月1日8时0分0秒的毫秒数大于等于0

注:以上多个参数的函数,除了第一个参数外的参数都为可选。

日期转字符串

toString()将日期转字符串,结果类似于Sun Jan 07 2018 20:01:14 GMT+0800 (中国标准时间),分别表示星期、月份、天数、年份、小时、分钟、秒和时区(中国采用东八区时间)。

console.log(new Date().toString());//输出Sat Apr 07 2018 20:40:14 GMT+0800 中国标准
3. 异常处理类
try-catch捕获和处理错误

用法如下:

try {  
    //运行时可能出错的代码
}catch(err) {  
    //处理出现的错误
}

JavaScript在运行时抛出的错误或者异常,会被catch语句捕捉到,其中的变量err包含了错误的有关信息。

try {   
    console.lo("JavaScript");
}catch(err) { 
    window.alert("发生错误,错误信息:"+err.message);
}
console.log("错误已处理完毕。");

第二句有语法错误,被catch捕捉到,错误信息console.lo is not a function通过js弹窗告知用户。用户点击弹窗上的确定后,程序继续往下运行。

如果没有进行错误处理,程序在第二句停止运行,这样后面的所有代码都不再执行。

创建自定义错误

console.lo is not a function显然是一个系统内置的错误类型,如果用户觉得这样的错误类型不够具体,可以自定义错误类型:

throw exception;

exception可以是字符串、数字、逻辑值或者对象,这样的错误也会被catch语句块捕获。

//求开方的值
function mySqrt(a) { 
    try {      
        if(a < 0)  
            throw new Error("错误!负数不能开平方");
        if(a > 10000)       
            throw new Error("错误!不支持大数开平方");        
        return Math.sqrt(a);   
    } catch(err) {   
        console.log("发生错误,错误信息:"+err.message);  
    }  
    return "error";
}

new Error()是一个Error对象,括号内的参数是err.message属性的值。

三 DOM文档操作

JavaScript的动态网页开发功能

什么是DOM

Document Object Module,简称DOM,中文名文档对象模型。在网页上,组成页面(又叫文档)的一个个对象被组织在树形结构中,用这种结构表示它们之间的层次关系,表示文档中对象的标准模型就称为DOM

DOM的作用是给HTML文档提供一个标准的树状模型,这样开发人员就能够通过DOM提供的接口去操作HTML里面的元素。

文档元素

先看一段网页代码:

<html>  
    <head>    
        <title>这里是标题</title> 
    </head> 
    <body>    
        <p>这是我学习JavaScript的网址:</p> 
        <a href="https://www.educoder.net/paths">JavaScript学习手册</a>   
    </body>
</html>

执行后效果如下:

img

文档元素:指的就是<html><head>等等这样一个个的标签和里面的内容

比如文档元素<title>就是这样:

<title>这里是标题</title>

JavaScript中,元素<title>对应一个对象,这个对象有一个属性的值是“这里是标题”。

所以,用JS操作这些文档元素,操作的就是它们对应的JS对象。

节点树

从代码的缩进可以知道,文档元素之间有层次关系,如下:

img

上面的图和数据结构中树的概念类似,被称为节点树<html>是根节点,网页的所有文档元素都在里面,<head><body>是两个子节点,分别存储网页标题有关内容和网页的主体部分。

JavaScript要操作这些元素,第一步自然是获得这些元素对应的JavaScript对象,那么,怎么获取呢?

1. 获取文档元素
通过id获取文档元素

文档元素一般都有一个id属性,它的值在本文档中唯一,如下:

<p id="myId">这是我学习JavaScript的网址:</p>

用这个id获取<p>元素的方法如下:

var pElement = document.getElementById("myId");

其中document表示整个文档,getElementById()document对象的一个方法,参数是id属性的值myId

获取的pElement就代表了<p>标签以及里面的内容,接下来,可以通过pElement操作这个元素。比如可以用弹框展示一下<p>标签里面的内容:

window.alert(pElement.innerText);

除了id以外,文档元素另外一个常见的属性是类名。

通过类名获取文档元素

文档元素的类名不唯一(存在多个文档元素的类名相同的情况),如下:

<p class="myName">段落</p>
<a class="myName" href="https://www.educoder.net">这是一个链接</a>

documentgetElementsByClassName()方法用来获取指定类名的文档元素数组NodeList,一般叫节点列表),如下:

var myNodeList = document.getElementsByClassName("myName");

这样,myNodeList[0]就是<p>元素,而myNodeList[1]就是<a>元素,通过这个方法的名字我们也可以知道获取的标签不唯一。

我们以弹框的形式查看一下<p>里面的内容:

window.alert(myNodeList[0].innerText);

效果如下:

img

通过标签的名字获取文档元素

标签名指的是<>里面的字符串,document对象的getElementsByTagName()获取整个文档中指定名字的所有标签,显然,结果是一个文档元素数组(节点列表),方法的名字也暗示了这一点。

<div id="div1">   
    <p id="p1">文本1</p>   
    <p id="p2">文本2</p> 
    <a name="a1">链接</a>
</div><div id="div2">
    <p id="p3" name="a1">文本3</p>
</div>

获取所有的<div>元素,如下:

var allDiv = document.getElementsByTagName("div");

为了显示效果,我们以页面弹框的形式展示第一个<div>里面的内容:

window.alert(allDiv[0]);

效果如下:

img

这个弹框表明,我们试图弹出的内容是一个div元素。

获取标签内部的子元素

我们获取到的文档元素,也有getElementsByTagName()方法,作用是获取该元素内部指定名字的所有子元素。比如,要获取第一个<div>里面所有的<a>元素,代码如下:

//变量allDiv上面有,这里不再重复!
var allLink = allDiv[0].getElementsByTagName("a");

这样就获取了第一个<div>里面的所有超链接元素。

2. HTML5中获取元素方法
css选择器

css选择器是干什么用的?简单来说,选择你想要的元素的样式。

这一块的内容对于没有学习过css的同学来说比较难,我们分三步来理解:

第一步:先看一段html代码:

<body>
    <p>
        CSS选择器 
    </p>
</body>

运行的效果如下:

img

第二步:我们想把字体改为红色,需要使用css来处理,假设我们已经有了一段css代码:

.css1{
    color:red;
}
#css2{ 
    color:blue;
}

前四行是一个名字为css1选择器,它是一种类选择器;后四行是一个名字为css2选择器,它是一种id选择器

第三步:有了css,我们还要把它和html关联起来,比如我们想在p元素上使用第一个选择器,反过来说:就是第一个选择器选择p元素(将它的样式应用在p元素上)。那么给p元素新增一个class属性,它的值是css1

<body>    <p class="css1">        CSS选择器    </p></body>

再来看一下效果:

img

这样p元素就选择了名字为css1的样式(反过来说也行),如果p元素要选择名为css2的样式,因为css2id选择器,需要设置id属性的值为css2

<body>    <p id="css2">        CSS选择器    </p></body>

效果如下:

img

querySelector

querySelector返回匹配指定css选择器的第一个元素。

以上面的html代码作为例子,比如我们想要获得class="css1"的元素:

css1是一个类选择器,在css代码里面的完整表示为.css1,那么这个.css1直接作为querySelector的参数,即可获得class="css1"的元素:

var myElement =  document.querySelector(".css1");
console.log(myElement.innerText);//输出“CSS选择器”

总结一下就是:用css选择器的完整名字作为querySelector的参数,就可以获取该选择器控制的所有元素。

需要注意的是,querySelector只返回一个元素,如果指定的选择器控制的元素有多个,返回第一个,下面是一个例子:

先看一段html代码:

<body>  
    <div class="myClass">文本1</div>
    <div class="myClass">文本2</div>  
    <div class="myClass">文本3</div>
</body>

显然,类名为myClassdiv元素有3个,使用querySelector在控制台输出类名为myClass的元素,看能输出几个:

var myClassElement = document.querySelector(".myClass");
console.log(myClassElement);

F12查看一下浏览器的控制台,效果如下:

img

很明显,querySelector方法只能获得第一个类名为myClass的元素。

querySelector只能获得第一个符合要求的文档元素,显然,我们需要一个能获取所有符合要求的文档元素的方法,querySelectorAll就是负责这项工作的。

querySelectorAll

如果一个选择器控制的元素有多个,而且我们需要取到这些元素,就需要用querySelectorAll方法,该方法返回指定的选择器对应的多个元素。

3.节点操作
节点树的有关概念

回顾一下前面出现过的这张图:

img

定义几个概念:

  • 父节点:逆着箭头方向的第一个节点,即为该节点的父节点;
  • 子节点:顺着箭头方向第一层的若干个结点,一般不唯一,即为该节点的的子节点;
  • 兄弟节点:父节点相同的节点互为兄弟节点;
  • 第一个子节点:子节点中最左边的节点;
  • 最后一个子节点:子节点中最右侧的节点;
  • 节点类型,值为9时表示Document节点(整个文档);值为1表示Element节点,即前面反复提到的文档元素;值为3表示Text节点,即节点里面的内容为纯文本,如<p>节点。
顺着节点树获取文档元素

先给一段html代码:

<body>
    <div id="div1">   
    <div class="cl1">    
        <p>文本</p>     
        <a>超链接</a>    
    </div>   
    <div class="cl2">   
        <select id="se">  
            <option>红</option>  
            <option>黄</option>  
            <option>蓝</option>  
        </select>   
    </div>
    </div>
</body>

首先,我们获取最外层的div节点:

var div1 = document.getElementById("div1");

然后获取它的第一个子节点(class值为cl1的节点):

//firstElementChild表示第一个子节点
var cl1 = div1.firstElementChild;

再获取cl1的最后一个子节点,即a节点:

//lastElementChild表示最后一个子节点
var aElement = cl1.lastElementChild;

在控制台打印出获取到的节点里面的文本:

console.log(aElement.innerText);

img

通过这个例子可以看出,我们的思路是顺着这个节点树从根部一直往下找,即顺着箭头的方向直到目标节点。

其他一些属性
前一个兄弟节点

previousElementSibling表示前一个兄弟节点。比如获取上面的超链接的前一个节点p,然后在控制台打印p的内容,代码以及效果如下:

var left = aElement.previousElementSibling;
console.log(left.innerText);

img

后一个兄弟节点

nextElementSibling表示后一个兄弟节点。显然,上面的p元素的后一个兄弟节点是a元素,打印一下a的内容:

var right = left.nextElementSibling;
console.log(right.innerText);

img

子节点列表: children

children[0]表示第一个子节点,以此类推。比如依次在控制台打印出上面的select标签的三个子节点:

var selectTag = document.getElementById("se");
console.log(selectTag.children[0].innerText);
console.log(selectTag.children[1].innerText);
console.log(selectTag.children[2].innerText);

效果如下:

img

children.length:子节点的个数;

console.log(selectTag.children.length);//输出3
4.属性值操作
获取文档元素的属性

通过前面的学习,我们可以发现,文档元素后面都会跟着相应的属性,比如<a>后面都会有一个href属性,用来表示超链接的地址,即点击这个超链接后跳往的目标页的地址。

怎么获取属性值呢?先看一段html代码:

<a href="https://www.educoder.net" target="_blank">EduCoder</a>

先获取文档元素:

var aElement = document.getElementsByTagName("a").[0];

然后通过获取到的元素的属性名来得到属性值:

var hrefValue = aElement.href;console.log(hrefValue);//输出https://www.educoder.net

从上面可以看出,文档元素.属性名即获得了该属性的值。

getAttribute()

getAttribute(a)用来获取属性值,a表示属性的名字。比如上面获取超链接的href属性值,也可以这样写:

console.log(aElement.getAttribute("href"));//输出https://www.educoder.net

区别是:getAttribute()返回的值统一为字符串,而第一种方法会返回属性实际的值,比如<input>maxLength属性的值应该是数值,第一种方法就会返回数值,getAttribute()返回了字符串:

<input type="name" maxLength=16 id="inputId"/>
//typeof检测变量的类型
var result1 = document.getElementById("inputId").maxLength;//返回16
var result2 = document.getElementById("inputId").getAttribute("maxLength");//返回"16"
console.log(typeof(result1));//输出number
console.log(typeof(result2));//输出string
特别提醒

class等文档元素的属性,不能直接用文档元素对象.class来获取,因为classJavaScript中的关键字,需要用className来代替。

但是,如果用的是getAttribute(),直接用class作为参数就行。

<a class="aClass" id="aId">超链接</a>
document.getElementById("aId").className;//返回"aClass"
document.getElementById("aId").getAttribute("class");//返回"aClass"

文档元素属性的值,除了可以获取外,当然也可以设置。设置属性的值也有两种方法。

直接设置

=连接,左边是你要设置的属性变量,右边是你要赋予这个属性的具体的值。比如:

<a id="a1" href="https://www.google.com">EduCoder</a>

设置超链接的href属性的值的表达式如下:

document.getElementById("a1").href="https://www.educoder.net";

这样,a标签的href属性的值就变成了https://www.educoder.net

需要注意:标签之间的文本用innerText属性表示,要修改上面超链接里面的文本,需要这样:

document.getElementById("a1").innerText="educoder";
setAttribute()

没错,setAttribute(a,b)就是一个与getAttribute()对应的方法,参数a是你要设置的属性的名字,参数b是你要设置的属性的值。

所以上面的操作(设置href)也可以这样写:

document.getElementById("a1").setAttribute("href","https://www.educoder.net");
5.节点增删替
创建节点

document.createElement("tagName")用来创建一个新的Element节点(即文档元素),返回值是新创建的节点,tagName是标签的名字,比如apimg等,需要注意的是它不区分大小写。

比如创建一个新的超链接节点:

var newA = document.createElement("a");//创建超链接节点
newA.src = "https://www.educoder.net";//设置超链接的目的地址

ul标签在html中表示无序列表,li标签标识其中的列表项。

插入节点

插入节点:插入一个新的文档元素。最常见的应用就是在<select>标签里插入一个新的<option>标签。

两种可选的方法:

方法1appendChild()

node1.appendChild(node2)表示将node2插入到node1的最后一个子节点中。

比如原来的选择框是这样:

<select id="s1">   
    <option id="cs">长沙</option>
    <option id="zz">株洲</option>
</select>

要增加多一个选项“湘潭”,实现代码如下:

var node1 = document.getElementById("s1");
var node2 = document.createElement("option");
node2.innerText = "湘潭";
node1.appendChild(node2);
方法2 insertBefore()

pNode.insertBefore(node1,node2):将node1插入作为pNode的子节点,并且node1排在已存在的子节点node2前面

比如要把最开始的复选框变成这样:

<select id="s1">  
    <option id="cs">长沙</option>  
    <option>湘潭</option>  
    <option id="zz">株洲</option>
</select>

我们需要像下面这样操作节点:

var pNode = document.getElementById("s1");
var node1 = document.createElement("option");
node1.innerText = "湘潭";
var node2 = document.getElementById("zz");//将内容为"湘潭"的节点插入到内容为"株洲"的节点前面
pNode.insertBefore(node1,node2);
删除节点

删除节点的方法是removeChild(),调用者是父节点,参数是子节点,作用是删除这个子节点。

第一步:获取父节点,即ul节点:

var parentNode = document.getElementById("parent");

第二步:获取待删除的子结点:

var childNode = document.getElementById("child3");

第三步:父节点调用removeChild()方法删除子节点:

parentNode.removeChild(childNode);
替换节点

replaceChild(a,b)的调用者是要被替换的节点的父节点,a是新的节点,b是被替换的节点。

第一步,获取父节点:

var parNode = document.getElementById("parent");

第二步,获取要被替换的子节点:

var oldNode = document.getElementById("child3");

第三步,创建新节点:

var newChild = document.createElement("li");newChild.innerText = "武夷山";

第四步,替换:

parNode.replaceChild(newChild,oldNode);

四 事件处理

1. 注册事件

页面上的每一个元素,会发生几种不同的事件,比如表单元素,可能会发生提交事件,也可能发生重置事件,我们需要为每一个事件绑定一个事件处理程序,也叫为事件注册事件处理程序。

下面是三种注册事件处理程序的方法。

为JavaScript对象设置一个函数

页面上的元素对应一个JavaScript对象,元素的每一个事件对应对象的一个属性,比如:

<form id="myForm"></form>
var myForm = document.getElementById("myForm");

myForm对应页面中id值为myForm的表单,myForm.onsubmit对应表单提交事件,myForm.onreset对应表单重置事件。通过为这些属性设置一个函数类型的值,实现事件处理程序的注册:

//为表单提交事件注册处理程序
myForm.onsubmit = function() {    
    console.log("表单提交的事件处理程序");
}
//为表单重置事件注册处理程序
myForm.onreset = function() { 
    console.log("表单重置的事件处理程序");
}
设置HTML标签属性的值为事件处理程序

比如,设置form标签的onsubmit属性的值为事件处理程序:

<form οnsubmit="submitForm()"></form>
function submitForm() {    console.log("表单提交的事件处理程序");}

这样提交表单时,就会触发submitForm()函数。

调用addEventListener()函数

页面元素对应的JS对象,通过调用addEventListener()函数也可以注册事件处理程序,函数的第一个参数是事件的类型,第二个参数是事件处理程序:

<form id="myForm"></form>
var myForm = document.getElementById("myForm");
myForm.addEventListener("submit",function() {  
    console.log("表单提交中");});

submit表示这是一个表单提交事件,后面的匿名函数即表单提交的事件处理程序。

2.文档加载事件

文档,指的是网页上的所有元素构成的一种格式化文本。文档加载事件指浏览器从服务器下载并渲染完文档后发生的事件。

文档加载事件名字为load

当文档加载完成后,就会触发文档加载事件监听程序(即上一关所说的事件处理程序),一般我们会在这个时候监测用户浏览器的类型、版本,从而加载不同的脚本。

在大多数情况下,文档记载事件绑定在body元素上,表示网页主体加载完成后触发该事件,也有少数情况下绑定在image等元素上,表示相关的元素加载完成后触发该事件。

文档加载完成后监测用户的浏览器类型并在控制台打印:

<body οnlοad="detectBrowser()"></body>
function detectBrowser(){   
var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串  
    if (userAgent.indexOf("Opera") > -1) {//判断是否是Opera浏览器 
        console.log("Opera"); 
    };  
    if (userAgent.indexOf("Firefox") > -1) { //判断是否是Firefox浏览器        
        console.log("Firefox");
    }
    if (userAgent.indexOf("Chrome") > -1) { //判断是否是Chrome浏览器    
        console.log("Chrome"); 
    }   
    if (userAgent.indexOf("Safari") > -1) {//判断是否是Safari浏览器    
        console.log("Safari");   
    }    
    if (userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1) {   
        console.log("IE"); 
    };
}
3. 鼠标事件
常见的鼠标事件

说到鼠标事件,最常见的无非是鼠标单击事件click,很多按钮都会绑定一个onclick()函数,表示当用户单击鼠标后会执行的函数。其实还有很多鼠标事件,比如双击鼠标、按下鼠标等,下面是一个总结:

类型事件处理函数触发条件
clickonclick按下并且释放鼠标
dbclickondbclick双击鼠标
mousedownonmousedown按下鼠标按键
mouseuponmouseup释放鼠标按键
mousemoveonmousemove移动鼠标
mouseoveronmouseover鼠标进入元素
mouseoutonmouseout鼠标离开元素

为页面上的某一个元素绑定一个鼠标事件,当用户在该元素上用鼠标执行了指定的动作后,就会触发指定的鼠标事件处理程序,开始执行函数。

鼠标的按下和释放

mousedowm表示鼠标按下的事件,onmousedown是用户按下鼠标后会触发的事件处理程序;mouseup表示鼠标按键释放的事件,onmouseup表示用户释放鼠标按键后会触发的事件处理函数。

下面是一个例子,页面上有一行文字“点我”,用户在文字上按下鼠标按键后,文字会变成“鼠标已经按下”,而用户释放鼠标后,文字会变成“鼠标已经释放”。

html代码如下:

<body>    
    <p id="p" οnmοusedοwn="downfunc()" οnmοuseup="upfunc()">  
        点我 
    </p>
</body>

页面的效果如下:

img

事件处理函数的代码如下:

function downfunc() {  
    document.getElementById("p").innerText = "鼠标已经按下";
}
function upfunc() {   
    document.getElementById("p").innerText = "鼠标已经释放";
}

用户在文字上面先按下鼠标,再释放鼠标,效果如下:

img

4.键盘事件

键盘事件,是指用户敲击键盘上的按键所代表的事件。

键盘事件有三种:

  • 按键按下:keydown,用户按下键盘上的键;
  • 按键释放:keyup,用户释放按键;
  • 点击按键:keypress,用户按下并且释放了按键。
点击按键

keypress表示用户点击某个按键的事件,该事件会触发onkeypress()事件处理程序,onkeypress()有一个event参数,其中event.which表示点击的按键的编码。这个编码是该按键的unicode编码。

需要注意的是,按下键盘上的A时,keyCode值是a的编码,只有同时按下shiftAkeyCode的值才是A的编码。

下面是一个例子,当用户点击键盘上的按键时,会打印出该按键的编码值:

<body οnkeypress="keyEvent(event)">
    <p>     
        keypress event  
    </p>
</body>
<script>  
    function keyEvent(event) {  //如果按下"B",编码是;98(int)
        console.log("编码是:"+event.which);
    }
</script>
按下按键

keydown表示用户按下按键,同上面一样,它也有一个event.which表示按下的按键的编码。

<body οnkeydοwn="downEvent(event)"></body>
<script> 
    function downEvent(event) {   
        console.log("编码是:"+event.which);   
    }
</script>

如果你按下按键后没有释放,控制台将会一直进行打印,比如按下的是1,控制台的打印结果如下:

img

灰色的数字20表示这条信息已经打印了20次。

释放按键

keyup表示用户释放按键,可以有一个参数eventevent.which表示释放的按键的编码。

<body οnkeyup="upEvent(event)"></body>
<script>   
    function upEvent(event) {   
        console.log("编码是:"+event.which); 
    }
</script>

比如,当用户按下1时,控制台没有输出,释放1后,控制台输出如下:

img

5. 表单事件

表单,即form,是页面最基本的元素之一,通常,用户的输入会放置在表单里面,然后提交给后台。

form有很多子元素,分别表示不同类型的用户输入:例如input表示文本等类型;select表示下拉列表;button表示按钮。

这些子元素可以被绑定一些事件,比如change表示用户的输入发生了改变。这些事件是表单元素特有的。

change事件

change事件表示当前元素失去焦点并且元素的内容发生了改变。失去焦点,指光标不在该元素上,比如光标本来在文本输入框里面,当用户在页面的其他地方点击了鼠标,文本框就会失去焦点。

下面是一个例子:当用户输入文本,并且鼠标点击页面上的其他地方后,我们将在控制台打印出用户的输入。

<body>   
    <form>   
        <input id="t1" type="text" οnchange="changeEve()"/>  
    </form>
    <script>     
        function changeEve() {     
            var e = document.getElementById("t1");    
            console.log(e.value);
        }
    </script>
</body>

比如当用户输入I changed后,在页面的其他地方点击鼠标,控制台如下:

img

select事件

select事件:文本框中的文本被用户选中时发生。

只能作用在<input type="text">的文本框里面,可以用window.getSelection().toString()获取选择的文本。

下面的例子:当用户选择了一段文本后,我们在控制台打印出用户选择的文本:

<body>    
    <input type="text" value="赵钱孙李,周吴郑王" οnselect="selectEve()"/> 
    <script>
        function selectEve() {  
            console.log(window.getSelection().toString()); 
        }    
    </script>
</body>

比如我们选择了郑王,然后松开鼠标,控制台的输出如下:

img

submit事件

表单的提交事件。

表单里面包含了用户输入的信息,最终要传到后台的服务器进行处理,这样就有一个表单的提交过程,submit即表单提交事件。

通常情况下,在submit的事件处理函数中,校验用户的输入是否符合要求,比如密码的长度够不够。

下面的例子,用户提交表单时,用js校验用户输入的密码长度是否达到6位。

<body>   
    <form οnsubmit="subEve()">
        <input type="password" id="pw"/>
        <input type="submit" value="提交" /> 
    </form>  
    <script>  
        function subEve() {   
            var content = document.getElementById("pw").value;
            if (content.length < 6) {   
                window.alert("密码不可以小于6位");  
            } 
        }   
    </script>
</body>

这时,用户在密码输入框输入123,点击提交,页面会弹出一个警告框如下:

img

6.拖动事件
元素的拖放

鼠标指向元素,按下鼠标,然后移动鼠标到另一个地方释放,即拖动元素。

相比html4以及之前的版本,html5增加了一个全新的属性draggable,表示元素是否支持拖动,默认的情况下,图片和超链接元素是支持拖动的,其他元素不支持。

将元素的draggable属性设置为true,即表示元素支持拖动。如:下面设置了p元素支持拖动:

<p id="p1" draggable="true">    元素支持鼠标的拖动</p>

也可以用下面的JavaScript代码设置p为可拖动的:

document.getElementById("p1").draggable = true;
ondrag

ondrag()是元素正在拖动时触发的事件处理程序。如果元素一直在拖动的过程中,ondrag()会每隔350ms被触发一次,比如,在下面的例子中,我们一直在拖动p元素,控制台会一直打印拖动的信息。

<body>   
    <div>     
        <p οndrag="dragging(event)" draggable="true">拖动我!</p> 
    </div>  
    <script> 
        function dragging(event) {  
            console.log("正在拖动");  
        }    
    </script>
</body>
ondragstart

用户开始拖动元素时触发,可以带有一个event参数,其中的event.target表示拖动的元素,比如,下面的例子中,用户开始拖动元素时,触发了ondragstart程序,我们尝试打印一下event.target的内容:

<body> 
    <p οndragstart="dragStart(event)"  draggable="true">拖动我!</p>  
    <script>   
        function dragStart(event) { 
            console.log(event.target);          
            console.log("你要拖动的文本的内容是:"+event.target.innerText);      
        }  
    </script>
</body>

拖动文本,效果如下:

img

第一行是要拖动的文本元素,第二行显示了文本里面的内容。

7.冒泡事件
文档树

在前面的学习中,我们说过,文档元素之间有层次关系,比如:

<body>  
    <div οnclick="clickParent()">   
        <p οnclick="clickChild()">点我</p> 
        <p id="p">content</p>  
    </div>   
    <script>  
        function clickChild() {    
            console.log("子"); 
        }      
        function clickParent() {     
            console.log("父");   
        }
    </script>
</body>

对应这样一个模型:

img

其中,箭头的方向是子节点的方向,而反过来则是父节点的方向。比如,两个p元素的父节点(父元素)都是div元素。

事件冒泡

在上面的例子中,点击p元素里面的内容,显然会触发p元素的事件处理程序clickChild。然后,因为p元素是放在div里面的,点击p元素相当于点击了div元素,会触发div的事件处理程序clickParent,这个过程被称为事件冒泡

事件冒泡是指,某个事件触发了某个元素的事件处理程序,接下来,就会自动沿着节点树往根节点的方向依次触发经过的路径上的所有元素的某个事件的处理程序。

比如上面的例子中,用鼠标点击p标签里面的文字点我,控制台的打印结果为: “子 父”。

第一行是子元素的click事件的事件处理程序的输出,第二行是父元素的,这里有一个先后的顺序,即从子元素一直到根节点。

事件冒泡的控制

事件冒泡不是所有的时候都受到欢迎,有的时候需要控制它的发生,使用event.stopPropagation()即可。

比如,对于上面的例子,我们在子元素的事件处理程序clickChild()的最后一行添加一行代码:

function clickChild() { 
    console.log("子"); 
    window.event?window.event.cancelBubble=true:event.stopPropagation(); 
}

这个时候再次点击p里面的内容,控制台的输出: “子”。

五 浏览器对象模型

1. 定时器

JavaScript中定时器的作用是在指定的时间或者时间间隔之后执行函数,可以用来对网页上的数据做实时的更新,比如网页上的北京时间的更新:

定时器的实现有两种方式,一个是window.setTimeout()函数,一个是window.setInterval()函数。

设置定时器1

window.setTimeout(a,b)用来指定函数a在延迟b毫秒时间后执行,即在window.setTimeout(a,b)这句话开始执行的b毫秒之后,再执行a函数。

比如下面的例子中,我们点击页面上的文字,经过4秒的延迟后弹出警告框:

<body> 
    <p οnclick="al()">    
        单击此处4秒后弹出警告框 
    </p>   
    <script>  
        var id; 
        function al() {  
            id = window.setTimeout(showAlert,4000); 
        }
        function showAlert() {     
            window.alert("警告框");  
        }
    </script>
</body>

点击文字会触发函数a1(),在这个函数里面设置了一个定时任务showAlert(),定时的时间为4秒之后。即:点击文字4秒之后会执行showAlert()函数。

取消定时器1

上面代码里的变量id是用来唯一标识这个定时任务的,它的作用是,作为函数window.clearTimeout(id)的参数,而这个函数是用来在定时任务发生之前关闭定时任务,这好比,早晨我们在闹钟响之前关掉闹钟。

设置定时器2

setInterval(a,b):每隔b毫秒,执行一次a函数。

下面的例子,每隔一秒钟,更新一下网页上的时间:

<body> 
    <p οnclick="updateTime()">        开始更新时间    </p> 
    <p id="timeContainer">    </p>   
    <script> 
        var id; 
        function updateTime() {
            id = window.setInterval(showTime,1000);  
        }    
        function showTime(){     
            document.getElementById("timeContainer").innerText = new Date();
        }
    </script>
</body>

点击“开始更新时间”,触发updateTime()函数,该函数开启一个循环定时任务showTime()showTime()的作用是更新网页上显示的时间。

取消定时器2

window.clearInterval(id)也是停止定时任务,其中的id就是上面例子里面的变量id,这个是为了唯一标识某一个定时任务,防止错误的取消了别的定时任务。

2.location对象

location对象就是window.location,记载了浏览器当前所在的窗口的URL(统一资源定位符)信息,它常常被用来实现网页的跳转。

页面的跳转

location.href属性表示当前窗口所在页面的地址。

#这个结果应当和浏览器地址栏上内容一样
<body>    <script>        console.log(window.location.href);    </script></body>

window.location.href还是可写的,如果把它设置为一个新的地址,当前窗口将立即打开这个新的地址,这是实现页面跳转的一种方式。比如下面的例子:

<body>   
    <p οnclick="toNew()">   
        点我调到EduCoder首页   
    </p>   
    <script>  
        function toNew() {       
            window.location.href = "https://www.educoder.net"; 
        } 
    </script>
</body>
location对象的其它属性

假设,当前浏览器地址栏的内容是:https://www.educoder.net:8080/shixun.html?tab=1。我们用一个表格看一下location对象的所有属性:

属性名解释属性的值
host主机名和端口号www.educoder.net:8080
hostname主机名www.educoder.net
pathname路径部分/shixun.html
port端口号8080
protocal协议https
search问号开始的查询部分?tab=1

以下用一个例子打印所有这些属性,假设我们在https://www.educoder.net:8080/shixun.html?tab=1这个页面:

<body οnlοad="printInfo()">  
    location attribute    
    <script>     
        function printInfo() {  
            var loc = window.location;     
            console.log("host:"+loc.host);    
            console.log("hostname:"+loc.hostname);   
            console.log("pathname:"+loc.pathname); 
            console.log("port:"+loc.port);      
            console.log("protocal:"+loc.protocal);   
            console.log("search:"+loc.search);      
        }   
    </script>
</body>

载入页面后,打印结果如下:

img

3.对话框

对话框就是在浏览器页面上再弹出一个小的窗口,用于和用户直接互动,window对象的alert()confirm()prompt()三个方法都是用来显示对话框的。

警告框

window.alert(msg)弹出一个警告框,表示向用户发送一条通知。前面的相关知识已经多次讲过alert()的用法。

需要注意的是,alert()方法弹出警告框后,其后的代码会暂停执行,直到警告框被关闭,即:alert()方法是阻塞的。

下面的例子中,关闭警告框后,控制台才会打印信息:

<body> 
    <p onclick="showAlert()">点我弹出警告框</p>
    <script>     
        function showAlert() {  
            window.alert("先弹出一个警告框");     
            console.log("然后才能在控制台打印信息");  
        }   
    </script>
</body>
确认框

window.confirm(msg)弹出一个确认框,msg是需要用户确认的信息,用户在弹出的框里面选择确认或者取消后,会返回true或者false

<body>   
    <p οnclick="showConfirm()">点我弹出确认框</p>  
    <script>    
        function showConfirm() {    
            var result = window.confirm("确定今天是周五?");   
            console.log(result);  
        } 
    </script>
</body>
输入框

window.prompt(a,b)弹出一个输入框,供用户输入关键信息。其中a是输入框的提示语,b是输入框里面默认的内容。

如果用户不输入,直接点击确认,返回b。如果点击取消,返回null

4. 窗口

浏览器的一个标签页叫做一个窗口,window对象可以操作浏览器窗口的打开与关闭。

打开浏览器的窗口

window.open(url,name,specs,replace)用来打开一个浏览器的窗口,它有四个参数:

url表示窗口里面的文档的地址;

name有两种情况。

如果name里面是窗口的名字。浏览器会先判断这个窗口是否已经打开。已经打开则用新的url里面的文档替换这个窗口里面原来的文档,反映到浏览器上是不会有新的标签页打开,但是一个已存在的标签页会刷新。没有打开则打开一个新的窗口,并且载入url里面的文档。

如果name_blank_self里面中的任何一个,它的含义如下:

含义
_blank打开新的窗口,载入地址为url的文档
_self不打开新的窗口,用地址为url的文档替换掉当前的文档

specs是用来控制新窗口的尺寸等特征,比如值为width=200,height=100时,表示新窗口宽度为200px,高度为100px

replace用来控制新的窗口在浏览器的浏览历史里面如何显示。为true表示装载到窗口的url替换掉浏览历史中的当前条目;为false表示装载到窗口的url创建一个新的条目。

下面的例子展示了这些参数的具体用法:

<body>  
    <p οnclick="openNewWindow()">name是一个窗口的名字,打开一个新的窗口,载入新的文档</p>   
    <p οnclick="openOldWindow()">name是一个窗口的名字,打开已存在的窗口,替换掉里面的文档</p>  
    <p οnclick="blankWindow()">name是一个target属性,值为_blank</p>   
    <p οnclick="selfWindow()">name是一个target属性,值为_self</p>   
    <script>      
        function openNewWindow() {  
            window.open("Demo1.html", "windowName");
        }    
        function openOldWindow() { 
            window.open("Demo2.html", "windowName"); 
        }     
        function blankWindow() {   
            window.open("Demo1.html", "_blank");
        }       
        function selfWindow() { 
            window.open("Demo1.html", "_self");  
        }   
    </script>
</body>

效果如下所示:

img

如上所示,第一种情况,name是一个窗口的名字,因为这个窗口还没有打开,所以会打开一个新的窗口,并载入url文档。

第二种情况,name是一个窗口的名字,因为这个窗口已打开,所以新的文档会替换掉原来的文档。

第三种情况,name值为_blank,会直接打开一个新的窗口。

第四种情况,name值为_self,会用url里面的文档替换掉当前窗口的文档,不会打开新的窗口。

关闭窗口

上面的window.open()会有一个返回值resultresult.close()用来关闭打开的窗口。比如下面的例子:

<body>  
    <p οnclick="openNewWindow()">打开新窗口</p>    
    <p οnclick="closeNewWindow()">关闭新窗口</p>  
    <script>     
        var w;      
        function openNewWindow() {     
            w = window.open("Demo1.html", "windowName");    
        }       
        function closeNewWindow() {  
            w.close();       
        }    
    </script>
</body>

功能实现

下拉列表的级联

相信大家都见过这样的下拉框:

img

它有三列,每一列都会根据前一列的结果动态的改变自己的可选项,称为下拉框的级联,那么如何实现呢?

第一步:静态的HTML的代码如下(简单起见,只考虑前两列):

<select id="province" onChange="changeCity()">   
    <option value="BeiJing" id="bj">北京</option> 
    <option value="AnHui" id="ah">安徽</option>
</select>
<select id="city"> 
    <option value="BeiJingCity">北京市</option>
</select>

select表示选择框,option表示选择框里面的每一个选项,onChange="changeCity()"表示一旦改变当前的选项,就会触发JavaScript函数changeCity()的执行。

对于这个静态的HTML页面,不论你在第一列选择的是北京还是安徽,第二列的选项都只有北京市一项。

第二步:获取两个选择框对应的节点元素 (以下的所有代码都是changeCity()函数里面的内容):

var province = document.getElementById("province");
var city = document.getElementById("city");

province变量代表第一列的选择框,city变量代表第二列的选择框。

第三步:清空第二列中的所有内容; 根据第一列的选择结果改变第二列的内容,就是根据父节点的不同替换不同的子节点,我们采用先删除后新增的方法实现替换:

var length = city.children.length;
for(var i = length-1;i >= 0;i--) {  
    city.removeChild(city.children[i]);
}

for循环里面,依次删除city节点下面的所有子节点。

需要注意的是,每删除一个子节点后,表示子节点个数的属性city.children.length都会自动减1,所以我们需要在for循环开始之前索取子节点的长度。

第四步:根据父节点的不同新增不同的子节点:

if(province.value == "BeiJing") {  
    var child1 = document.createElement("option");   
    child1.value ="BeiJingCity";   
    child1.innerText="北京市"  
    city.appendChild(child1);
} 
else {  
    var child1 = document.createElement("option"); 
    child1.value="HuangShanCity";   
    child1.innerText="黄山市"; 
    city.appendChild(child1);
}

province.value表示第一列选中的选项的值,即选中的option标签的value的值。

如果第一列选择的是北京,我们需要增加一个选项为北京市option节点,这个节点将作为city的子节点。如果第一列选择的是安徽,我们需要增加一个选项为黄山市option节点,这个节点将作为city的子节点。

value属性表示option标签的值,innerText表示option标签呈现出来的值。

<html>
<head>
<title>myTitle</title>
<meta charset="utf-8" />
</head>
<body>
<select id="province" onChange="changeCity()">
	<option value="BeiJing" id="bj">北京</option>
    <option value="AnHui" id="ah">安徽</option>
</select>
<select id="city">
    <option value="BeiJingCity">北京市</option>
</select>
<script>
function changeCity() {
    var province = document.getElementById("province");
    var city = document.getElementById("city");
    var length = city.children.length;
    for(var i = length-1;i >= 0;i--) {
        city.removeChild(city.children[i]);
    }
    if(province.value == "BeiJing") {
        var child1 = document.createElement("option");
        child1.value="BeiJingCity";
        child1.innerText="北京市"
        city.appendChild(child1);
    } else {
        var child1 = document.createElement("option");
        child1.value="HuangShanCity";
        child1.innerText="黄山市";
        city.appendChild(child1);
        var child2 = document.createElement("option");
        child2.value= "HeFeiCity";
        child2.innerText = "合肥市";
        city.appendChild(child2);
    }
}
</script>
</body>
</html>
点不到的按钮

主要知识点:鼠标事件+CSS绝对位置

在按钮上增加鼠标事件监听,否定代码的事件主要是点击之后更改为随机位置。

        <script>
            function clickYesButton (){
                 var but = document.getElementById("yes");	
				but.innerText = "就这么说定了";
            }
            function clickNoButton (){
                 var but = document.getElementById("no");	
				var ran1 = Math.random()*400+10;
				var ran2 = Math.random()*400+10;
                str = "position:absolute;top:"+ran1+"px;left:"+ran2+"px";
                but.style=str;
            }
            var yesButton = document.getElementById("yes");
            yesButton.addEventListener("click",clickYesButton);
            var noButton = document.getElementById("no");
            noButton.addEventListener("click",clickNoButton);
        </script>

其中HTML中按钮的声明为,注意其中的位置是“绝对的”。

	</div>
	<div  id="yes" align="center" style="position:absolute;top:40px;left:20px">
    		<button>接受</button>
	</div>
	<div  id="no" align="center" style="position:absolute;top:80px;left:20px">
    		<button>拒绝</button>
	</div>

在按钮上面随便提出一个问题,修改下文案,对方就不能够拒绝你啦~

效果如下:

点击前 点击前
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

如果皮卡会coding

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值