JavaScript
JavaScript
时弱类型,即变量类型可变
Java
是强类型,变量定义后类型不可变
script中文为脚本、写作,读音为skript
特点:
- 可以做信息交互
- 安全,不允许访问本地硬盘
- 跨平台性,只要可以解释JS的浏览器即可
与HTML结合
使用<script></script>
标签中写
-
alert();
中文为警告,是js提供的警告框函数,读音əˈlərt
-
<!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="UTF-8"> <title>标题</title> <link rel="stylesheet" href="css/1.css"> <script type="text/javascript"> alert("hello world"); </script> </head> <body> </body> </html>
引入方式
可以使用引入的方式把js标签引入,类似于引入CSS,使用src
属性
<script type="text/javascript" src="路径">
</script>
引入后,原有在script
标签中的语句无效
变量
类型
- 数值型
number
- 字符串类型
string
- 对象类型
object
- 布尔类型
boolean
- 函数类型
function
特殊的数值
undefined
,所有的js变量没有赋初值时,默认值都为undefined
null
,空值NAN
,全称为Not a Number
,非数值
定义格式
var 变量名;
var 变量名 = 值;
var i;
alert(i)
输出为undefined
使用typeof(变量名)
可以获取变量的类型
var a = "string";
var b = 1;
alert(a + b); //语法上允许
结果为NaN
运算符
关系运算符
-
==
,等于,仅限于字面值的比较-
var a = "12"; var b = 12; alert(a == b);//为true
-
-
===
,全等于,字面值、类型的比较-
var a = "12"; var b = 12; alert(a === b);//为false
-
-
!=
,不等于 -
> < >= <=
,基本运算符
逻辑运算符
- 且运算:
&&
- 或运算:
||
- 取反运算:
!
其中0
、null
、""
(空串)、undefined
默认都会认为是false
数字也可以作为boolean
进行比较,和C语言一样
&&
运算时,如果全为真时,返回第二个值
var a = "abcd";
var b = 1234;
alert(a && b);//结果为1234
如果全为假时,返回第一个为假的值
var a = "abcd";
var b = 0
var c = "pppp"
alert(a && b && c);//结果为0
数组
定义
var 数组名 = [];//空数组
var 数组名 = [值1, 值2, ...., 值n];
数组名.length;//获取数组长度
可以直接赋值,只要通过数组下标赋值,那么会自动扩容给数组
var arr = [];
arr[10] = "avvvv";
alert(arr.length);//数组大小为11
数组中可以放任意类型的值,即使类型不一致,与Python
的列表类似,在上例中,只给a[10]
赋值,那么a[0]
到a[9]
的值为undefined
数组的长度可以手动更改,例如a.length = 1000
var arr = [];
arr[10] = "avvvv";
alert(arr.length);
for (var i = 0; i < arr.length; i++) {
alert(arr[i]);
}
使用foreach(function{})
进行遍历
a = [3, 5, 6, 4, 6, 24, 52, 45, 245, 24, 4];
a.forEach(function(a) {
console.log(a);
});
也可以有多个参数,参数1为值,参数2为索引下标,参数3为整个数组
<script type="text/javascript">
a = [3, 5, 6, 4, 6, 24, 52, 45, 245, 24, 4];
a.forEach(function(value, index, arr) {
console.log(value + "," + index);
});
</script>
函数
有两种定义方式
函数可以嵌套函数
第一种
可以使用function
关键字定义
function 函数名(参数列表){
//函数体
}
参数列表不需要写var
function fun(a, b) {
alert("函数调用:" + (a + b))
}
fun(2, 3);
有返回值时,直接写return即可,无须指明返回值类型
function fun(a, b) {
return a + b;
}
alert(fun(2, 3))
第二种
调用方式,函数体内书写方式与第一种方式一致
var 函数名 = function(形参列表){
//函数体
}
JavaScript
中的函数不允许重载,重载会直接覆盖上一次的定义
函数也是一个对象!!!
第三种
<script type="text/javascript">
var fun = new Function("console.log('函数');\
for(var i = 0; i < 10; i++){\
console.log(i);\
}\
");
fun();
</script>
函数对象可以封装可执行的代码
隐形参数
函数的隐形参数,arguments
,argument中文为争论、论点、论据,读音为ˈärɡyəmənt
即不需要定义,可以直接获取所有参数的变量,类似于Java的可变形参
JavaScript
中的隐形参数也是一个数组,如果有参数列表,那么也会把相关的值放到arguments
中
function fun() {
alert("长度为:" + arguments.length);
var sum = 0;
for (var i = 0; i < arguments.length; i++) {
alert(arguments[i]);
sum += arguments[i];
}
return sum;
}
alert("和为" + fun(2, 3, 4, 5, 6))
立即执行函数
如果单独写一个
function(){
alert("这是一个立即执行函数");
}
是不对的,此时是匿名函数,没有能够调用这个函数的东西
如果加个括号
(function() {
alert("这是一个立即执行函数");
})
此时是正确的
如果想要直接的调用这个函数,可以从末尾再加个括号,此时函数会自动的调用,也就是定义完了之后会立即被调用,这类函数只会调用一次
(function() {
alert("这是一个立即执行函数")
})()
带有参数的
(function() {
for (var i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
})(3, 5, 6, 7, 3, 425, 42, 54, 524, 542542, 546, 654, 642, 65)
调用方式
以上三种调用方式效果相同
对象
"属性名" in 对象名
判断一个对象中是否有这个属性
自定义对象
对象名["属性名"]
也可以使用一个对象中的一个属性
var 变量名 = new Object();//对象实例,空对象
变量名.属性名 = 值;//定义一个属性
变量名.方法名 = function(){
//函数体
}//定义一个方法
方式2:字面量方式定义,格式
var 对象名 = {
属性名: 值,
属性名: 值
};
或者
var 对象名 = {
"属性名": 值,
"属性名": 值
};
例如
// 字面量方式定义,两种方式等价
var obj = {};
var ob = new Object();
console.log(obj);
console.log(ob);
var obj = {
age: 3,
name: "gogo"
};
对象名.函数名()
此时被称为方法
方法体内可以直接使用this
调用当前的相关属性和方法
var obj = new Object();
obj.name = "狗";
obj.fun = function () {
alert("名字:" + this.name);
}
obj.fun();
使用{}定义对象
var 变量名 = {
属性名:值,
方法名:function(){
}
}
访问方式都一样的
var obj = {
name: "狗",
fun: function () {
alert("名字:" + this.name);
}
}
obj.fun();
for ... in
可以遍历数组、对象
<script type="text/javascript">
var a = [33, 55, 6, 54, 35, 65];
for (var i in a) {
console.log(i);
}
var obj = {
name: "go",
age: 999,
sex: true,
len: 9993
}
for (var i in obj) {
console.log("属性名:" + i + ", 值:" + obj[i]);
}
</script>
this
以函数的形式调用某个函数,此时this
是window
以对象名.函数()
的形式调用,此时this
是当前调用的对象
<script type="text/javascript">
var fun = function() {
console.log("当前的this是" + this);
}
var obj = {
name: "go",
age: 999,
sex: true,
len: 9993,
fun: fun
}
obj.fun();
fun();
</script>
输出结果是
当前的this是[object Object]
当前的this是[object Window]
构造函数
执行流程:
new
之后,立即创建一个新的对象- 将新建的对象设置为函数中的
this
- 逐行执行函数中的代码
- 将新创建的对象作为返回值返回
function Person(name) {
var obj = new Object();
obj.name = name;
obj.age = 1;
obj.sex = true;
return obj;
}
var p = new Person();
console.log(p);
以上也相当于
<script type="text/javascript">
function Person(name) {
this.name = name;
this.age = 1;
this.sex = true;
}
var p = new Person();
console.log(p);
</script>
不加new
就是普通的函数,加上new
是构造函数,为了区分构造函数和普通函数/方法,此时可将第一个字母大写,也可以看作是一个工厂函数
可以使用实例 instanceof 构造函数
来判断是否是一个类的实例
DOM
全称为document object model,即文档对象模型,document读音为dɑːkjument
,中文为文档
document文档,代表整个HTML网页
object对象,将网页中的每一个部分都转换为了一个对象
model模型,表示对象之间的关系
childNodes
也会将换行当成一个节点,如果不把换行当成节点,可以使用var s = document.getElementById("city").children;
children属性
firstChild
包括空白,而firstChild
不包括空白
也可以通过选择器来获取元素document.querySelector("选择器")
只能返回一个
可以使用document.querySelectorAll("选择器")
返回所有的符合条件的
事件
电脑输入设备与页面进行交互的响应
onload
加载完成事件,常用于做js界面初始化操作onclick
单击事件,常按钮的点击响应操作,click读音为klik
,中文点击onblur
失去焦点事件,常用于输入框失去焦点后,验证内容是否合法,blur读音为blər
,中文为模糊、朦胧onchange
内容发生改变事件,常用于下拉列表和输入框内容发生改变后的操作onsubmit
表单提交事件,常用于表单提交前,验证所有表单项是否合法,submit,中文为提交、呈递、服从,读音为səbˈmit
事件的注册
又称为事件的绑定,即告诉浏览器,当事件响应后要执行哪些代码
- 静态事件的注册
- 通过HTML事件的属性直接赋予事件响应后的代码
- 动态注册事件:通过js代码得到dom的对象,通过dom对象.事件名 = function{}的形式赋予事件响应后的代码,称为动态注册
onload事件
浏览器解析完页面之后自动触发的事件
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>标题</title>
<link rel="stylesheet" href="css/1.css">
<script type="text/javascript" src="js.js">
</script>
</head>
<body onload="alert('静态注册onload事件')">
</body>
</html>
如果页面加载完之后有许多事要做,可以将要做的代码写到一个函数内,再通过onload
调用相关的函数
动态注册的写法
window.onload = function(){
alert("动态注册的onload事件");
}
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>标题</title>
<link rel="stylesheet" href="css/1.css">
<script>
window.onload = function (){
alert("动态注册的onload事件")
}
</script>
</head>
<body>
</body>
</html>
onclick事件
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>标题</title>
<link rel="stylesheet" href="css/1.css">
</head>
<body>
<button onclick = "alert('这是个测试按钮')">
测试
</button>
</body>
</html>
点击按钮后的内容
以上事件的写法不推荐,结构和行为耦合,不方便维护
可以通过获取按钮对象的写法进行书写
写法:
- 给按钮设置一个
id
- 使用
var 变量名 = document.getElementById("id名")
,即通过id获取按钮对象 - 通过
变量名.事件 = function(){}
为事件绑定需要的操作
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>标题</title>
<script>
window.onload = function (){
var btn = document.getElementById("button1");
btn.onclick = function () {
alert("动态注册");
}
}
</script>
</head>
<body>
<button id = "button1">
测试
</button>
</body>
</html>
onblur
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>标题</title>
<link rel="stylesheet" href="css/1.css">
<script>
window.onload = function (){
var ip = document.getElementById("input1");
ip.onblur = function () {
alert("失去焦点");
}
}
</script>
</head>
<body>
文本框:
<input type="text" id = "input1">
</body>
</html>
onchange
当发生改变时,进行的操作
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>标题</title>
<link rel="stylesheet" href="css/1.css">
<script>
window.onload = function (){
var st = document.getElementById("select1");
st.onchange = function () {
alert("内容发生改变");
}
}
</script>
</head>
<body>
<select id = "select1">
<option>选项1</option>
<option>选项2</option>
<option selected = "selected">选项3</option>
<option>选项4</option>
</select>
</body>
</html>
onsubmit
提交前,要验证所有的表单是否合法,如果合法就提交,如果不合法就不提交,即不会和正常提交那样浏览器要加载界面
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>标题</title>
<link rel="stylesheet" href="css/1.css">
<script>
window.onload = function () {
var st = document.getElementById("form1");
st.onsubmit = function (){
alert("登录失败");
return false;//只有返回true时才会提交,默认为true
}
}
</script>
</head>
<body>
<form action="localhost" method="get" id = "form1">
用户名:<input type="text" name = "username">
<br>
密码:<input type="password" name = "password">
<br>
<button type="submit">登录</button>
</form>
</body>
</html>
Prototype 原型
每一个构造函数都有prototype
对象,如果一个函数作为一个普通函数调用,那么这个函数的prototype
有和没有都一样
访问prototype
:调用对象.__proto__
原型对象是一个公共的部分,所有同一个类的对象都可以访问到这个原型对象,可以将所有类所共有的内容放到原型对象中
<script type="text/javascript">
function Person(name) {
this.name = name;
this.age = 1;
this.sex = true;
}
Person.prototype.static = "这个属性是公共的";
var p = new Person("狗");
console.log(p.__proto__.static);
var p2 = new Person("猫");
console.log(p2.static);
p2.__proto__.static = "888";
console.log("p.static = " + p.static);
console.log("p2.static = " + p2.static);
</script>
结果为:
这个属性是公共的
这个属性是公共的
p.static = 888
p2.static = 888
在访问一个对象的属性时,首先去这个对象自身找,如果有,就返回,如果没有再去prototype
中再找一次
在prototype
中的属性也可以通过"属性名" in 对象
进行判断是否在对象中
但如果想要查看这个对象自身是否有某个属性时,可以调用对象名.hasOwnProperty("属性名")
原型对象中也有原型,其中hasOwnProperty()
方法一般在原型的原型中,例如上例的p2.__proto__.__proto__.hasOwnProperty("hasOwnProperty")
为true
,而p2.__proto__.hasOwnProperty("hasOwnProperty")
为false
Object
没有原型
toString
和Java作用相同,默认的也是定义在一个对象的原型中的原型上
function Person(name) {
this.name = name;
this.age = 1;
this.sex = true;
this.toString = function() {
return "toString方法";
}
}
var p = new Person("狗");
console.log("p = " + p);
输出结果为:
p = toString方法
Date
var date = new Date();
或者
var date = new Date("年/月/日 hh:mm:ss")
对象.getDate()
获取当前对象的日
Date对象提供了一系列get*
方法,用来获取实例对象某个方面的值。
getTime()
:返回距离1970年1月1日00:00:00的毫秒数,等同于valueOf
方法。getDate()
:返回实例对象对应每个月的几号(从1开始)。getDay()
:返回星期几,星期日为0,星期一为1,以此类推。getYear()
:返回距离1900的年数。getFullYear()
:返回四位的年份。getMonth()
:返回月份(0表示1月,11表示12月)。getHours()
:返回小时(0-23)。getMilliseconds()
:返回毫秒(0-999)。getMinutes()
:返回分钟(0-59)。getSeconds()
:返回秒(0-59)。getTimezoneOffset()
:返回当前时间与UTC的时区差异,以分钟表示,返回结果考虑到了夏令时因素。
包装类
有三个包装类
将基本数据类型转换为对象,有3个:
-
Number
-
var n = new Number(333); console.log(typeof n); var n = 333; console.log(typeof n);
-
object number
-
-
String
-
Boolean
包装类无法使用==
判等
DOM相关方法
DOM全称为Document Object Model
文档对象模型
节点是构成整个网页的最基本的单元,分为:
- 文档节点:
- 整个
HTML
文档
- 整个
- 元素节点
- 每个标签
- 属性节点
- 属性值
- 文本节点
- 标签中的内容
将网页中所有的内容转换为对象
DOM的增删改
父.appendChild(子)
将子添加到父中(最后一个位置)
例如
<div class="inner">
<p>
你喜欢哪个城市?
</p>
<ul id="city">
<li id="bj">北京</li>
<li>上海</li>
<li>东京</li>
<li>首尔</li>
</ul>
</div>
将广州插入到<ul></ul>
最后
var li = document.createElement("li");
li.innerHTML = "广州";
var city = document.getElementById("city");
city.appendChild(li);
父.insertBefore(需要插入的, 已有的)
将需要插入的元素插入到已有的前边
还是以上的html结构,代码过程:
- 获取父标签
- 获取父标签中的第一个
- 调用
父.insertBefore(需要插入的, 已有的)
父.replaceChild(替换后的, 被替换的)
元素的替换
var li = document.createElement("li");
li.innerHTML = "广州";
var bj = document.getElementById("bj");
var city = document.getElementById("city");
city.replaceChild(li, bj);
元素.patentElement
可以获取到一个元素的父结点
删除一个结点:结点.remove()
用父元素删除子结点:父元素.removeChild(子元素)
var obj = document.getElementById(id)
返回名为id的第一个标签,即使有多个,也只返回第一个
- 获取对象后,可以调用
obj.type
获取类型,比方说文本输入框中的text类型 - 获取对象后,可以调用
obj.id
获取id名称 - 可以通过调用
obj.value
获取其中的值
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>标题</title>
<link rel="stylesheet" href="css/1.css">
<script>
window.onload = function () {
var login = document.getElementById("login");<!---获取登录按钮的对象--->
login.onclick = function () {<!---设置单击时的属性--->
var username = document.getElementById("username");<!---获取input标签的用户名的编辑框对象--->
var password = document.getElementById("password");
alert("账号:" + username.value + "\n" + "密码:" + password.value);<!---用两个对象的属性进行操作--->
}
}
</script>
</head>
<body>
<form action="localhost" method="get" id = "form1"><!---一个表单--->
用户名:<input type="text" name = "username" id = "username">
<br>
密码:<input type="password" name = "password" id = "password">
<br>
<button type="button" id = "login">登录</button>
</form>
</body>
</html>
正则表达式
写法1
var 变量名 = regExp("表达式")
判断给定的字符串是否合法
<script>
var re = new regExp("a");
re.test(字符串);//返回true或者false
</script>
写法2
var 变量名 = /表达式/
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>标题</title>
<link rel="stylesheet" href="css/1.css">
<script>
window.onload = function () {
//正则表达式,匹配数字、字母、下划线,并且大于4位小于等于10位
var re = /^[a-zA-Z0-9_-]{4,10}$/;
//获得一个对象
var login = document.getElementById("login");
//当按钮被单击
login.onclick = function () {
var username = document.getElementById("username");
var tip = document.getElementById("tip");
//查看用户名是否匹配
if (re.test(username.value)) {
//在其内部写一个标签,内容如下
tip.innerHTML = "<span style='color: green'>用户名合法</span>";
} else {
//在其内部写一个标签,内容如下
tip.innerHTML = "<span style='color: red'>用户名不合法</span>";
}
}
}
</script>
</head>
<body>
<form action="localhost" method="get" id="form1">
用户名:<input type="text" name="username" id="username">
<span id="tip"></span>
<br>
密码:<input type="password" name="password" id="password">
<br>
<button type="button" id="login">登录</button>
</form>
</body>
</html>
不匹配情况
匹配情况
var obj = getElementsByName(名称字字符串)
返回带有指定名称对象的集合(数组)
可以调用obj.length
获得结果集的长度
调用obj[i].checked
即可查看该下标处的复选框 是否被选中,也可以改变checked的值,如果改为true
代表选中,如果为false
代表未选中
<!doctype html>
<html class="no-js" lang="">
<head>
<meta charset="UTF-8">
<style>
button {
margin: 10px;
width: 70px;
height: 30px;
border: none;
background-color: rgb(252, 1, 57);
color: white;
border-radius: 30px;
}
button:hover {
background-color: #bd082c;
}
button:active {
background-color: #950421;
}
</style>
<script>
//这个集合中的值从上到下分别都是name为hobby的标签对象
window.onload = function () {
var hobbys = document.getElementsByName("hobby");
var allSelect = document.getElementById("all");
var notSelect = document.getElementById("notAll");
var reverseSelect = document.getElementById("reverse");
allSelect.onclick = function () {
for (var i = 0; i < hobbys.length; i++) {
hobbys[i].checked = true;
}//顺序cpp java python
}
//全不选
notSelect.onclick = function () {
for (var i = 0; i < hobbys.length; i++) {
hobbys[i].checked = false;
}//顺序cpp java python
}
//反选
reverseSelect.onclick = function () {
for (var i = 0; i < hobbys.length; i++) {
//设置为相反值
hobbys[i].checked = !hobbys[i].checked;
}
}
}
</script>
</head>
<body>
<form>
<input type="checkbox" name="hobby" value="cpp" id="cpp">
<label for="cpp">C++</label>
<input type="checkbox" name="hobby" value="java" id="java">
<label for="java">Java</label>
<input type="checkbox" name="hobby" value="python" id="python">
<label for="python">Python</label>
<br>
<button type="button" id="all">全选</button>
<button type="button" id="notAll">全不选</button>
<button type="button" id="reverse">反选</button>
</form>
</body>
</html>
效果
var obj = document.getElementsByTagName(标签名)
返回带有指定标签名的集合
以上三个查询方法,如果有id属性,优先使用idgetElementById
,如果id也没有,尝试使用name
getElementsByName
,如果两者都没有,就使用getElementsByTagName
,只有在页面加载完成后才能够查到对象,即尽量写在window.onload = function{}
中,即浏览器读完标签后才能够创建对象
属性
节点就是标签对象
body对象是经常用的,可以调用document.body
返回对象
创建标签
<!doctype html>
<html class="no-js" lang="">
<head>
<meta charset="UTF-8">
<style>
button {
margin: 10px;
width: 70px;
height: 30px;
border: none;
background-color: rgb(252, 1, 57);
color: white;
border-radius: 30px;
}
button:hover {
background-color: #bd082c;
}
button:active {
background-color: #950421;
}
</style>
<script>
//计数
var count = 1;
window.onload = function () {
var button = document.getElementById("button");
button.onclick = function () {
//先获取一个预添加的元素
var buttonObject = document.createElement("button");
//设置按钮类型
buttonObject.type = "button";
//设置按钮名称
buttonObject.innerText = "按钮" + count++;
//在合适的位置添加元素,此时在body中添加元素
document.body.appendChild(buttonObject);
}
}
</script>
</head>
<body>
<form>
<button type="button" id = "button">添加按钮</button>
</form>
</body>
</html>
效果
一个问题,i的索引
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript">
window.onload = function(){
var a = document.getElementsByTagName("a");
for(var i = 0; i < a.length; i++){
a[i].onclick = function(){
alert(i);
return false;
}
}
}
</script>
</head>
<body>
<a href="">点我</a><br>
<a href="">点我</a><br>
<a href="">点我</a><br>
<a href="">点我</a><br>
<a href="">点我</a><br>
<a href="">点我</a><br>
<a href="">点我</a><br>
<a href="">点我</a><br>
<a href="">点我</a><br>
<a href="">点我</a><br>
</body>
</html>
此时无论点击哪个a
标签,弹出的提示框的i
的值永远是10
因为for
循环执行时,响应函数并没有执行(此时没有触发点击事件),for
循环在此处的作用仅仅是给点击事件赋值,只有点击标签时才会执行响应函数,所以弹出的提示框的i
的值永远是10
DOM操作CSS
修改CSS样式:
DOM元素.style.样式名 = "样式值";
如上图,修改div的宽度和高度
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript">
window.onload = function(){
var css = document.getElementById("css");
css.onclick = function(){
var div = document.getElementById("div1");
div.style.width = "100px";
div.style.height = "100px";
}
}
</script>
<style>
#div1{
width: 300px;
height: 300px;
background-color: rgb(89, 170, 245);
}
</style>
</head>
<body>
<div id="div1">
</div>
<br>
<br>
<button id = "css">修改</button>
</body>
</html>
对于带有-
的样式,在js
中-
被当成减号
处理的,需要将其改成驼峰规则,例如background-color
改成div.style.backgroundColor = "black";
通过这个方法设置或者读取到的样式只能读取到内联样式,读取不到写在css
标签中的样式
可以使用getComputedStyle(要获取的元素, 参数2)
获取CSS中的样式,这个方法是Window
提供的而不是DOM
提供的,参数2可以传递伪元素,通常都把第二个元素值为null
,即getComputedStyle(要获取的元素, null)
,这个方式获取到的样式不能修改
事件对象
当响应事件触发时,浏览器会将一个事件对象作为实参传递给响应函数,可以在函数的形参列表中随便定义一个变量查看
例如
window.onload = function(){
var div1 = document.getElementById("div1");
div1.onmousemove = function(e){
alert(e);
}
}
此时e就是传递给函数的一个变量,输出内容为[object MouseEvent]
详情:查看
例如以下效果:
就是使用事件对象获取到的鼠标的坐标
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript">
window.onload = function(){
var div1 = document.getElementById("div1");
var x = document.getElementById("x");
var y = document.getElementById("y");
div1.onmousemove = function(e){
x.innerText = e.clientX;
y.innerText = e.clientY;
}
}
</script>
<style>
#div1, #div2{
width: 300px;
height: 300px;
border: 1px solid black;
}
#div2{
width: 300px;
height: 40px;
margin-top: 20px;
}
</style>
</head>
<body>
<div id="div1">
</div>
<div id="div2">
<span style="margin-left: 10px;">
x:<span id="x"></span>px
</span>
<span style="margin-right: 10px; float:right;">
y:<span id="y"></span>px
</span>
</div>
</body>
</html>
div跟着鼠标走,需要开启定位
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript">
window.onload = function(){
var div1 = document.getElementById("div1");
document.onmousemove = function(e){
// 鼠标相对于页面的位置
div1.style.left = e.pageX + "px";
div1.style.top = e.pageY + "px";
}
}
</script>
<style>
#div1{
width: 300px;
height: 300px;
border: 1px solid black;
position: absolute;
}
#div2{
width: 300px;
height: 40px;
margin-top: 20px;
}
</style>
</head>
<body>
<div id="div1">
adsfadsfafadf
</div>
</body>
</html>
事件的冒泡 bubble
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript">
window.onload = function(){
var div1 = document.getElementById("div1");
div1.onclick = function(){
alert("div1");
}
var div2 = document.getElementById("div2");
div2.onclick = function(){
alert("div2");
}
}
</script>
<style>
#div1{
width: 300px;
height: 300px;
border: 1px solid black;
position: absolute;
}
#div2{
width: 60px;
height: 60px;
background-color: rgb(43, 228, 151);
}
</style>
</head>
<body>
<div id="div1">
<div id="div2">
</div>
</div>
</body>
</html>
此时如果点div2,div1的事件也会触发,此时称为事件的冒泡
当后代的事件触发时,祖先的相关事件也会触发
取消事件的冒泡
var div2 = document.getElementById("div2");
div2.onclick = function(e){
// 取消冒泡
e.cancelBubble = true;
alert("div2");
}
事件的委派
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript">
window.onload = function () {
var btn = document.getElementById("btn");
var a = document.getElementsByTagName("a");
for (var i = 0; i < a.length; i++) {
a[i].onclick = function () {
alert("点击了a标签");
}
}
var ul = document.getElementById("u1");
btn.onclick = function () {
var li = document.createElement("li");
li.innerHTML = "<a href='javascript:;'>新的超链接</a>"
ul.appendChild(li);
}
}
</script>
<style>
</style>
</head>
<body>
<button id="btn">添加新的超链接</button>
<ul id="u1">
<li><a href="javascript:;">超链接1</a></li>
<li><a href="javascript:;">超链接2</a></li>
<li><a href="javascript:;">超链接3</a></li>
</ul>
</body>
</html>
如以上代码,给已有的3个a标签添加了点击事件,但新加入的a标签没有点击事件
给已有的a标签绑定的事件的过程比较繁琐,效率比较低,可以尝试找一种只绑定一次事件,可应用到多个a标签,即使a标签是后加入的
针对此问题,此时可以给<ul></ul>
标签添加一个单击事件,此时再点击a标签时,也会有相应的事件了,此时称为事件的委派,即让其父元素添加事件,使用此种方式减少了绑定次数,提高了性能
但可能会出现点击<li></li>
标签时事件会触发,要想解决这个问题,需要判断点击的是哪个标签,如果点击的是a标签,那么执行,如果点击的是<li></li>
标签就不执行
解决方案:
- 为所有的a标签添加相同的
class
- 通过
event.target.className
获取到点击元素的class
- 如果点击元素的class是a标签的class,此时就执行
- 如果不是,不执行
最终
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript">
window.onload = function () {
var btn = document.getElementById("btn");
var ul = document.getElementById("u1");
ul.onclick = function(e){
// 判断点击的元素的class名称
if(e.target.className == "link"){
alert("点击了a的元素");
}
}
btn.onclick = function () {
var li = document.createElement("li");
li.innerHTML = "<a href='javascript:;' class='link'>新的超链接</a>"
ul.appendChild(li);
}
}
</script>
<style>
</style>
</head>
<body>
<button id="btn">添加新的超链接</button>
<ul id="u1">
<li><a href="javascript:;" class="link">超链接1</a></li>
<li><a href="javascript:;" class="link">超链接2</a></li>
<li><a href="javascript:;" class="link">超链接3</a></li>
</ul>
</body>
</html>
一个元素同一个事件绑定多个响应函数
使用元素.onclick = function(){....}
一次只能给一个元素绑定一个事件,如果有多次绑定,那么以最后一次绑定为准
使用元素.addEventListener("事件", 回调函数function(){}, false)
参数1,事件,例如onclick
事件要写为click
不要写为onclick
,第三个参数为布尔值 是否在捕获阶段执行,一般为false
例如
var btn = document.getElementById("btn");
btn.addEventListener("click", function(){
alert("你好,世界");
}, false);
btn.addEventListener("click", function(){
alert("你好,地球");
}, false);
此时点击按钮会触发两个对话框
拖拽
流程:
- 鼠标在要拖拽的元素按下时,开始拖拽
onmousedown
- 鼠标按下并移动时,元素跟着鼠标移动
onmousemove
- 鼠标松开时,被拖拽的元素固定到当前位置
onmouseup
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript">
window.onload = function () {
var box = document.getElementById("box");
box.onmousedown = function () {
box.onmouseup = function (e) {
document.onmousemove = null;
};
document.onmousemove = function (e) {
box.style.left = e.pageX - 10 + "px";
box.style.top = e.pageY - 10 + "px";
};
}
}
</script>
<style>
#box {
width: 300px;
height: 400px;
border-radius: 10px;
border: 1px solid rgb(0 0 0 / 10%);
box-shadow: -4px 7px 46px 2px rgb(0 0 0 / 10%);
position: absolute;
}
</style>
</head>
<body>
<div id="box">
</div>
</body>
</html>
拖动div
使用此种方式体验不好,每次点击时,以左上角为中心
解决方案
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript">
window.onload = function (e) {
var box = document.getElementById("box");
box.onmousedown = function (e) {
box.onmouseup = function () {
document.onmousemove = null;
box.onmouseup = null;
};
// 鼠标偏移量
var ol = e.pageX - box.offsetLeft;
var ot = e.pageY - box.offsetTop;
document.onmousemove = function (e) {
box.style.left = e.pageX - ol + "px";
box.style.top = e.pageY - ot + "px";
};
}
document.getElementById("close").onclick = function () {
box.style.display = "none";
}
}
</script>
<style>
#box {
width: 300px;
height: 400px;
border-radius: 10px;
border: 1px solid rgb(0 0 0 / 10%);
box-shadow: -4px 7px 46px 2px rgb(0 0 0 / 10%);
position: absolute;
}
.top1 {
height: 30px;
border-bottom: 1px solid rgb(0 0 0 / 10%);
}
#close {
width: 30px;
height: 30px;
/* background-color: rgb(7, 7, 7); */
border-radius: 0px 10px 0px 0px;
float: right;
text-align: center;
line-height: 30px;
}
#close:hover {
color: white;
background-color: red;
}
#close:active {
color: white;
background-color: rgb(194, 3, 3);
}
</style>
</head>
<body>
<div id="box">
<div class="top1">
<div id="close">
×
</div>
</div>
</div>
</body>
</html>
效果:
滚动
wheel车轮
delta三角洲
例子:向上滚动变短,向下滚动变长
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript">
window.onload = function (e) {
var box = document.getElementById("box");
box.onmousedown = function (e) {
box.onmouseup = function () {
document.onmousemove = null;
box.onmouseup = null;
};
// 鼠标偏移量
var ol = e.pageX - box.offsetLeft;
var ot = e.pageY - box.offsetTop;
document.onmousemove = function (e) {
box.style.left = e.pageX - ol + "px";
box.style.top = e.pageY - ot + "px";
};
}
document.getElementById("close").onclick = function () {
box.style.display = "none";
}
box.onmousewheel = function (e) {
if (e.wheelDelta < 0 && box.clientHeight - 1 > 35) {
// 向下滚动变短
box.style.height = box.clientHeight - 1 + "px";
}else if(e.wheelDelta > 0){
// 向上滚动变长
box.style.height = box.clientHeight + 1 + "px";
}
}
}
</script>
<style>
#box {
width: 300px;
height: 400px;
border-radius: 10px;
border: 1px solid rgb(0 0 0 / 10%);
box-shadow: -4px 7px 46px 2px rgb(0 0 0 / 10%);
position: absolute;
}
.top1 {
height: 30px;
border-bottom: 1px solid rgb(0 0 0 / 10%);
}
#close {
width: 30px;
height: 30px;
/* background-color: rgb(7, 7, 7); */
border-radius: 0px 10px 0px 0px;
float: right;
text-align: center;
line-height: 30px;
}
#close:hover {
color: white;
background-color: red;
}
#close:active {
color: white;
background-color: rgb(194, 3, 3);
}
</style>
</head>
<body>
<div id="box">
<div class="top1">
<div id="close">
×
</div>
</div>
</div>
</body>
</html>
键盘事件
onkeydown
键盘按下,当按下某个按键不动时,这个事件一直被触发
onkeyup
键盘松开
一般绑定到可以获取焦点的对象或者document
,div
就不能获取焦点,input
可以获取焦点
e.key
获取按下的按键名称
也可以通过e.keyCode
获取按下的值
也可以通过e.code
获取
也可以获取组合按键
document.onkeydown = function(e){
if(e.key == "a" && e.ctrlKey){
console.log("ctrl + a");
}
}
阻止向input
中输入内容
<input type="text" id="input"/>
window.onload = function () {
document.getElementById("input").onkeydown = function(){
console.log("按键按下");
return false;
}
}
此时无法向输入框中输入内容,如果监听事件是onkeyup
还能输入内容
键盘控制div
上下左右移动
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript">
window.onload = function () {
var box = document.getElementById("box1");
document.onkeydown = function (e) {
switch (e.key) {
case "ArrowDown":
box.style.top = box.offsetTop + 1 + "px";
break;
case "ArrowUp":
box.style.top = box.offsetTop - 1 + "px";
break;
case "ArrowLeft":
box.style.left = box.offsetLeft - 1 + "px";
break;
case "ArrowRight":
box.style.left = box.offsetLeft + 1 + "px";
break;
}
}
}
</script>
<style>
#box1 {
width: 30px;
height: 30px;
background-color: rgb(133, 36, 36);
position: absolute;
}
</style>
</head>
<body>
<div id="box1">
</div>
</body>
</html>
BOM
全称为浏览器对象模型,可以通过JS操作浏览器
包括:
Window
- 浏览器的窗口,网页中的全局对象
Navigator
- 代表浏览器的信息,通过该信息识别不同的浏览器
Location
- 地址栏的信息
History
- 浏览器的历史记录,由于隐私的问题,不能获取到具体的历史记录
- 只能操纵浏览器前进或者后退
- 只在本次访问中有效
Screen
- 获取显示器相关信息
Navigator
读音ˈnævɪɡeɪtər
,中文航海家
通过navigator.userAgent
可以获取浏览器标识
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36
History
history.length
可以获取访问的链接数量
history.back()
可以使浏览器后退
history.forward()
可以使浏览器前进
history.go(数字)
可以使浏览器前进/后退数字个数,如果大于0代表前进,小于0代表后退
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript">
window.onload = function () {
alert(location)
document.getElementById("back").onclick = function(){
history.back();
}
document.getElementById("forward").onclick = function(){
history.forward();
}
}
</script>
</head>
<body>
<button id="back">后退</button>
<button id="forward">前进</button>
</body>
</html>
Location
存储着地址栏的信息
修改location
会跳转到修改后的页面,也会生成历史记录
assign
中文为分配
location.assign("地址,支持相对路径和绝对路径");
location.reload()
普通刷新
location.reload(true)
强制刷新,相当于按shift + 刷新
location.replace("地址")
也是跳转到另一个页面,但不会生成历史记录,也就是说本地历史记录不会记录并且不能后退回去
定时器
进入页面后自动计时
setInterval(function{}, 毫秒)
,每间隔一段时间执行一次函数,intervalˈɪntərvl
,中文为间隔,返回值为一个整数,这个整数用来表示是第几个定时器
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript">
window.onload = function () {
var count = document.getElementById("count");
var c = 0;
setInterval(function(){
count.innerHTML = c++;
}, 100);
}
</script>
</head>
<body>
<div id="count"></div>
</body>
</html>
此时有个问题,不会停止
可以使用clearInterval(第几个定时器);
关闭某个定时器,只有在传递进来的参数是正常的数值时才会执行,如果不是正常的数值或者不存在的定时器,将不会执行
例如当数字到达444的时候关闭定时器
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript">
window.onload = function () {
var count = document.getElementById("count");
var c = 0;
var id = setInterval(function () {
count.innerHTML = c++;
if (c == 444) {
clearInterval(id);
}
}, 0);
}
</script>
</head>
<body>
<div id="count"></div>
</body>
</html>
轮播图可以使用定时器制作
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript">
window.onload = function () {
var img = document.getElementById("img");
var count = 0;
// 设置自动切换
setInterval(function () {
img.src = "/img/" + (count % 5 + 1) + ".jpg";
count++;
}, 2000);
}
</script>
</head>
<body>
<img src="/img/1.jpg" alt="" id="img">
</body>
</html>
按钮开始图片切换
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript">
window.onload = function () {
var img = document.getElementById("img");
var flag = null;
var start = document.getElementById("start");
var count = 1;
start.onclick = function () {
// 防止开启多个定时器
if (flag == null) {
// 设置自动切换
flag = setInterval(function () {
img.src = "/img/" + (count + 1) + ".jpg";
count = (count + 1) % 5;
}, 2000);
}
}
var end = document.getElementById("end");
end.onclick = function () {
// 关闭定时器
clearInterval(flag);
flag = null;
}
}
</script>
</head>
<body>
<img src="/img/1.jpg" alt="" id="img">
<br><br><br><br>
<button id="start">开始</button>
<button id="end">停止</button>
</body>
</html>
延时调用
setTimeout(function{}, 毫秒)
一个函数不马上执行,延迟一段时间后执行,只执行一次
也会返回一个整数用来表示这是第几个延时调用函数,也可以使用clearTimeout(整数)
来停止延时调用
更换样式
之前使用的更换样式的方法是document元素.style.属性 = 值
,使用这种方式更换的样式性能比较差,并且每修改一次会重新渲染页面
可以写一个类选择器,使用类选择器定义样式并且在之后的样式切换中直接使用
document元素.className = "值"
进行切换样式
追加样式:
-
在之前的HTML中,为一个标签添加多个样式时是以空格进行分割的,例如
-
<div class = "style1 style2" id = "div1"> </div>
-
-
使用
JavaScript
追加样式时,只需要在原有样式基础上加上一个新样式-
例如为以上的
div1
追加一个style3
可以写为-
div1.className += " style3";// 一定要有空格
-
-
案例,点击展开菜单,再次点击收缩菜单
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script type="text/javascript">
window.onload = function () {
var menus = document.getElementsByClassName("menu");
var items = document.getElementsByClassName("item");
for(var i = 0; i < menus.length; i++){
menus[i].onclick = function(){
var next = this.nextElementSibling;
// js无法直接使用 dom元素.style.属性 获取原本css样式,只能通过以下的方法获取
var style = getComputedStyle(next, null);
if(style.display == "none"){
next.style.display = "block";
}else{
next.style.display = "none";
}
}
}
}
</script>
<style>
li {
list-style: none;
}
.item{
display: none;
}
</style>
</head>
<body>
<ul>
<li>
<div class="menu">菜单1</div>
<div class="item">
<ul>
<li>菜单项</li>
<li>菜单项</li>
<li>菜单项</li>
<li>菜单项</li>
<li>菜单项</li>
<li>菜单项</li>
</ul>
</div>
</li>
<li>
<div class="menu">菜单2</div>
<div class="item">
<ul>
<li>菜单项</li>
<li>菜单项</li>
<li>菜单项</li>
<li>菜单项</li>
<li>菜单项</li>
<li>菜单项</li>
</ul>
</div>
</li>
<li>
<div class="menu">菜单3</div>
<div class="item">
<ul>
<li>菜单项</li>
<li>菜单项</li>
<li>菜单项</li>
<li>菜单项</li>
<li>菜单项</li>
<li>菜单项</li>
</ul>
</div>
</li>
</ul>
</body>
</html>
JSON
属性名必须要加""
json允许的值的类型:
- 字符串
- 数值
null
- 对象
- 数组
- 布尔值
在js中有一个工具类为JSON
,可以将JSON
字符串转换为对象,也可以把一个对象转化为JSON
字符串
使用JSON.parse(字符串)
可以转换为一个对象,例如
var json = '{"name":"hello", "age":15, "sex":true, "amount":1.1, "arr":[1,2,3], "obj":{"name":"object字符串"}}';
// JSON 转换为对象
var obj = JSON.parse(json);
alert(obj.obj.name);
对象转JSON
字符串:JSON.stringify(对象)
例如:
var object = {
name: "obj",
age: "33",
num: 88.44,
bool: true,
arr: [33,536,356,46,74]
};
alert(JSON.stringify(object));
结果为:{"name":"obj","age":"33","num":88.44,"bool":true,"arr":[33,536,356,46,74]}
Q.E.D.