JavaScript详解
一、快速入门
1.JavaScript的两种引入方式
方式一:直接在html里面写 目的:实现简单的弹窗点击查看代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--script标签内,写JavaScript代码,可以放在head标签里,也可以放在body标签里-->
<script>
<!--弹窗,打开页面时弹出一个窗口,并显示有hello,world-->
alert('hello,world');
</script>
</head>
<body>
</body>
</html>
方式二:新建一个js文件,在HTML中连接该文件也可以实现,就像css一样和HTML分开
注意script标签必须是成对出现,
2.基本语法
点击查看代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--Javascript严格区分大小写-->
<script>
//单行与多行注释与Java中注释的方式一样
/*1.定义变量 变量类型 变量名 = 变量值;*/
var score =100;//这里不写分号也没事
var name = "twq";//这里不写var也没事,就算不写变量名都可以,是不感觉可以随心所欲了
if(score>60 && score <70){
alert('小子,你很危险呀');
}else if(score > 70 && score < 80){
alert('革命尚未成功,同学 仍需努力呀!!');
}else{
alert('不要骄傲哦!');
}
</script>
</head>
<body>
</body>
</html>
调试方法
参照下图:3.数据类型
(1)number
js不区分小数和整数,Number点击查看代码
123//整数123
123.1//浮点数123.1
1.123e3//科学计数法
-99//负数
NaN//not a number
Infinity//表示无限大
(2)字符串
和Java的一样(长度str.length)
(3)布尔值
(4)逻辑运算
① && 两个都为真,结果为真② | | 一个为真,结果为真
③ !真即假,假即真
逻辑中断
逻辑与
语法:表达式1&&表达式2
如果第一个表达式的值为真,则返回表达式2
如果第一个表达式的值为假,则返回表达式1
语法: 表达式1 || 表达式2
如果第一个表达式的值为真,则返回表达式1
如果第一个表达式的值为假,则返回表达式2
(5)比较运算符
① = 赋值② == 等于(类型不一样,值一样,也会判断为true)
③ === 绝对等于(类型一样,值一样结果为true)
注意:这是Java的一个缺陷,坚决不要使用==比较
须知:
- NaN===NaN,这个与所有的数值都不相等,包括自己
- 只能通过isNaN(NaN)来判断这个数据是否是NaN
(6)浮点数
尽量避免使用浮点数进行运算,存在精度问题!(7)数组
java的数值必须是相同类型的对象,JS中需不要这样!
如果数组下标越界会报undefined
(8)对象
对象是大括号,数组是中括号 每个属性之间用逗号隔开,最后一个属性之后不需要逗号点击查看代码
<script>
console.log((1/3)===(1-2/3));
console.log(Math.abs(1/3-(1-2/3))<0.00000001);
//保证代码的可读性,尽量使用[]
var arr=[1,2,3,4,5,'hello',null,true];
new Array(1,12,3,4,5,'hello');
var person ={
name:"Twq",
age:23,
tags:['js','java','web','...']
}
</script>
数据类型判断及转换
点击查看代码
<!DOCTYPE html>
<html lang="en">
<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>
var num = 10;
console.log(typeof num) //number
//prompt得到的值为字符类型
var age = prompt("输入年龄")
console.log(typeof age) //string
//转化为字符串
var num = 10
console.log(typeof num) //number
console.log(typeof num.toString()) //string
var a = 1
console.log(typeof String(a)) //string
//转换为数字类型
var a = '3.14'
console.log(typeof num) //string
console.log(typeof parseInt(a)) //number,并且a的值为3,直接取整
console.log(parseInt('120px')) //会去掉px
console.log(parseInt('as120px')) //NaN
console.log(parseFloat('3.14')) //3.14
console.log(parseFloat('120px')) //会去掉px
console.log(parseFloat('as120px')) //NaN
//
</script>
</head>
<body>
</body>
</html>
4.严格检查模式
点击查看代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
/*前提是IDEA需要设置支持ES6语法
*'use strict'严格检查模式,预防Javascript的随意性导致产生的一些问题如:
* ①定义变量不写变量类型在没有写严格检查时不会报错,但是加上这严格检查之后就会报错
* 必须要写在JS的第一行
* 局部变量建议都使用let去定义 */
'use strict';
/*let是块作用域,就会好比在for循环里用let定义了一个块变量
在循环的外部则无法使用该变量,var是函数作用域,在循环里面定义的
变量在循环外面也可以可以访问*/
let i = 1;
</script>
</head>
<body>
</body>
</html>
二、详解数据类型
1.字符串
(1)正常字符串,我们使用单引号或者双引号包裹
(2)注意转义字符
①\'②\n
③\u4e2d unicode字符格式:\u####
④\41 Ascll字符
(3)多行字符串编写
(4)模板字符串
点击查看代码
<script>
//tab 上面 esc下面
let name = "Twq";
var msg =`你好呀,${name}`//在Java中连接两个字符串用加号,二JS可以使用$符号连接
</script>
(5)字符串长度
(6)字符串内容的不可变性
(7)大小写转换
(8)查找
(9)substring
2.数组
(1)长度
Array可以包含任意的数据类型
注意:假如给arr.length赋值,数组大小就会发生变化,如果赋值过小,元素就会丢失
(2)indexOf,通过元素获得下标索引
在数组里字符串的1和数字1是不同的
(3)slice()
截取Array的一部分,返回一个新数组,类似于String中的substring(4)尾部压入和弹出push(),pop()
从尾部压入和弹出元素(5)unshift(),shift()
unshift()压入到头部 shift()弹出头部的第一个元素(6)sort()
(7)元素反转
(8)concat()
注意:concat()并没有修改原来的数组的值,只是会返回一个新的数组
(9)连接符join
打印拼接数组,使用特定的字符串连接(10)多维数组
3.对象
(1).使用一个不存在的对象属性,不会报错!undefined
(2)动态的删减属性
(3)动态的添加属性
(4)判断属性值是否在这个对象中
(5)判断一个属性是否是这个对象自身拥有的hasOwnProperty()
4.Map和Set
(1)Map
点击查看代码
<script>
var map = new Map([['tom',100],['jack',900],['haha',80]])
console.log(map.get('jack'))
map.set('admin',90);//新增或修改
map.delete('tom');//删除
for(let x of map){
console.log(x)
}
</script>
(2)Set
无序不重复的集合点击查看代码
<script>
var set = new Set([1,1,1,3]);
set.add(2);//添加一个元素
set.delete(3);//删除一个元素
for(let x of set){
console.log(x)
}
console.log(set.has(1))//集合中是否包含1
</script>
四、函数
1.定义函数
(1)定义方式一
点击查看代码
<script>
function abs(x){
if(x >= 0){
return x;
}
else{
return -x;
}
}
</script>
一旦执行到return代表函数结束,返回结果
如果没有执行return,函数执行完也会返回结果,结果就是undefined
(2)方式二:
点击查看代码
var abs = function(x){
if(x >= 0){
return x;
}
else{
return -x;
}
}
点击查看代码
<script>
var abs = function(x){
if(typeof x !== 'number'){//如果参数x的类型不是一个数
//手动定义异常
throw 'Not a number';
}
if(x >= 0){
return x;
}
else{
return -x;
}
}
</script>
②假设参入的参数有多个
可以使用arguments关键词
arguments:代表传递进来的所有参数,是一个数组
点击查看代码
<script>
var abs = function(x){
if(typeof x !== 'number'){//如果参数x的类型不是一个数
//手动定义异常
throw 'Not a number';
}
for(let i =0; i<arguments.length;i++){
console.log(arguments[i])
}
// if(x >= 0){
// return x;
// }
// else{
// return -x;
// }
}
</script>
③使用reset获取当前除已定义的参数以外的所有参数
点击查看代码
<script>
var abs = function(a,b,c,...rest){
console.log("a->"+a);
console.log("b->"+b);
console.log("c->"+c);
console.log(rest);
}
</script>
2.变量的作用域
(1)在JavaScript中,var定义变量实际是有作用域的
假设在函数体中声明,则在函数体外不可以使用-(非要想实现的话可以后面研究一下闭包)(2)如果两个函数是用来相同的变量名,只要在函数内部,就不冲突
点击查看代码
<script>
'use strict'
function twq(){
var x = 1;
x = x+1;
}
function twq1(){
var x = x +1;
}
</script>
(3)内部函数可以访问外部函数的成员,反之则不行
点击查看代码
<script>
'use strict'
function twq(){
var x = 1;
function twq1(){
var y = x +1;
}
var z = y +1;
}
</script>
(4)当内外函数变量重名时
在JS中函数查找变量从自身函数开始,由‘内’ 向 ‘外’查找,假设外部存在两个同名的函数变量,则内部函数会屏蔽外部函数的变量。点击查看代码
<script>
'use strict'
function twq(){
var x = 1;
function twq(){
var x = 'A';
console.log('inner'+x);
}
console.log('outer'+x);
twq();
}
twq();
</script>
(5)提升变量的作用域
点击查看代码
<script>
'use strict'
function twq(){
var x = 'x' + y;
console.log(x);
var y = 'y';
}
twq();
</script>
由此结果可知JS执行引擎,自动提升了y的声明,但是不会提升y的赋值
(7)全局对象window
默认所有的全局变量,都会自动绑定在window对象中点击查看代码
<script>
'use strict'
var x = 'xxx';
alert(x);
alert(window.x);
</script>
(8)局部作用域(let)
循环中使用var时点击查看代码
<script>
'use strict'
function aaa(){
for (var i = 0; i < 100; i++) {
console.log(i);
}
console.log(i+1);
}
</script>
let关键字,解决局部作用域冲突的问题
点击查看代码
<script>
'use strict'
function aaa(){
for (let i = 0; i < 100; i++) {
console.log(i);
}
console.log(i+1);
}
</script>
(9)常量const
在ES6之前,怎么定义常量:只有用全部大写字母命名的变量就是常量,建议不要修改这样的值点击查看代码
<script>
'use strict'
var PI = '3.14';
console.log(PI);
PI = '213';//可以改变这个值
console.log(PI)
</script>
在ES6引入了常量关键字const
点击查看代码
<script>
'use strict'
const PI = '3.14';
console.log(PI);
PI = '213';//可以改变这个值
console.log(PI);
</script>
3.方法
(1)定义方法
①方法就是把函数放在对象的里面,对象只有两个东西:属性和方法点击查看代码
<script>
'use strict'
var person = {
name:'唐',
birth:1999,
//方法
age:function (){
//今年-出生的年 为它的年龄
var now = new Date().getFullYear();//获取当前的年份
return now - this.birth;
}
}
</script>
②方式二:
点击查看代码
<script>
'use strict'
function getAge(){
//今年-出生的年 为它的年龄
var now = new Date().getFullYear();
return now - this.birth;
}
var person = {
name:'唐',
birth:1999,
//方法
age:getAge//这里只需要将方法名天在这里即可
}
//kuangshen.age() ok
//getAge() NaN 直接调用getAge()其内部的this指的是window
</script>
(2)apply
getAge.apply(person,[]) this指向了person,参数为空五、内置对象
MDN文档查阅,在这里可以查找一些常用内置对象的使用方法https://developer.mozilla.org/zh-CN/1.标准对象
2.Date
(1)基本使用
(2)转换
3.JSON
在JS中一切皆为对象,任何JS支持的类型都可以用JSON来表示:格式:
- 对象都用{ }
- 数组都用[]
- 所有的键值对都使用key:value
(1)JSON字符窜和JS对象的相互转化
点击查看代码
<script>
var user={
name:'twq',
age:3,
sex:'男'
}
//对象转化为JSON字符串{}
var jsonUser = JSON.stringify(user);
//JSON字符串转化为对象 参数为JSON字符串
var obj = JSON.parse('{\"name\":\"twq\",\"age\":3,\"sex\":\"男\"}');
</script>
六、面向对象编程
1.原型(父类)
点击查看代码
<script>
var student={
name:'twq',
age:23,
run:function (){
console.log(this.name+' is running.....')
}
}
var xiaoming={
name:'xiaoming'
}
xiaoming.__proto__=student;
</script>
2.class继承
(1)class关键字,是在ES6引入的
点击查看代码
<script>
class Student{
constructor(name) {//构造器
this.name =name;
}
hello(){
alert('hello')
}
}
var st1 = new Student("小明");
var st2 = new Student("小红");
</script>
(2)继承
点击查看代码
<script>
class Student{
constructor(name) {//构造器
this.name =name;
}
hello(){
alert('hello')
}
}
var st1 = new Student("小明");
var st2 = new Student("小红");
class primeStudent extends Student{
constructor(name,grade) {
super(name);
this.grade = grade;
}
myGrade(){
alert('我是一名小学生');
}
}
var st3 = new primeStudent("小刚",23);
</script>
本质:查看对象原型
七、操作BOM对象(重点)
1.浏览器介绍
(1)javascript和浏览器的关系
JavaScript诞生就是为了能够让它在浏览器中运行 BOM:浏览器对象模型(2)window
window代表浏览器的窗口(4)Navigator(了解)
Navigator,封装了浏览器的信息
大多数时候,我们不会使用navigator对象,因为会被人为修改
(5)screen
屏幕的尺寸(6)location(重点)
location代表当前页面的URL信息点击查看代码
host: "localhost:63342"
href:"http://localhost:63342/Java02/JavaScript/tang/%E5%86%85%E9%83%A8%E5%AF%B9%E8%B1%A1/class%E7%BB%A7%E6%89%BF.html?_ijt=sibusl004num53m4li95rdnuvg"
protocol: "http:"
reload: ƒ reload()//刷新页面
//设置新的地址
location.assign('https://www.cnblogs.com/twq46/')
(7)document
document代表当前的页面,HTML DOM文档树
获取具体的文档树节点
点击查看代码
<body>
<dl id="app">
<dt>java</dt>
<dd>javaSE</dd>
<dd>javaEE</dd>
</dl>
<script>
var dl = document.getElementById('app');
</script>
</body>
获取cookie
劫持cookie原理:对于有病毒的网站,可能就会存在获取你的cookie的JS代码,一旦他们获得你的cookie值,就可以登录的你的账号进行操作,比如你在登录淘宝账号之后,天猫网站也会自动登录上,这就是因为天猫会获取你登录淘宝账号的cookie值,从而用这些信息自动去登录天猫网站
服务器端可以设置cookie:httpOnly,就可以保证信息安全
(8)history
history代表浏览器的历史记录2.BOM概述
window 对象是浏览器的顶级对象,它具有双重角色。
- 它是 JS 访问浏览器窗口的一个接口。
- 它是一个全局对象。定义在全局作用域中的变量、函数都会变成 window 对象的属性和方法。
在调用的时候可以省略 window,前面学习的对话框都属于 window 对象方法,如 alert()、prompt() 等。
注意:window下的一个特殊属性 window.name
DOM
文档对象模型
DOM 就是把「文档」当做一个「对象」来看待 DOM 的顶级对象是 document
DOM 主要学习的是操作页面元素
DOM是W3C标准规范
BOM
浏览器对象模型
把「浏览器」当做一个「对象」来看待
BOM 的顶级对象是 window
BOM 学习的是浏览器窗口交互的一些对象
BOM 是浏览器厂商在各自浏览器上定义的,兼容性较差
3.window对象的常见事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script>
// window.onload = function() {
// var btn = document.querySelector('button');
// btn.addEventListener('click', function() {
// alert('点击我');
// })
// }
// window.onload = function() {
// alert(22);
// }
window.addEventListener('load', function() {
var btn = document.querySelector('button');
btn.addEventListener('click', function() {
alert('点击我');
})
})
window.addEventListener('load', function() {
alert(22);
})
document.addEventListener('DOMContentLoaded', function() {
alert(33);
})
// load 等页面内容全部加载完毕,包含页面dom元素 图片 flash css 等等
// DOMContentLoaded 是DOM 加载完毕,不包含图片 falsh css 等就可以执行 加载速度比 load更快一些
</script>
</head>
<body>
<button>点击</button>
</body>
</html>
窗口大小变化
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
window.addEventListener('resize',function(){
console.log(window.innerWidth)
})
</script>
</body>
</html>~~~
<h3>4.定时器</h3>
<h4>1.定时器的两种方式</h4>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
// 1. setInterval
// 语法规范: window.setInterval(调用函数, 延时时间);
setInterval(function() {
console.log('继续输出');
}, 1000);
// 2. setTimeout 延时时间到了,就去调用这个回调函数,只调用一次 就结束了这个定时器
// 3. setInterval 每隔这个延时时间,就去调用这个回调函数,会调用很多次,重复调用这个函数
</script>
</body>
~~~
倒计时效果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
div {
margin: 180px;
}
span {
display: inline-block;
width: 50px;
height: 50px;
background-color: #333;
font-size: 20px;
color: #fff;
text-align: center;
line-height: 50px;
}
</style>
</head>
<body>
<div>
<span class="day">t</span>
<span class="hour">1</span>
<span class="minute">2</span>
<span class="second">3</span>
</div>
<script>
// 1. 获取元素
var day = document.querySelector('.day');//天数的黑盒子
var hour = document.querySelector('.hour'); // 小时的黑色盒子
var minute = document.querySelector('.minute'); // 分钟的黑色盒子
var second = document.querySelector('.second'); // 秒数的黑色盒子
var inputTime = +new Date('2035-5-1 18:00:00'); // 返回的是用户输入时间总的毫秒数
countDown(); // 我们先调用一次这个函数,防止第一次刷新页面有空白
// 2. 开启定时器,每隔一秒调用一次countDown
setInterval(countDown, 1000);
function countDown() {
var nowTime = +new Date(); // 返回的是当前时间总的毫秒数
var times = (inputTime - nowTime) / 1000; // times是剩余时间总的秒数
var d = parseInt(times / 60 /60 /24); //天
d = d < 10 ? '0' + d : d;
day.innerHTML = d
var h = parseInt(times / 60 / 60 % 24); //时
h = h < 10 ? '0' + h : h;
hour.innerHTML = h; // 把剩余的小时给 小时黑色盒子
var m = parseInt(times / 60 % 60); // 分
m = m < 10 ? '0' + m : m;
minute.innerHTML = m;
var s = parseInt(times % 60); // 当前的秒
s = s < 10 ? '0' + s : s;
second.innerHTML = s;
}
</script>
</body>
</html>
清楚setInterva
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<button class="begin">开启定时器</button>
<button class="stop">停止定时器</button>
<script>
var begin = document.querySelector('.begin')
var stop = document.querySelector('.stop')
var timer
begin.addEventListener('click',function(){
timer = setInterval(function(){
console.log('ni hao ma')
},1000);
})
stop.addEventListener('click',function(){
clearInterval(timer)
})
</script>
</body>
</html>
发送验证码倒计时案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
验证码: <input type="number"> <button>发送</button>
<script>
// 按钮点击之后,会禁用 disabled 为true
// 同时按钮里面的内容会变化, 注意 button 里面的内容通过 innerHTML修改
// 里面秒数是有变化的,因此需要用到定时器
// 定义一个变量,在定时器里面,不断递减
// 如果变量为0 说明到了时间,我们需要停止定时器,并且复原按钮初始状态
var btn = document.querySelector('button')
var time = 3
var timer = null
btn.addEventListener('click',function(){
btn.disabled = true
timer = setInterval(caltime,1000)
function caltime(){
if(time > 0){
btn.innerHTML = time + '秒之后重新发送'
time = time - 1
}else{
clearInterval(timer)
btn.disabled = false
btn.innerHTML = '发送'
time = 3
}
}
})
</script>
</body>
</html>
5.JS执行机制
同步和异步
为了解决这个问题,利用多核 CPU 的计算能力,HTML5 提出 Web Worker 标准,允许 JavaScript 脚本创 建多个线程。于是,JS 中出现了同步和异步。 同步 前一个任务结束后再执行后一个任务,程序的执行顺序与任务的排列顺序是一致的、同步的。比如做饭的同步做 法:我们要烧水煮饭,等水开了(10分钟之后),再去切菜,炒菜。 异步 你在做一件事情时,因为这件事情会花费很长时间,在做这件事的同时,你还可以去处理其他事情。比如做 饭的异步做法,我们在烧水的同时,利用这10分钟,去切菜,炒菜。 他们的本质区别: 这条流水线上各个流程的执行顺序不同。js将代码中的任务分为同步任务和异步任务(事件),运行的时候会先运行同步任务然后在运行异步任务
6.location 对象
1.location对象属性
2.页面自动跳转案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div></div>
<script>
var div = document.querySelector('div')
var time = 3
setInterval(function(){
if(time == 0){
location.href = 'http://www.itcast.cn'
}else{
div.innerHTML = '将在'+time+'秒之后自动跳转'
time --;
}
},1000)
</script>
</body>
</html>
获取URL参数案例
login界面<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<form action="index.html">
账号:<input type="text" name="uname">
<input type="submit">
</form>
</body>
</html>
index界面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
欢迎进入首页
<script>
console.log(location.search)//获取页面参数 ?uname='aaa'
//substr('起始位置','截取几个字符')但第二个参数省略的时候默认截取到最后一个字符
var query = location.search.substr(1,location.search.length-1)
console.log(query)
//利用=把字符串分割为数组split('=');
var arr = query.split('=')
console.log(arr[1])
</script>
</body>
</html>
location常见方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<button>点击</button>
<script>
var btn = document.querySelector('button');
btn.addEventListener('click', function () {
// 记录浏览历史,所以可以实现后退功能
// location.assign('http://www.itcast.cn');
// 不记录浏览历史,所以不可以实现后退功能
// location.replace('http://www.itcast.cn');
location.reload(true);
})
</script>
</body>
</html>
7.navigator 对象
navigator 对象包含有关浏览器的信息,它有很多属性,我们最常用的是 userAgent,该属性可以返回由客 户机发送服务器的 user-agent 头部的值。 下面前端代码可以判断用户那个终端打开页面,实现跳转if((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android| Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS |Symbian|Windows Phone)/i))) {
window.location.href = ""; //手机 } else {
window.location.href = ""; //电脑 }
8.history 对象
window 对象给我们提供了一个 history 对象,与浏览器历史记录进行交互。该对象包含用户(在浏览器窗口中) 访问过的 URL。八、操作DOM对象(重点)
1.核心
浏览器网页就是一个dom树形结构
- 跟心Dom节点
- 遍历dom节点:得到Dom节点
- 删除:删除一个Dom节点
- 添加:添加一个新的节点
2.获得dom节点
点击查看代码
<body>
<div id="father">
<h1>标题</h1>
<p id="p1">段落1</p>
<p class="p2">段落2</p>
</div>
<script>
var h1 = document.getElementsByTagName('h1');//获取标签选择器
var p1 = document.getElementById('p1');//获取id选择器
var p2 = document.getElementsByClassName('p2');//获取类选择器
var father = document.getElementById('father');//获取id选择器
console.log(father.children);//获取父节点下的所有子节点
// console.log(father.firstChild);//获取父节点下的第一个节点
// console.log(father.lastChild);//获取父节点下的最后一个节点
</script>
</body>
3.更新节点
点击查看代码
<body>
<div id="div">
</div>
<script>
var div1 = document.getElementById('div');
console.log(div1);
div1.innertext='123'//修改网页内容的值
</script>
</body>
div1.innerHTML='<strong>123</strong>'
操作JS:属性使用字符串包裹
4.删除节点
(1)删除节点的步骤:
①先获取父节点,如:p1.parentElement; ②在通过父节点删除自己:father.remove(p1.parentElement); 也可以直接通过下图删除指定节点
还可通过数组来删除
注意:删除多个节点的时候,children是在时刻变化的,删除节点的时候一定要注意
5.插入节点
我们获得了某个DOM节点,假设这个dom节点是空的,我们通过innerHTML就可以增加一个元素了,但是这个DOM节点已经存在元素了,我们就不能这么干,会产生覆盖(1)追加
目的:将div外面的p标签加到div内部点击查看代码
<body>
<p id="js">TWQ</p>
<div id="div">
<p id="'se">javaSE</p>
<p id="ee">JavaEE</p>
<p id="me">javaME</p>
</div>
<script>
var js = document.getElementById('js');
var div = document.getElementById('div');
</script>
</body>
(2)创建一个标签并实现插入
目的:新建一个p标签并将其加入div标签中点击查看代码
<body>
<!--<p id="js">TWQ</p>-->
<div id="div">
<p id="'se">javaSE</p>
<p id="ee">JavaEE</p>
<p id="me">javaME</p>
</div>
<script>
// var js = document.getElementById('js');
var div = document.getElementById('div');
var newp = document.createElement('p')//创建一个p标签
newp.id = 'newp';//设置id选择器的名称,等价于<p id="newp"></p>
newp.innerText="Twqwq123"//等价于<p id="newp">Twqwq123</p>
</script>
</body>
目的:实现创建一个标签自带属性和值,并加入到div标签中
点击查看代码
<body>
<div id="div">
<p id="'se">javaSE</p>
<p id="ee">JavaEE</p>
<p id="me">javaME</p>
</div>
<script>
var div = document.getElementById('div');
//创建一个带值的标签
var myScript = document.createElement('script');
myScript.setAttribute('type','text/javascript');
</script>
</body>
6.操作元素
目标:点击谁的按钮显示谁的图片点击查看代码
<body>
<button id="btn">唐伯虎</button><br>
<button id="ldh">刘德华</button><br>
<button id="zxy">张学友</button><br>
<img src="./images/ldh.png" alt="">
<script>
//1.事件是有三部分组成 事件源 事件类型 事件处理程序 我们也称为事件三要素
//(1)事件源 事件被触发的对象
var btn = document.getElementById('btn');
//(2)事件类型 如何触发 什么事件 比如鼠标点击(onclick)还是鼠标经过 还是键盘按下
//(3)事件处理程序 通过一个函数赋值的方式 完成
btn.onclick = function () {
alert('点秋香');
}
//案例2:点击谁的按钮显示谁的图片
//修改元素属性 src
// 1.获取元素
var ldh = document.getElementById('ldh');
var zxy = document.getElementById('zxy');
var imgs = document.querySelector('img');
//2.注册事件
ldh.onclick = function () {
imgs.src = './images/ldh.png';
}
zxy.onclick = function () {
imgs.src = './images/zxy.png';
}
</script>
</body>
7.事件
7.1常用事件
7.2注册事件的两种方式
给元素添加事件,称为注册事件或者绑定事件,注册事件有两种方式:传统方式和方法监听主册方式<body>
<button>传统注册事件</button>
<button>方法监听注册事件</button>
<button>ie9 attachEvent</button>
<script>
var btns = document.querySelectorAll('button');
// 1. 传统方式注册事件
btns[0].onclick = function() {
alert('hi');
}
//传统注册方式同一个元素,同一个事件只会执行最后一个事
btns[0].onclick = function() {
alert('hao a u');
}
// 2. 事件侦听注册事件 addEventListener
// (1) 里面的事件类型是字符串 必定加引号 而且不带on
// (2) 同一个元素 同一个事件可以添加多个侦听器(事件处理程序)
btns[1].addEventListener('click', function() {
alert(22);
})
btns[1].addEventListener('click', function() {
alert(33);
})
// 3. attachEvent ie9以前的版本支持
btns[2].attachEvent('onclick', function() {
alert(11);
})
</script>
</body>
传统注册方式
利用 on 开头的事件 onclick
btn.onclick = function() {}
特点: 注册事件的唯一性
同一个元素同一个事件只能设置一个处理函数,最 后注册的处理函数将会覆盖前面注册的处理函数
方法监听注册方式
w3c 标准 推荐方式 addEventListener() 它是一个方法
IE9 之前的 IE 不支持此方法,可使用 attachEvent() 代替
特点:同一个元素同一个事件可以注册多个监听器
按注册顺序依次执行
7.3删除事件的两种方式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
div {
width: 100px;
height: 100px;
background-color: pink;
}
</style>
</head>
<body>
<div>1</div>
<div>2</div>
<div>3</div>
<script>
var divs = document.querySelectorAll('div');
divs[0].onclick = function () {
alert(11);
// 1. 传统方式删除事件
divs[0].onclick = null;
}
// 2. removeEventListener 删除事件
divs[1].addEventListener('click', fn) // 里面的fn 不需要调用加小括号
function fn() {
alert(22);
divs[1].removeEventListener('click', fn);
}
// 3. detachEvent
divs[2].attachEvent('onclick', fn1);
function fn1() {
alert(33);
divs[2].detachEvent('onclick', fn1);
}
</script>
</body>
</html>
7.4DOM事件流的三个阶段
事件流描述的是从页面中接收事件的顺序。事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即 DOM 事件流。
比如我们给一个div 注册了点击事件:
DOM 事件流分为3个阶段:
1. 捕获阶段
2. 当前目标阶段 3. 冒泡阶段
事件冒泡: IE 最早提出,事件开始时由最具体的元素接收,然后逐级向上传播到到 DOM 最顶层节点的过程。
事件捕获: 网景最早提出,由 DOM 最顶层节点开始,然后逐级向下传播到到最具体的元素接收的过程。
形象解释就是:
我们向水里面扔一块石头,首先它会有一个下降的过程,这个过程就可以理解为从最顶层向事件发生的最具 体元素(目标点)的捕获过程;之后会产生泡泡,会在最低点( 最具体元素)之后漂浮到水面上,这个过 程相当于事件冒泡。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.father {
overflow: hidden;
width: 300px;
height: 300px;
margin: 100px auto;
background-color: pink;
text-align: center;
}
.son {
width: 200px;
height: 200px;
margin: 50px;
background-color: purple;
line-height: 200px;
color: #fff;
}
</style>
</head>
<body>
<div class="father">
<div class="son">son盒子</div>
</div>
<script>
// dom 事件流 三个阶段
// 1. JS 代码中只能执行捕获或者冒泡其中的一个阶段。
// 2. onclick 和 attachEvent(ie) 只能得到冒泡阶段。
// 3. 捕获阶段 如果addEventListener 第三个参数是 true 那么则处于捕获阶段 document -> html -> body -> father -> son
// var son = document.querySelector('.son');
// son.addEventListener('click', function() {
// alert('son');
// }, true);
//如果给father也绑定了事件,由于处于捕获阶段,点击son会先处理father的点
击事件然后才处理son的点击事件
// var father = document.querySelector('.father');
// father.addEventListener('click', function() {
// alert('father');
// }, true);
// 4. 冒泡阶段 如果addEventListener 第三个参数是 false 或者 省略 那么则处于冒泡阶段 son -> father ->body -> html -> document
var son = document.querySelector('.son');
son.addEventListener('click', function () {
alert('son');
}, false);
var father = document.querySelector('.father');
father.addEventListener('click', function () {
alert('father');
}, false);
document.addEventListener('click', function () {
alert('document');
})
</script>
</body>
</html>
冒泡阶段结果图
注意:
- JS 代码中只能执行捕获或者冒泡其中的一个阶段。
- onclick 和 attachEvent 只能得到冒泡阶段。
- addEventListener(type, listener[, useCapture])第三个参数如果是 true,表示在事件捕 获阶段调用事件处理程序;如果是 false(不写默认就是false),表示在事件冒泡阶段调用事件处理 程序。
- 实际开发中我们很少使用事件捕获,我们更关注事件冒泡。
- 有些事件是没有冒泡的,比如 onblur、onfocus、onmouseenter、onmouseleave
- 事件冒泡有时候会带来麻烦,有时候又会帮助很巧妙的做某些事件,我们后面讲解。
7.5利用事件对象完成跟随鼠标案例
常见事件对象的属性和方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
div {
width: 100px;
height: 100px;
background-color: pink;
}
</style>
</head>
<body>
<div>
<ul>
<li>123</li>
</ul>
</div>
<script>
/*var div = document.querySelector('div')
div.addEventListener('click',function(e){
console.log(e.target)
console.log(div)
}) */
var ul = document.querySelector('ul')
ul.addEventListener('click',function(e){
//e.target指向我们点击的那个对象 谁触发了这个事件他就指向谁
console.log(e.target)
//给ul绑定的事件,this就指向的是ul
console.log(this)
})
</script>
</body>
</html>
7.6封装阻止冒泡的兼容性函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.father {
overflow: hidden;
width: 300px;
height: 300px;
margin: 100px auto;
background-color: pink;
text-align: center;
}
.son {
width: 200px;
height: 200px;
margin: 50px;
background-color: purple;
line-height: 200px;
color: #fff;
}
</style>
</head>
<body>
<div class="father">
<div class="son">son儿子</div>
</div>
<script>
// 常见事件对象的属性和方法
// 阻止冒泡 dom 推荐的标准 stopPropagation()
var son = document.querySelector('.son');
son.addEventListener('click', function (e) {
alert('son');
e.stopPropagation(); // stop 停止 Propagation 传播
e.cancelBubble = true; // 非标准 cancel 取消 bubble 泡泡
}, false);
var father = document.querySelector('.father');
father.addEventListener('click', function () {
alert('father');
}, false);
document.addEventListener('click', function () {
alert('document');
})
</script>
</body>
</html>
7.7事件委托原理
不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点。以下案例:给 ul 注册点击事件,然后利用事件对象的 target 来找到当前点击的 li,因为点击 li,事件会冒泡到 ul 上, ul 有注册事件,就会触发事件监听器。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<ul>
<li>知否知否,点我应有弹框在手!</li>
<li>知否知否,点我应有弹框在手!</li>
<li>知否知否,点我应有弹框在手!</li>
<li>知否知否,点我应有弹框在手!</li>
<li>知否知否,点我应有弹框在手!</li>
</ul>
<script>
// 事件委托的核心原理:给父节点添加侦听器, 利用事件冒泡影响每一个子节点
var ul = document.querySelector('ul');
ul.addEventListener('click', function (e) {
// alert('知否知否,点我应有弹框在手!');
// e.target 这个可以得到我们点击的对象
e.target.style.backgroundColor = 'pink';
})
</script>
</body>
</html>
7.8常用鼠标和键盘事件
常用鼠标事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
fasffdsag
<script>
//禁止鼠标右键
document.addEventListener('contextmenu',function(e){
e.preventDefault();
})
//禁止选中文本
document.addEventListener('selectstart',function(e){
e.preventDefault();
})
</script>
</body>
</html>
鼠标事件对象
event对象代表事件的状态,跟事件相关的一系列信息的集合。现阶段我们主要是用鼠标事件对象 MouseEvent 和键盘事件对象 KeyboardEvent。<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
document.addEventListener('click', function (e) {
//clientX,clientY鼠标在可视区的距离
console.log(e.clientX)
console.log(e.clientY)
//pageX,pageY得到的是鼠标距离文档顶部的距离
//区别:clientY,pageY:当一个网页往下滚动了一段距离之后,
//clinetY表示鼠标距离当前可视窗口顶部的距离,而pageY表示鼠标到整个文档顶部的距离
console.log(e.pageX)
console.log(e.pageY)
})
</script>
</body>
</html>
跟随鼠标天使案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
img{
position:absolute;
}
</style>
</head>
<body>
<img src="../images/angel.gif" alt="">
<script>
var img = document.querySelector('img')
document.addEventListener('mousemove',function(e){
var x = e.pageX
var y = e.pageY
//不要忘记添加px
//想让鼠标在图片的中间 图片大小 96*80
img.style.left = x - 40 + 'px'
img.style.top = y - 40 + 'px'
console.log(e.pageX)
})
</script>
</body>
</html>
常用键盘事件
注意:
1. 如果使用addEventListener 不需要加 on
2. onkeypress 和前面2个的区别是,它不识别功能键,比如左右箭头,shift 等。
3. 三个事件的执行顺序是: keydown -- keypress --- keyup
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
//按键弹起时触发
document.onkeyup = function(){
console.log('弹起onkeyup')
}
document.addEventListener('keyup',function(){
console.log('弹起keyup')
})
//keydown执行优先级要高于keypress
document.addEventListener('keypress',function(){
console.log('按下keypress')
})
document.addEventListener('keydown',function(){
console.log('按下keydown')
})
</script>
</body>
</html>
键盘事件案例
模仿京东界面按下s键之后光标自动定位到搜索框
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<input type="text">
<script>
//判断用户是否按下s键,如果按下s键,就把光标定位到搜索框里面
var search = document.querySelector('input')
document.addEventListener('keyup',function(e){
console.log(e.key)//按下的是键盘的哪个键,并且区分大小写
//if(e.key === 's'){
// search.focus();
// }
//s字母的ASCLL值为83
if(e.keyCode === 83){
search.focus();
}
})
</script>
</body>
</html>
京东快递单号查寻
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.search {
position: relative;
width: 178px;
margin: 100px;
}
.con {
display: none;
position: absolute;
top: -40px;
width: 171px;
border: 1px solid rgba(0, 0, 0, .2);
box-shadow: 0 2px 4px rgba(0, 0, 0, .2);
padding: 5px 0;
font-size: 18px;
line-height: 20px;
color: #333;
}
.con::before {
content: '';
width: 0;
height: 0;
position: absolute;
top: 28px;
left: 18px;
border: 8px solid #000;
border-style: solid dashed dashed;
/*一个正方形分成了四个三角形,border-color: #fff transparent transparent;上面三角形的背景颜色为白色,左右三角形隐藏,下边三角形隐藏*/
border-color: #fff transparent transparent;
}
</style>
</head>
<body>
<div class="search">
<div class="con">123</div>
<input type="text" placeholder="请输入您的快递单号" class="jd">
</div>
<script>
// 快递单号输入内容时, 上面的大号字体盒子(con)显示(这里面的字号更大)
// 表单检测用户输入: 给表单添加键盘事件
// 同时把快递单号里面的值(value)获取过来赋值给 con盒子(innerText)做为内容
// 如果快递单号里面内容为空,则隐藏大号字体盒子(con)盒子
var dcon = document.querySelector('.con')
var input = document.querySelector('.jd')
input.addEventListener('keyup',function(){//这里不能用keydown事件,因为这个事件在按键按下立马会触发事件,但是值还没有输入到输入框里
if(this.value == ''){
dcon.style.display = 'none'
}else{
dcon.style.display = 'block'
dcon.innerHTML = this.value
}
})
</script>
</body>
九、操作表单
1.获得表单的值
点击查看代码
<body>
<p>
<span>用户名:</span><input type="text" id="username">
</p>
<script>
var input_text = document.getElementById('username');
//得到输入框的值
input_text.value
</script>
</body>
2.修改表单的值
点击查看代码
<body>
<p>
<span>用户名:</span><input type="text" id="username">
</p>
<script>
var input_text = document.getElementById('username');
//得到输入框的值
input_text.value
// //修改输入框的值
input_text.value='124';
</script>
</body>
3.获取与修改单选框的状态
点击查看代码
<body>
<p>
<span>用户名:</span><input type="text" id="username">
</p>
<p>
<span>性别:</span>
<input type="radio" name="sex" value="man" id="boy">男
<input type="radio" name="sex" value="girl" id="women">女
</p>
<script>
var input_text = document.getElementById('username');
var boy_radio = document.getElementById('boy');
var girl_radio = document.getElementById('women');
//得到输入框的值
input_text.value
//对于单选框,多选框等等固定的值,boy_radio.value只能取到当前的值
boy_radio.checked;//查看返回的结果,是否为true,如果为true,则被选中
girl_radio.checked = true;//赋值
</script>
</body>
4.表单提交验证
(1)表单验证放在按钮上
点击查看代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- MD5工具类-->
<script src="https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.min.js"></script>
</head>
<body>
<form action="#" method="post">
<p>
<span>用户名:</span><input type="text" id="username" name="username">
</p>
<p>
<span>密码:</span><input type="password" id="password" name="password">
</p>
<!-- 绑定事件 onclick 被点击-->
<button type="submit" onclick="aaa()">提交</button>
</form>
<script>
function aaa(){
var uname = document.getElementById('username');
var pwd = document.getElementById('password');
console.log(uname.value);
console.log(pwd.value);
//MD5算法,可对自己提交的密码进行加密,防止别人抓包的的时候抓到你提交的用户名及密码信息
pwd.value = md5(pwd.value);
console.log(pwd.value)
}
</script>
</body>
</html>
(2)验证作用于表单上
点击查看代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- MD5工具类-->
<script src="https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.min.js"></script>
</head>
<body>
<!--
表单绑定提交事件
onsubmit:绑定一个提交检测的函数,true,false
将这个结果返回给表单,使用onsubmit接收
-->
<form action="https://www.cnblogs.com/" method="post" onsubmit="return aaa()">
<p>
<span>用户名:</span><input type="text" id="username" name="username">
</p>
<p>
<span>密码:</span><input type="password" id="input_password" >
</p>
<input type="hidden" id="md5_password" name="password">
<!--绑定事件 onclick 按钮被点击时-->
<button type="submit">提交</button>
</form>
<script>
function aaa(){
alert(1);
var uname = document.getElementById('username');
var pwd = document.getElementById('input_password');
var md5pwd = document.getElementById('md5_password');
md5pwd.value = md5(pwd.value);
return true;//如果改为true,点击提交之后就可以跳转到博客园界面
}
</script>
</body>
</html>
十、jQuery
1.获取jQuery
jQuery库,里面存在大量的JavaScript函数点击查看代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!-- 方式一:线上导入的方式-->
<!-- <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>-->
<!-- 方式二:可以再jQuery官网下载
若在官网点击下载仅是在网页打开了一个文档,并没有实现文档的下载
可以按 alt + 鼠标左键或 option + 左键即可以文档的形式下载,然后导入项目中-->
<script src="lib/jquery-3.6.0.min.js"></script>
</head>
<body>
<a href="" id="text_jquery">点我</a>
<script>
document.getElementById('id');
//选择器就是css的选择器
$('#text_jquery').click(function (){
alert('你好,jQuery')
})
</script>
</body>
</html>
2.选择器
点击查看代码
<script>
//jQuery css中的选择器它全都能使用
$('p').click();//标签选择器
$('#id1').click();//id选择器
$('.class1').click();//class类选择器
</script>
3.jQuery事件
点击查看代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="lib/jquery-3.6.0.js"></script>
<style>
#divMove{
width: 500px;
height: 500px;
border: 1px solid red;
}
</style>
</head>
<body>
<!--要求:获取鼠标当前的一个坐标-->
mouse:<span id="mouseMove"></span>
<div id="divMove">
在这里点击试试
</div>
<script>
//当网页元素加载完毕之后,响应事件
//document:当前网页
//ready:网页加载完之后要做的事
// $(document).ready(function (){
//
// })
//上诉可简化为
$(function (){
$('#divMove').mousemove(function (e){
$('#mouseMove').text('x:'+e.pageX+'y:'+e.pageY)
})
});
</script>
</body>
</html>
4.操作DOM元素
点击查看代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="lib/jquery-3.6.0.js"></script>
</head>
<body>
<ul id="test-ul">
<li class="js">javaScript</li>
<li name="python">python</li>
</ul>
<script>
$('#test-ul li[name=python]').text();//获取div标签下的ul里li的name=python的值
$('#test-ul li[name=python]').text('设置的值');//修改div标签下的ul里li的name=python的值
//css的操作
$('#test-ul li[name=python]').css({"color","red"})
</script>
</body>
</html>
十一、PC段网页特效
1.元素偏移量 offset 系列
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.father {
/* position: relative; */
width: 200px;
height: 200px;
background-color: pink;
margin: 150px;
}
.son {
width: 100px;
height: 100px;
background-color: purple;
margin-left: 45px;
}
.w {
width: 200px
height: 200px;
background-color: skyblue;
margin: 0 auto 200px;
padding: 10px;
border: 15px solid red;
}
</style>
</head>
<body>
<div class="father">
<div class="son"></div>
</div>
<div class="w"></div>
<script>
// offset 系列
var father = document.querySelector('.father');
var son = document.querySelector('.son');
// 1.可以得到元素的偏移 位置 返回的不带单位的数值
console.log(father.offsetTop);
console.log(father.offsetLeft);
// 它以带有定位的父亲为准 如果么有父亲或者父亲没有定位 则以 body 为准
console.log(son.offsetLeft);
var w = document.querySelector('.w');
// 2.可以得到元素的大小 宽度和高度 是包含padding + border + width
console.log(w.offsetWidth);
console.log(w.offsetHeight);
// 3. 返回带有定位的父亲 否则返回的是body
console.log(son.offsetParent); // 返回带有定位的父亲 否则返回的是body
console.log(son.parentNode); // 返回父亲 是最近一级的父亲 亲爸爸 不管父亲有没有定位
</script>
</body>
</html>
拖动的模态框
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
.login-header {
width: 100%;
text-align: center;
height: 30px;
font-size: 24px;
line-height: 30px;
}
ul,
li,
ol,
dl,
dt,
dd,
div,
p,
span,
h1,
h2,
h3,
h4,
h5,
h6,
a {
padding: 0px;
margin: 0px;
}
.login {
display: none;
width: 512px;
height: 280px;
position: fixed;
border: #ebebeb solid 1px;
left: 50%;
top: 50%;
background: #ffffff;
box-shadow: 0px 0px 20px #ddd;
z-index: 9999;
transform: translate(-50%, -50%);
}
.login-title {
width: 100%;
margin: 10px 0px 0px 0px;
text-align: center;
line-height: 40px;
height: 40px;
font-size: 18px;
position: relative;
cursor: move;
}
.login-input-content {
margin-top: 20px;
}
.login-button {
width: 50%;
margin: 30px auto 0px auto;
line-height: 40px;
font-size: 14px;
border: #ebebeb 1px solid;
text-align: center;
}
.login-bg {
display: none;
width: 100%;
height: 100%;
position: fixed;
top: 0px;
left: 0px;
background: rgba(0, 0, 0, .3);
}
a {
text-decoration: none;
color: #000000;
}
.login-button a {
display: block;
}
.login-input input.list-input {
float: left;
line-height: 35px;
height: 35px;
width: 350px;
border: #ebebeb 1px solid;
text-indent: 5px;
}
.login-input {
overflow: hidden;
margin: 0px 0px 20px 0px;
}
.login-input label {
float: left;
width: 90px;
padding-right: 10px;
text-align: right;
line-height: 35px;
height: 35px;
font-size: 14px;
}
.login-title span {
position: absolute;
font-size: 12px;
right: -20px;
top: -30px;
background: #ffffff;
border: #ebebeb solid 1px;
width: 40px;
height: 40px;
border-radius: 20px;
}
</style>
</head>
<body>
<div class="login-header"><a id="link" href="javascript:;">点击,弹出登录框</a></div>
<div id="login" class="login">
<div id="title" class="login-title">登录会员
<span><a id="closeBtn" href="javascript:void(0);" class="close-login">关闭</a></span>
</div>
<div class="login-input-content">
<div class="login-input">
<label>用户名:</label>
<input type="text" placeholder="请输入用户名" name="info[username]" id="username" class="list-input">
</div>
<div class="login-input">
<label>登录密码:</label>
<input type="password" placeholder="请输入登录密码" name="info[password]" id="password" class="list-input">
</div>
</div>
<div id="loginBtn" class="login-button"><a href="javascript:void(0);" id="login-button-submit">登录会员</a></div>
</div>
<!-- 遮盖层 -->
<div id="bg" class="login-bg"></div>
<script>
// 1. 获取元素
var login = document.querySelector('.login');
var mask = document.querySelector('.login-bg');
var link = document.querySelector('#link');
var closeBtn = document.querySelector('#closeBtn');
var title = document.querySelector('#title');
// 2. 点击弹出层这个链接 link 让mask 和login 显示出来
link.addEventListener('click', function() {
mask.style.display = 'block';
login.style.display = 'block';
})
// 3. 点击 closeBtn 就隐藏 mask 和 login
closeBtn.addEventListener('click', function() {
mask.style.display = 'none';
login.style.display = 'none';
})
// 4. 开始拖拽
// (1) 当我们鼠标按下, 就获得鼠标在盒子内的坐标
title.addEventListener('mousedown', function(e) {
var x = e.pageX - login.offsetLeft;
var y = e.pageY - login.offsetTop;
// (2) 鼠标移动的时候,把鼠标在页面中的坐标,减去 鼠标在盒子内的坐标就是模态框的left和top值
document.addEventListener('mousemove', move)
function move(e) {
//这里要使用style来进行赋值,offset只能获取值
login.style.left = e.pageX - x + 'px';
login.style.top = e.pageY - y + 'px';
}
// (3) 鼠标弹起,就让鼠标移动事件移除
document.addEventListener('mouseup', function() {
document.removeEventListener('mousemove', move);
})
})
</script>
</body>
</html>
图片放大镜案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>手机详情页!</title>
<meta name="description"
content="品优购JD.COM-专业的综合网上购物商城,销售家电、数码通讯、电脑、家居百货、服装服饰、母婴、图书、食品等数万个品牌优质商品.便捷、诚信的服务,为您提供愉悦的网上购物体验!" />
<meta name="Keywords" content="网上购物,网上商城,手机,笔记本,电脑,MP3,CD,VCD,DV,相机,数码,配件,手表,存储卡,品优购" />
<style>
.de_container {
margin-top: 20px;
}
.crumb_wrap {
height: 25px;
}
.crumb_wrap a {
margin-right: 10px;
}
.preview_wrap {
width: 400px;
height: 590px;
}
.preview_img {
position: relative;
height: 398px;
border: 1px solid #ccc;
}
.mask {
display: none;
position: absolute;
top: 0;
left: 0;
width: 300px;
height: 300px;
background: #FEDE4F;
opacity: .5;
border: 1px solid #ccc;
cursor: move;
}
.big {
display: none;
position: absolute;
left: 410px;
top: 0;
width: 500px;
height: 500px;
background-color: pink;
z-index: 999;
border: 1px solid #ccc;
overflow: hidden;
}
.big img {
position: absolute;
top: 0;
left: 0;
}
</style>
</head>
<body>
<!-- 详情页内容部分 -->
<div class="de_container w">
<!-- 产品介绍模块 -->
<div class="product_intro clearfix">
<!-- 预览区域 -->
<div class="preview_wrap fl">
<div class="preview_img">
<img src="../images/s3.png" alt="">
<div class="mask"></div>
<div class="big">
<img src="../images/big.jpg" alt="" class="bigImg">
</div>
</div>
</div>
</div>
</div>
<script>
//等页面加载完毕在进行操作
window.addEventListener('load',function(){
var preview_img = document.querySelector('.preview_img')
var mask = document.querySelector('.mask')
var big = document.querySelector('.big')
preview_img.addEventListener('mouseover',function(){
mask.style.display = 'block'
big.style.display = 'block'
})
preview_img.addEventListener('mouseout',function(){
mask.style.display = 'none'
big.style.display = 'none'
})
preview_img.addEventListener('mousemove',move)
function move(e){
var x = e.pageX - this.offsetLeft - mask.offsetWidth / 2
var y = e.pageY - this.offsetTop - mask.offsetWidth / 2
var maskMaxlength = preview_img.offsetWidth - mask.offsetWidth
if(x <= 0){
x = 0
}
if(y <= 0){
y = 0
}
if(x >= maskMaxlength){
x = maskMaxlength
}
if (y >= maskMaxlength){
y = maskMaxlength
}
mask.style.left = x + 'px'
mask.style.top = y + 'px'
// 大图片的移动距离 / 大图片的最大移动距离 = 遮挡层移动距离 / 遮挡层的最大移动距离
var bigImg = document.querySelector('.bigImg')
//大图片的最大移动距离
var bigmaxlength = big.offsetWidth - bigImg.offsetWidth
var bigX = x * bigmaxlength / maskMaxlength
var bigY = y * bigmaxlength / maskMaxlength
bigImg.style.left = bigX + 'px'
bigImg.style.top = bigY + 'px'
}
})
</script>
</body>
</html><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>手机详情页!</title>
<meta name="description"
content="品优购JD.COM-专业的综合网上购物商城,销售家电、数码通讯、电脑、家居百货、服装服饰、母婴、图书、食品等数万个品牌优质商品.便捷、诚信的服务,为您提供愉悦的网上购物体验!" />
<meta name="Keywords" content="网上购物,网上商城,手机,笔记本,电脑,MP3,CD,VCD,DV,相机,数码,配件,手表,存储卡,品优购" />
<style>
.de_container {
margin-top: 20px;
}
.crumb_wrap {
height: 25px;
}
.crumb_wrap a {
margin-right: 10px;
}
.preview_wrap {
width: 400px;
height: 590px;
}
.preview_img {
position: relative;
height: 398px;
border: 1px solid #ccc;
}
.mask {
display: none;
position: absolute;
top: 0;
left: 0;
width: 300px;
height: 300px;
background: #FEDE4F;
opacity: .5;
border: 1px solid #ccc;
cursor: move;
}
.big {
display: none;
position: absolute;
left: 410px;
top: 0;
width: 500px;
height: 500px;
background-color: pink;
z-index: 999;
border: 1px solid #ccc;
overflow: hidden;
}
.big img {
position: absolute;
top: 0;
left: 0;
}
</style>
</head>
<body>
<!-- 详情页内容部分 -->
<div class="de_container w">
<!-- 产品介绍模块 -->
<div class="product_intro clearfix">
<!-- 预览区域 -->
<div class="preview_wrap fl">
<div class="preview_img">
<img src="../images/s3.png" alt="">
<div class="mask"></div>
<div class="big">
<img src="../images/big.jpg" alt="" class="bigImg">
</div>
</div>
</div>
</div>
</div>
<script>
//等页面加载完毕在进行操作
window.addEventListener('load',function(){
var preview_img = document.querySelector('.preview_img')
var mask = document.querySelector('.mask')
var big = document.querySelector('.big')
preview_img.addEventListener('mouseover',function(){
mask.style.display = 'block'
big.style.display = 'block'
})
preview_img.addEventListener('mouseout',function(){
mask.style.display = 'none'
big.style.display = 'none'
})
preview_img.addEventListener('mousemove',move)
function move(e){
var x = e.pageX - this.offsetLeft - mask.offsetWidth / 2
var y = e.pageY - this.offsetTop - mask.offsetWidth / 2
var maskMaxlength = preview_img.offsetWidth - mask.offsetWidth
if(x <= 0){
x = 0
}
if(y <= 0){
y = 0
}
if(x >= maskMaxlength){
x = maskMaxlength
}
if (y >= maskMaxlength){//因为盒子是个正方形,所以可以用动y上
y = maskMaxlength
}
mask.style.left = x + 'px'
mask.style.top = y + 'px'
// 大图片的移动距离 / 大图片的最大移动距离 = 遮挡层移动距离 / 遮挡层的最大移动距离
var bigImg = document.querySelector('.bigImg')
//大图片的最大移动距离
var bigmaxlength = big.offsetWidth - bigImg.offsetWidth
var bigX = x * bigmaxlength / maskMaxlength
var bigY = y * bigmaxlength / maskMaxlength
//bigImg必须要有定位才行
bigImg.style.left = bigX + 'px'
bigImg.style.top = bigY + 'px'
}
})
</script>
</body>
</html>
2.元素可视区 client 系列
client 翻译过来就是客户端,我们使用 client 系列的相关属性来获取元素可视区的相关信息。通过 client 系列 的相关属性可以动态的得到该元素的边框大小、元素大小等。
淘宝 flexible.js 源码分析
flexible.js是手淘开发出的一个用来适配移动端的js框架。手淘框架的核心原理就是根据制不同的width给网页中html根节点设置不同的font-size,然后所有的px都用rem来代替,这样就实现了不同大小的屏幕都适应相同的样式了。其实它就是一个终端设备适配的解决方案,也就是说它可以让你在不同的终端设备中实现页面适配。
(function flexible(window, document) {
var docEl = document.documentElement
var dpr = window.devicePixelRatio || 1
// adjust body font size
function setBodyFontSize() {
if (document.body) {
document.body.style.fontSize = (12 * dpr) + 'px'
} else {
document.addEventListener('DOMContentLoaded', setBodyFontSize)
}
}
setBodyFontSize();
// set 1rem = viewWidth / 10
function setRemUnit() {
var rem = docEl.clientWidth / 10
docEl.style.fontSize = rem + 'px'
}
setRemUnit()
// reset rem unit on page resize
window.addEventListener('resize', setRemUnit)
window.addEventListener('pageshow', function(e) {
if (e.persisted) {
setRemUnit()
}
})
// detect 0.5px supports
if (dpr >= 2) {
var fakeBody = document.createElement('body')
var testElement = document.createElement('div')
testElement.style.border = '.5px solid transparent'
fakeBody.appendChild(testElement)
docEl.appendChild(fakeBody)
if (testElement.offsetHeight === 1) {
docEl.classList.add('hairlines')
}
docEl.removeChild(fakeBody)
}
}(window, document))
立即执行函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>手机详情页!</title>
<meta name="description"
content="品优购JD.COM-专业的综合网上购物商城,销售家电、数码通讯、电脑、家居百货、服装服饰、母婴、图书、食品等数万个品牌优质商品.便捷、诚信的服务,为您提供愉悦的网上购物体验!" />
<meta name="Keywords" content="网上购物,网上商城,手机,笔记本,电脑,MP3,CD,VCD,DV,相机,数码,配件,手表,存储卡,品优购" />
</head>
<body>
<script>
//普通函数
function fn(){
console.log(1);
}
fn();//当有多个函数时每个函数之间需要使用分号来结尾
//立即执行函数:不需要调用,立马能够自己执行的函数
//写法:(function(){})() 第二个小括号相当于调用函数 或者 (function(){}())
(function(a,b){
console.log(a + b);
})(1,2)
</script>
</body>
</html>
3.元素滚动 scroll 系列
scroll 翻译过来就是滚动的,我们使用 scroll 系列的相关属性可以动态的得到该元素的大小、滚动距离等。<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.slider-bar {
position: absolute;
left: 50%;
top: 300px;
margin-left: 600px;
width: 45px;
height: 130px;
background-color: pink;
}
.w {
width: 1200px;
margin: 10px auto;
}
.header {
height: 150px;
background-color: purple;
}
.banner {
height: 250px;
background-color: skyblue;
}
.main {
height: 1000px;
background-color: yellowgreen;
}
span {
display: none;
position: absolute;
bottom: 0;
}
</style>
</head>
<body>
<div class="slider-bar">
<span class="goBack">返回顶部</span>
</div>
<div class="header w">头部区域</div>
<div class="banner w">banner区域</div>
<div class="main w">主体部分</div>
<script>
//1. 获取元素
var sliderbar = document.querySelector('.slider-bar');
var banner = document.querySelector('.banner');
// banner.offestTop 就是被卷去头部的大小 一定要写到滚动的外面
var bannerTop = banner.offsetTop
// 当我们侧边栏固定定位之后应该变化的数值
var sliderbarTop = sliderbar.offsetTop - bannerTop;
// 获取main 主体元素
var main = document.querySelector('.main');
var goBack = document.querySelector('.goBack');
var mainTop = main.offsetTop;
// 2. 页面滚动事件 scroll
document.addEventListener('scroll', function() {
// console.log(11);
// window.pageYOffset 页面被卷去的头部
// console.log(window.pageYOffset);
// 3 .当我们页面被卷去的头部大于等于了 172 此时 侧边栏就要改为固定定位
if (window.pageYOffset >= bannerTop) {
sliderbar.style.position = 'fixed';
sliderbar.style.top = sliderbarTop + 'px';
} else {
sliderbar.style.position = 'absolute';
sliderbar.style.top = '300px';
}
// 4. 当我们页面滚动到main盒子,就显示 goback模块
if (window.pageYOffset >= mainTop) {
goBack.style.display = 'block';
} else {
goBack.style.display = 'none';
}
})
</script>
</body>
</html>
4.动画函数封装
动画原理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
div {
position: absolute;
left: 0;
width: 100px;
height: 100px;
background-color: pink;
}
</style>
</head>
<body>
<div></div>
<script>
// 动画原理
// 1. 获得盒子当前位置
// 2. 让盒子在当前位置加上1个移动距离
// 3. 利用定时器不断重复这个操作
// 4. 加一个结束定时器的条件
// 5. 注意此元素需要添加定位, 才能使用element.style.left
var div = document.querySelector('div');
var timer = setInterval(function () {
if (div.offsetLeft >= 400) {
// 停止动画 本质是停止定时器
clearInterval(timer);
}
div.style.left = div.offsetLeft + 1 + 'px';
}, 30);
</script>
</body>
</html>
简单动画函数的封装
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
/**/
div {
position: absolute;/*定位必须得加*/
left: 0;
width: 100px;
height: 100px;
background-color: pink;
}
span {
position: absolute;/*定位必须得加*/
left: 0;
top: 200px;
display: block;
width: 150px;
height: 150px;
background-color: purple;
}
</style>
</head>
<body>
<div></div>
<span>夏雨荷</span>
<script>
var div = document.querySelector('div')
var span = document.querySelector('span')
animate(div,300)
animate(span,200)
//调用函数
function animate(obj,target){
clearInterval(obj.timer)//先清除以前定时器,只保留当前的一个定时器
obj.timer = setInterval(function(){
if(obj.offsetLeft > target){
clearInterval(obj.timer)
}
obj.style.left = obj.offsetLeft + 1 + 'px'
})
}
</script>
</body>
</html>
5.animate.js
function animate(obj, target, callback) {
// console.log(callback); callback = function() {} 调用的时候 callback()
// 先清除以前的定时器,只保留当前的一个定时器执行
clearInterval(obj.timer);
obj.timer = setInterval(function() {
// 步长值写到定时器的里面
// 把我们步长值改为整数 不要出现小数的问题
// var step = Math.ceil((target - obj.offsetLeft) / 10);
var step = (target - obj.offsetLeft) / 10;
step = step > 0 ? Math.ceil(step) : Math.floor(step);
if (obj.offsetLeft == target) {
// 停止动画 本质是停止定时器
clearInterval(obj.timer);
// 回调函数写到定时器结束里面
// if (callback) {
// // 调用函数
// callback();
// }
callback && callback();
}
// 把每次加1 这个步长值改为一个慢慢变小的值 步长公式:(目标值 - 现在的位置) / 10
obj.style.left = obj.offsetLeft + step + 'px';
}, 15);
}
引用动画函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.sliderbar {
position: fixed;
right: 0;
bottom: 100px;
width: 40px;
height: 40px;
text-align: center;
line-height: 40px;
cursor: pointer;
color: #fff;
}
.con {
position: absolute;
left: 0;
top: 0;
width: 200px;
height: 40px;
background-color: purple;
z-index: -1;
}
</style>
<script src="animate.js"></script>
</head>
<body>
<div class="sliderbar">
<span>←</span>
<div class="con">问题反馈</div>
</div>
<script>
// 1. 获取元素
var sliderbar = document.querySelector('.sliderbar');
var con = document.querySelector('.con');
// 当我们鼠标经过 sliderbar 就会让 con这个盒子滑动到左侧
// 当我们鼠标离开 sliderbar 就会让 con这个盒子滑动到右侧
sliderbar.addEventListener('mouseenter', function() {
// animate(obj, target, callback);
animate(con, -160, function() {
// 当我们动画执行完毕,就把 ← 改为 →
sliderbar.children[0].innerHTML = '→';
});
})
sliderbar.addEventListener('mouseleave', function() {
// animate(obj, target, callback);
animate(con, 0, function() {
sliderbar.children[0].innerHTML = '←';
});
})
</script>
</body>
</html>