黑马javascript笔记

JAVASCRIPT基础

一、javascript导读

1.1 历史

发明人:布兰登.艾奇

1.2 javascript是什么

运行在客户端的脚本语言

脚本语言:不需要编译,由js解释器逐行进行解释并执行

1.3作用

  • 表单验证
  • 网页特效
  • 服务端开发
  • 桌面程序
  • app
  • 控制硬件
  • 游戏开发

1.4 html/css/js关系

HTML/css为标记语言-描述类语言

js为脚本语言-编程类语言

1.5浏览器执行js

浏览器由渲染引擎和js引擎组成

  • 渲染引擎:解析HTML和CSS也就是内核
  • js引擎:用于读取网页中的js代码,比如chrome的v8

二、js三种书写位置

与css类似

1、行内式

  • 可以将单行或少量js代码写在HTML标签属性中(以on开头的属性),如:onclick
  • 特殊情况下使用
<input type="button" value="唐伯虎" onclick="alert('秋香')">

2、内嵌式

<head>
    <script>
	里面为js代码
	script>
head>

3、外链式

以.js为后缀的文件

<script src="my.js">script>

三、注释

1、单行注释

//

ctrl+/

2、多行注释

/**/

shift+alt+a

四、js输入输出语句

方法 说明 归属
alert(msg) 浏览器弹出警示框 浏览器
console.log(msg) 浏览器控制台打印输出信息 浏览器
prompt(info) 浏览器弹出输出框,用户可以输入 浏览器

五、变量

1、声明变量

var 变量名;

js中var用来声明变量

可以同时声明多个变量

var age=18,name=“stive”,gz=2000;

允许不声明直接赋值,但是不提倡(会变成全局变量)

2、赋值

var age;

age=18;

3、初始化

var age=18;

4、获取输入值

var myname=prompt(“输入名字:”);

5、命名规范

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DJ1IhXte-1673928790986)(C:\Users\ZYJ\AppData\Roaming\Typora\typora-user-images\image-20221203203039745.png)]

六、数据类型

js是一种弱类型或者说动态语言,这意味着不用提前声明变量的类型,在程序运行过程中,类型会被自动确定

根据=右侧的值来判断数据类型

1、分类

简单数据类型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YOD7qH2B-1673928790987)(C:\Users\ZYJ\AppData\Roaming\Typora\typora-user-images\image-20221203203534510.png)]

①Number数字型

数字型最大值和最小值(了解)

Number.Max_VALUE 数字型最大值

Number.Min_VALUE 数字型最小值

Number.Max_VALUE*2 无穷大(Infinity)

-Number.Max_VALUE*2 无穷小(-Inifinity)

isNaN()用于判断非数字,是数字则返回false

②String字符串型

’ ‘或者“ ”都可

推荐单引号(因为html推荐是双引号)

转义字符

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mvFppx1j-1673928790988)(C:\Users\ZYJ\AppData\Roaming\Typora\typora-user-images\image-20221203204539212.png)]

字符串长度获取

str.length

字符串拼接

str1+str2

注意:字符串+数字/boolean 输出的是字符串,也可以用

字符串+变量

③Boolean布尔型

true和false

参与运算时true当1,false当0

④Undefined和Null

typeof 变量 显示变量类型

数字类型转换

方式 说明 案例
toString() 转成字符串
String() 强制转成字符串
加号拼接字符串 和字符串拼接的结果是字符串
方式 说明 案例
parseInt(string) string转整数值
parseFloat(string) string转浮点值
Number() 强制转数值型
js隐式转换(- * /) 利用运算转数值型 ‘a’-0
方式 说明 案例
Boolean() 其它类型转成布尔值

复杂数据类型

七、运算符

算数运算符 描述 案例
+
-
*
/
% 取余
递增递减运算符 描述 案例
++ 递增
递减
比较运算符 描述 案例
<
>
>=
<=
== 判断两边值是否相等,有隐式转换
!=
=== !== 全等 要求值和数据类型都一致 37===‘37’ false
逻辑运算符 描述 案例
&&
||
!

逻辑运算中有逻辑中断特性

赋值运算符 描述 案例
=
+=、-=
*=、/=、%=

八、流程控制(与c一样)

1、分支结构

if语句

if(){

}
else if(){

}
else{

}

三元表达式

条件表达式? 表达式1:表达式2

真则返回1的值,假则返回2的值

switch语句

switch(n){
	case1:
		...
		break;
	case2:
		...
		break;
	defualt:
		case值不匹配时执行的代码
	
}

2、循环

1、for循环

2、while循环

3、do/while循环

以上循环基本和c一致

九、数组

1、数组创建

①var a=new Array();

a[0]=1;

a[1]=2;

②var a=new Array(1,2);

③var a=[1,‘a’,3];

数组的下标是基于0的

数组里的数据类型可以为任意,类似python的列表

2、访问数组元素

数组名[索引号]

索引 从0开始

3、遍历数组

for(var i=0;i<a.length;i++){
    console.log(a[i])
}

4、数组新增元素

1、修改length长度(扩容)

​ 例如本来为3长度的数组

a.length=5则改为长度为5的数组,后两个元素默认为undifined

2、通过下一位索引号(追加元素)

arr=[1,2,3,4];

arr[4]=‘pink’;追加元素

十、函数

1、语法

声明函数

①命名函数方式声明

function funcname(参数1,参数2)
{
	//执行代码
}

调用函数

fucname(参数1,参数2)

②函数表达式

var 变量名=function(){
    
};
//调用
变量名();

2、return

函数没有return就会返回undefined

3、arguments

当形参个数不确定时可以用arguments来获取。

arguments存储了所有传递过来的实参

function fn()
{
	console.log(arguments);
}
fn(1,2,3)

伪数组并不是正真意义上的数组

1、具有数组的length属性

2、按照索引方式进行存储

3、没有真正数组的一些方法如pop() push()等

4、可以按照数组的遍历方式遍历

十一、作用域

js作用域分为全局和局部

1、全局作用域:整个script标签,或者单独的js文件

2、局部作用域:函数作用域

变量分为全局变量和局部变量

1、全局变量

①函数外声明的变量

函数内没有声明的变量(没有用var声明)

2、局部变量

①函数内声明的变量(要用var声明)

全局变量只有浏览器关闭才会销毁,占用内存资源。局部变量当程序执行完毕就会直接销毁,节约内存资源。

js没有块级作用域,es6新增了块级作用域

块级作用域,即{}中的作用域

十二、js预解析

js引擎运行js分为两步:预解析 代码执行

js预解析:会把js里所有var还有function提升到当前作用域最前面

代码执行:按照代码书写顺序从上往下执行

预解析分为变量预解析和函数预解析

变量预解析:所有变量声明提升到当前作用域最前面,不提升赋值

函数预解析:就是把所有函数声明提升到当前作用域最前面,不调用函数。

其实可以不用管这个前提是有良好的代码习惯

十三、对象(类似python的字典,就是多了方法)

对象:具体的事物,在编程中,对象由属性和方法组成

1、创建对象

1】字面量创建对象

var obj={};创建空对象

var obj={

​ name=“小明”,

​ age=‘18’,

​ gender=‘男’,

​ sayHi:function(){//定义方法

​ console.log(‘hello’);

​ }

}

类似python的字典采用键值对的形式

2】new Object创建对象(个人不推荐)

var obj=new Object();//创建空对象
obj.name="张三丰";
obj.age=18;
obj.sayHi=function(){
	console.log("hai")}

我个人是不推荐这种写法的,因为c和python等语言并没有类似的这种对象的写法,而且结构不清晰

3】利用构造函数创建对象(个人推荐)

构造函数:一种特殊的函数,主要用于初始化对象,即为对象成员变量赋初始值,它总与new运算符一起使用,我们可以把对象中一些公共属性和方法抽取出来,然后封装到这个函数里面

语法

function 构造函数名(参数1,参数2...){//定义构造函数
	this.属性=参数或值;
	this.方法=function(){}
}
var 变量名=new 构造函数名();//调用构造函数创建对象

构造函数首字母大写
例:

function Star(name,age){
	this.name=name;
	this.age=age;
}
var ldh=new Star("刘德华",18);

2、使用对象

1】调用对象属性

①对象名.属性名

②对象名[‘属性名’]

2】调用对象方法

对象名.方法名()

3、遍历对象

for in语句

for(变量 in 对象){
	
}
for(var k in obj){
	console.log(k);//输出属性名
	console.log(obj[k]);//输出属性名
}

十四、内置对象

js对象分为自定义对象、内置对象、浏览器对象

前两者对象是js基础内容属于ECMAScript;最后一个是js独有的,js API中会讲解

1】查文档MDN

官网http://developer.mozilla.org/zh-CN/

1、查阅方法的功能

2、查看参数意义和类型

3、查看返回值意义和类型

4、测试

2】Math对象

  • Math.PI圆周率
  • Math.max(value1,value2,…)最大值
  • Math.abs()绝对值
  • Math.floor()向下取整,往最小取值
  • Math.ceil()向上取整
  • Math.round()四舍五入
  • Math.random()随机数

Math.random()

​ 返回随机小数[0,1)

​ 构造返回整数的方法:

function getRandomInt(min,max){
	return Math.floor(Math.random()*(max-min+1))+min

}//包含了最大值和最小值

3】封装自己的数学对象

var myMath={
	PI:3.141592653,
	max:function(){
		var max=arguments[0];
		for(var i=1;i<arguments.length;i++)
		{
			if(arguments[i]>max){
				max=arguments[i];
			}
		}
		return max;
	}
}

4】日期对象Date

Date()是一个构造函数必须用new调用来创建一个对象

1、使用Date

var date=new Date();

console.log(date);

如果无参数则返回系统当前时间

2、参数常用写法

①数字型 2019,10,01

②字符串型‘ 2019-10-1 8:8:8’

var date1=new Date(2019,10,1);

返回11月不是10月

var date2=new Date(‘2019-10-1 8:8:8’)

返回10月

3、日期格式化

var date=new Date();

date.getFullYear() ;//获取当前日期年

date.getMonth();//获取月份(0-11)小一个月

date.getDate();//返回几号

date.getDay();//返回周几(0-6)周日返回0

date.getHours();

date.getMinutes();

date.getSeconds();

4、时间戳(总毫秒数)

距离1970年1月1号过了多少毫秒数

1、通过valueOf() 或getTime()

var date=new Date();

2、简单写法

var date= +new Date();

返回的date就是毫秒数

3、H5新增写法

console.log(Date.now());

5、倒计时

核心算法:规定时间减去剩余时间即倒计时,但是不能拿时分秒相减

可以用时间戳来做,用户输入时间总的毫秒数减去现在时间的总的毫秒数得到的就是剩余时间的毫秒数。再把总的毫秒数转换为天、时、分、秒

转换公式如下:

  • d=parseInt(总秒数/60/60/24);计算天数
  • h=parseInt(总秒数/60/60%24);计算小时
  • m=parsent(总秒数/60%60);计算分
  • s=parsentInt(总秒数%60);计算秒
function countDown(time){
	var nowTime=+newDate();//返回当前总毫秒数
	var inputTime=+new Date(time);//用户输入时间总的毫秒数
	var times=(inputTime-nowTime)/1000;//剩余总时间秒数
	var d=parseInt(times/60/60/24);计算天数
    d=d<10?'0'+d:d;//小于10补0
	var h=parseInt(times/60/60%24);计算小时
    h=h<10?'0'+h:h;
	var m=parsent(times/60%60);计算分
    m=m<10?'0'+m:m;
	var s=parsentInt(times%60);计算秒
    s=s<10?'0'+s:s;
    return d+'天'+h+'时'+m+'分'+s+'秒';
}

5】数组内置对象Array

1、字面量创建数组

var arr=[1,2,3];
console.log(arr[0]);

2、利用new Array()

var arr1=new Array();//创建空数组
var arr2=new Array(2);//创建长度为2的数组,有两个空元素
var arr3=new Array(2,3);//创建[2,3]数组

3、添加数组元素

方法 描述 案例
push() 给原数组末尾添加一个或多个元素,返回新数组长度 arr.push(4,5,6);
unshift() 再数组开头添加一个或多个元素,返回新数组长度 arr.unshift(4,5,6)

4、删除数组元素

方法 描述 案例
pop() 删除最后一个元素,返回删除的元素 a.pop()
shift() 删除第一个元素,返回删除的元素 a.shift()

5、数组排序

方法 描述 案例
reverse() 数组倒序 arr.reverse()
sort() 冒泡排序 arr.sort()

降序

arr1.sort(function(a,b){return b-a;})

升序

arr1.sot(function(a,b){return a-b;})

6、获取数组索引

方法 描述 案例
indexOf(元素) 返回对应元素值的第一个满足的索引,若找不到则返回-1 arr.index(‘blue’)
lastIndexOf() 与indexOf类似,只是从后往前找

7、数组转字符串

方法 描述 案例
toString() 把数组转换成字符串,逗号分隔每一项 arr.toString()
join(‘分隔符’) 把数组中的元素转换成一个字符串 arr.join(‘-’)

6】字符串对象string

基本包装类型:就是把简单数据类型包装成为了复杂数据类型,这样一个简单数据类型就有了属性和方法

str.length()获取字符串长度

字符串不可变

根据字符返回位置

str.indexOf(‘查找字符’[,查找起始位置])

方法 说明
concat(str1,str2,…) 用于连接两个或者多个字符串相当于+,+更常用
substr(start,length) 从start位置开始,取length个数
slice(start,end) 从start位置开始,截取到end位置,不包括end
substring(start,end) 从start位置开始截取到end位置,不包括end,但是不接受负值
方法 描述 案例
replace(‘被替换字符’,‘替换字符’) 只会替换第一个字符
split(‘分隔符’) 分隔字符串

WEB APIs

webapis简介

1、js组成

黑马javascript笔记_第1张图片

只有js基础是做不了网页交互效果的

2、web APIS

  • 是w3c组织的标准
  • 主要学习DOM和BOM
  • 是js独有的部分
  • 我们主要学习页面交互功能
  • 需要js基础

3、API

应用程序编程接口,是给程序员提供的一种工具以便更轻松实现想要完成的功能

4、web API

是浏览器提供的一类API,用于操作浏览器功能和页面元素

(1)DOM

一、简介

1、什么是dom

文档对象模型,是w3c推荐的处理html的标准编程接口

可以改变网页内容、结构和样式

2、DOM树

黑马javascript笔记_第2张图片

  • 文档:一个页面就是一个文档,dom中用document表示
  • 元素:页面中所有标签都是元素,dom中使用element表示
  • 节点:网页中所有内容都是节点(标签属性文本注释等),dom中用node表示

二、获取元素

方法(get/query) 描述 说明 案例
document.getElementById(‘id’) 获取对应唯一ID的元素对象,返回一个获取的元素对象 ID var element = document.getElementById(id);
document.getElementsByTagName() 更让据标签名返回元素对象,返回的是存放所有标签的一个伪数组 标签名 var element = document.getElementsByTagName(‘标签名’);
document.getElementsByClassName() 更具类名返回存放所有标签的伪数组 类名,H5新增 var element=document.getElementsByClassName(类名)
document.querySelector(选择器名) 通过选择器,返回指定选择器的第一个元素对象 选择器名第一个,H5新增 var firstBox=document.querySelector(选择器名)//类选择器名前要加. ID选择器前要加#
document.querySelectorAll(选择器名) 根据指定选择器返回所有集合 选择器名所有,H5新增 var boxs=document.querySelectorAll(选择器名)
  • 获取的元素对象可以用.符号嵌套使用例如
  var element = document.getElementsByTagName('ul');  
element.getElementsByTagName('li');
  • 可以用console.dir打印我们的元素对象,更好的查看里面的属性和方法

三、获取特殊元素

1、获取body元素

var bodyEle=document.body;

2、获取html元素

var htmlEle=document.documentElement;

四、事件三要素

事件的组成:事件源、事件类型、事件处理程序

  • 事件源:事件被触发的对象(谁)
  • 事件类型:如何触发 什么事件 比如鼠标点击(干了什么)
  • 事件处理程序:通过函数 (怎么办)
var btn=document.getElementById('btn');//获取事件源(元素对象)
btn.onclick=function(){//给事件类型附上触发函数
    alert('按钮被点击');
}

五、执行事件的过程

1、获取事件源

例如:

var div=document.querySelector('div');

2、绑定事件

div.onclick=

3、添加事件处理程序

div.onclick=function(){
}

鼠标事件 触发条件
onclick 鼠标点击左键触发
onmouseover 鼠标经过触发
onmouseout 鼠标离开触发
onfocus 获得鼠标焦点触发
onblur 失去鼠标焦点触发
onmousemove 鼠标移动触发
onmouseup 鼠标弹起触发
onmousedown 鼠标按下触发

六、操作元素

6.1改变元素内容

element.innerText

从起始位置到终止位置的内容,但它不识别html标签,同时空格和换行也会去掉(不常用)

element.innerHTML 

起始位置到终止位置的全部内容,识别html标签,同时保留空格和换行 (W3C推荐)

innerText例子:

//点击按钮改变文字
1、获取元素
var btn=document.querySelector('btn');
var div=document.querySelector('div');
2、注册事件
btn.onclick=function(){
    div.innerText='2019-6-6';
}

innerHTML例子:

1、获取元素
var btn=document.querySelector('btn');
var div=document.querySelector('div');
2、注册事件
btn.onclick=function(){
    div.innerText='2019-6-6';
}

6.2改变元素属性

常用属性:src/title/href/id/alt等

var ldh=document.getElementById('ldh');
var zxy=document.getElementById('zxy');
var img=document.getElementById('img');
zxy.onclick=function(){
    img.src='images/zxy.jpg';
}

总结:元素对象.属性=值

6.3修改css样式属性

1、获取元素

2、注册元素 处理程序

1】element.style.样式名 行内样式操作 样式少时使用

2】element.className 类名样式操作 样式复杂时使用

var div=document.querySelector('div');
div.onclick=function(){
	this.style.backgroundColor='purple';
    this.style.width='200px';
}
var div=document.querySelector('div');
div.onclick=function(){
	this.className='change';//把类名改成change,之后只要在css里添加change类名对应的样式即可
}

注意:

  • JS里的样式采取驼峰命名方法,比如fontSize,backgroundColor

  • 修改style样式的操作产生的是行内样式,css权重高

  • 修改样式多时可以用修改类名的方式来更改元素样式

  • className会直接更改元素的类名,会覆盖原先的类名

循环精灵图(案例)

1、首先精灵图排列得有规律

2、利用for循环修改精灵图背景位置

3、剩下的就是数学问题了

显示隐藏文本框内容(案例)

1、首先需要两个事件:失去焦点和获取焦点

var text=document.querySelector('input');
text.onfoncus=function(){
	if(text.value==='手机'){
		text.value='';
        this.style.color='gray';
	}
}
text.onblur=function(){
	if(text.value===''){
		text.value='手机'
        this.style.color='#fff';
	}
}

七、排他思想

<body>
     <botton>按钮1botton>
     <botton>按钮1botton>
     <botton>按钮1botton>
     <botton>按钮1botton>
     <botton>按钮1botton>
    <script>
    	var btns=document.getElementsByTagName('button');
        for(var i=0;i<btns.length;i++){//通过for循环给所有button元素注册事件
            btns[i].onclick=function(){
                //1、把所有按钮背景色还原
                for(var i=0;i<btns.length;i++){
                    btns[i].style.backgroundColor='';
                }
                //2、把当前按钮变成背景色
                this.style.backgroundColor="pink";
            }
        }
    script>
    
body>

通过上面案例可知,排他思想就是

1、所有元素设置原先样式

2、设置当前元素样式

表格隔行换色(案例)

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>Documenttitle>
    <style>

    style>
head>

<body>
    <table>
        <thead>
            <tr>
                <td>姓名td>
                <td>性别td>
                <td>年龄td>
            tr>
        thead>
        <tbody>
            <tr>
                <td>小明td>
                <td>td>
                <td>18td>
            tr>
            <tr>
                <td>小芳td>
                <td>td>
                <td>17td>
            tr>
        tbody>

    table>
    <script>
        var trs = document.querySelector('tbody').querySelectorAll('tr');
        for (var i = 0; i < trs.length; i++) {
            trs[i].onmouseover = function() {
                this.style.backgroundColor = 'pink';
            }
            trs[i].onmouseout = function() {
                this.style.backgroundColor = '#fff';
            }
        }
    script>
body>

html>

表单全选/取消全选(案例)

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>Documenttitle>
    <style>
        thead tr {
            background-color: skyblue;
        }
    style>
head>

<body>
    <table cellspacing="0px">
        <thead>
            <tr>
                <td><input type="checkbox" id="All_c">td>
                <td>姓名td>
                <td>性别td>
                <td>年龄td>
            tr>
        thead>
        <tbody>
            <tr>
                <td><input type="checkbox" id="c">td>
                <td>小明td>
                <td>td>
                <td>18td>
            tr>
            <tr>
                <td><input type="checkbox" id="c">td>
                <td>小芳td>
                <td>td>
                <td>17td>
            tr>
        tbody>

    table>
    <script>
        //全选或者取消全选的方法
        var a_cbox = document.getElementById('All_c');
        var cbox = document.querySelector('tbody').querySelectorAll('input');
        a_cbox.onclick = function() {
            for (var i = 0; i < cbox.length; i++) {
                cbox[i].checked = this.checked;
            }
        }
		//子按钮状态影响全选框状态
		for (var i = 0; i < cbox.length; i++) {
            cbox[i].onclick = function() {
                if (!this.checked) {
                    a_cbox.checked = false;
                } else {
                    var flag = 1;
                    for (var i = 0; i < cbox.length; i++) {
                        if (cbox[i].checked == false) {
                            flag = 0;
                            break;
                        }
                    }
                    if (flag) {
                        a_cbox.checked = true;
                    }
                }
            }
        }
    script>

body>

html>

八、自定义属性

8.1获取元素自定义属性值

1、获取元素的属性值

  • element.getAttribute(‘属性’) ;用于获得自定义属性
  • element.属性值 ;获取元素本身自带属性

自定义属性:程序员自己添加的属性

2、设置属性值

  • element.setAtrribute(‘属性’,‘值’);设置自定义属性
  • element.属性值=‘值’;设置内置属性

3、移除属性

element.removeAtrribute(‘属性’)

tab栏切换案例-重要

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>Documenttitle>
    <style>
        .clearfix:before,
        .clearfix:after {
            content: "";
            display: table;
        }
        
        .clearfix:after {
            clear: both;
        }
        
        .clearfix {
            *zoom: 1;
        }
        
        .tab_list li {
            float: left;
            list-style: none;
            margin-left: 10px;
        }
        
        .current {
            float: left;
            list-style: none;
            margin-left: 10px;
            background-color: pink;
        }
        
        .item {
            display: none;
        }
    style>
head>

<body>
    <div class="tab">
        <div class="tab_list clearfix">
            <ul>
                <li class="current">商品介绍li>
                <li>规格包装li>
                <li>售后保障li>
                <li>商品评价li>
                <li>手机社区li>
            ul>
        div>
        <div class="tab_con">
            <div class="item">商品介绍模块div>
            <div class="item">规格包装模块div>
            <div class="item">售后保障模块div>
            <div class="item">商品评价模块div>
            <div class="item">手机社区模块div>
        div>
    div>
    <script>
        var tab_list = document.querySelector('.tab_list');
        var lis = tab_list.querySelectorAll('li');
        var items = document.querySelector('.tab_con').querySelectorAll('.item');
        items[0].style.display = 'block';
        for (var i = 0; i < lis.length; i++) {
            //设置索引号(自定义属性index)
            lis[i].setAttribute('index', i);
        }
        for (var i = 0; i < lis.length; i++) {

            lis[i].onclick = function() {
                //改变底色
                for (var i = 0; i < lis.length; i++) {
                    lis[i].className = '';
                }
                this.className = 'current';
                //改变内容
                var index = this.getAttribute('index');
                for (var i = 0; i < items.length; i++) {
                    items[i].style.display = 'none';
                }
                items[index].style.display = 'block';
            }
        }
    script>
body>

html>

8.2H5自定义属性

1、H5自定义属性概念

为了防止歧义自定义属性必须是data-开头的

比如data-index

2、设置H5自定义属性

必须以data-属性名的形式创建自定义属性

3、获取H5自定义属性

  • 兼容性获取:element.getAttribute(‘data-属性名’)

  • H5新增:element.dataset.属性名

    ​ element.dataset[‘属性名’]

    ​ 这两个属性名不需要带data-且只有IE11才开始支持这两个方法

PS: 对于这样命名的自定义属性data-list-name

必须采用驼峰命名法获取,也就是element.dataset.listName

十一、节点操作

11.1节点概述

获取元素通常有两种方式:

1、利用DOM提供的方法获取,逻辑不强且繁琐

2、利用节点层级关系获取元素,逻辑性强但是兼容性差

这两种方式都可以获取元素节点,后面都会使用,但是节点操作更加简单

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oKTW1EC7-1673928790989)(C:\Users\ZYJ\AppData\Roaming\Typora\typora-user-images\image-20221205171441111.png)]

网页中的所有内容都是节点(标签、属性、文本、注释等),在DOM 中,节点使用 node 来表示。
HTML DOM 树中的所有节点均可通过 JavaScript 进行访问,所有 HTML 元素(节点)均可被修改,也可以创建或删除。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wcq61A0T-1673928790990)(C:\Users\ZYJ\AppData\Roaming\Typora\typora-user-images\image-20221215142925754.png)]

实际操作中主要的是元素节点

11.2节点层级

常见的为父子兄节点关系

1、父节点node.parentNode

返回某节点的最近父节点,若找不到则返回null

var a=document.querySelector('.son');//获取节点
console.log(a.parentNode);//获取并打印最近父节点

2、子节点

  • node.childNodes

返回指定节点的所有子节点(不仅仅是元素节点)

var a=document.querySelector('.father');
console.log(a.childNodes);//获取并打印所有子节点
for(var i=0;i<ul.childNodes.length;i++){
    //通过for循环通过nodeType来过滤出子节点中的元素节点
    if(ul.childNodes[i].nodeType==1){
        console.log(ul.childNodes[i]);
    }
}

由于想要获取里面的元素节点,则需要专门处理,所以我们一般不提倡使用childNodes

  • node.children 重点

返回所有子元素节点,虽然他是非标准的获取方式,但是浏览器都支持,所以可以大量使用这种方式,也是实际开发常用的

  • node.firstChild/node.lastChild

获取第一个子节点/最后一个子节点(不管是文本还是元素节点等)

  • node.firstElementChild/lastElementChild

获取第一个/最后子元素节点,

注意这两种方法有兼容性问题ie9以上才支持

解决方案

实际开发里一般通过node.children[0]获取第一个子元素节点

node.children[node.children.length-1]获取最后一个元素节点

3、兄弟节点

  • node.nextSibling

获取下一个兄弟节点(包括文本节点,元素节点等)

可以用这个自己封装一个函数来找到兄弟节点避免兼容性

  • node.previousSibling

获取上一个兄弟节点(包括文本节点,元素节点等)

  • node.nextElementSibling

获取下一个元素节点,ie9以上才支持

  • node.previousElementSibling

获取上一个元素节点,ie9以上才支持

11.3节点的创建和添加

1.创建节点

document.createElement(‘tagName’);

var li=document.createElement('li');

2、追加节点

node.appendChild(child)

添加到节点的最后子节点末尾

var ul.document.querySelector('ul');
ul.appendChild(li);

3、插入节点

node.insertBefore(child,指定元素);

ul.insertBefore(li,ul.children[0])

11.4节点的删除

  • node.removeChild(child) 删除子节点

例:ul.removeChild(ul.children[0]);删除ul中第一个子元素节点

11.5节点的复制

  • node.cloneNode() 返回调用该方法的节点的一个副本
  • 若括号里为空或者false则为浅拷贝,即只复制标签不复制内容
  • 若为true则为深拷贝,复制标签和内容
var ul=document.querySelector('ul');
var ul_copy=ul.children[0].cloneNode(true);
ul.appendChild(ul_copy);

十二、DOM总结重点核心

对于DOM操作,我们主要针对子元素的操作,主要有

创建,增,删,改,查,属性操作,时间操作

1.创建
document.write,innerHTML,createElement

2.增
appendChild,insertBefore

3.删
removeChild

4.改
主要修改dom的元素属性,dom元素的内容、属性、表单的值等
修改元素属性:src、href、title 等
修改普通元素内容:innerHTML、innerText
修改表单元素:value、type、disabled
修改元素样式:style、className

5.查
主要获取查询dom的元素
DOM提供的API方法:getElementById、getElementsByTagName (古老用法,不推荐)
H5提供的新方法:querySelector、querySelectorAll (提倡)
利用节点操作获取元素:父(parentNode)、子(children)、兄(previousElementSibling、nextElementSibling) 提倡

6.属性操作
主要针对于自定义属性
setAttribute:设置dom的属性值
getAttribute:得到dom的属性值
removeAttribute:移除属性

十三、事件高级

13.1注册事件

注册事件有两种方式:传统方式和方法监听注册方式

传统注册方式 方法监听注册方式
利用on开头的事件 onclick w3c标准推荐方式
addEventListener()是一个方法
btn.οnclick=function(){} IE9及之后支持,可使用attachEvent()代替
特点:注册事件唯一性,同一个元素同一个事件只能当设置一个处理函数 特点:同一个元素同一个事件可以注册多个监听器
最后注册的处理函数将会覆盖前面注册的处理函数 按注册顺序依次执行

13.2addEventListener事件监听方式

eventTarget.addEventListener(type,listener[,userCapture]);
  • 该方法将指定的监听器注册到目标对象eventTarget上,

  • 当该对象触发指定的事件时,就会执行事件处理函数。

该方法接受三个参数:

type:事件类型字符串,比如click,mouseover这里不用带on

listener:事件处理函数,事件发生时,会调用该监听函数

useCapture:可选参数,是一个布尔值,默认时false

例:

<body>
    <button>传统注册事件button>
    <button>方法监听注册事件button>
    <button>ie9 attachEventbutton>
    <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>

13.3attachEvent注册方式-了解

ie9以前版本,该特性是非标准不提倡使用

eventTarget.attacjEvent(eventNameWithOn,callback)

指定监听器注册到eventTarget上,当该对象触发指定的事件时,指定的回调函数就会被执行

参数

  • eventNameWithOn:事件类型字符串,比如onclick、onmouseover
  • callback:事件处理函数,当目标触发事件时回调函数被调用

注册事件兼容性解决方案

function addEventListener(element, eventName, fn) {
    // 判断当前浏览器是否支持 addEventListener 方法
    if (element.addEventListener) {
        element.addEventListener(eventName, fn);  // 第三个参数 默认是false
    } else if (element.attachEvent) {
        element.attachEvent('on' + eventName, fn);
    } else {
        // 相当于 element.onclick = fn;
        element['on' + eventName] = fn;
    } 

13.3删除事件

1】removeEventListener方法监听注册方式

eventTarget.removeEventListener(type,listener[,useCapture]);

参数

  • type:事件类型字符串,比如click,mouseover,注意这里不要带on

  • listener:事件处理函数,事件发生时,会调用该监听函数

  • useCapture:可选参数,是一个布尔值,默认是 false。学完 DOM 事件流后,我们再进一步学习

  • div[1].addEventListener('click',fn)//注册事件函数
    function fn(){//事件函数
    	alter(22)//输出22
    	divs[1].removeEventListener('click',fn)//移除fn事件函数
    }
    
    

    该移除函数,在绑定函数时绑定的函数需要先分离写法。

2】detachEvent删除事件方式

eventTarget.detachEvent(eventNameWithOn,callback);

参数:

  • eventNameWithOn:事件类型字符串,比如 onclick 、onmouseover ,这里要带 on
  • callback: 事件处理函数,当目标触发事件时回调函数被调用
  • ie9以前的版本支持

3】传统事件删除方式

eventTarget.onclick = null;

十四、DOM事件流

事件流描述的是页面中接收事件的顺序

事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-51NpLW5O-1673928790990)(C:\Users\ZYJ\AppData\Roaming\Typora\typora-user-images\image-20221215200959839.png)]

  • 事件冒泡: IE 最早提出,事件开始时由最具体的元素接收,然后逐级向上传播到到 DOM 最顶层节点的过程。
  • 事件捕获: 网景最早提出,由 DOM 最顶层节点开始,然后逐级向下传播到到最具体的元素接收的过程。

1、js代码只能执行捕获或者冒泡中的一个阶段

2、onclick和attachEvent只能执行冒泡阶段

3、addEventLisenner(type,listener[,useCapture])第三个参数如果是true,表示再事件捕获阶段调用事件处理程序;如果是false,默认是false,表示再事件冒泡阶段调用事件处理程序

十五、事件对象

div.onclick=function(event){}

1、event就是一个事件对象,写在侦听函数的小括号中,当作形参来看

2、事件对象只有有了事件才会存在它是系统自动创建的不需要传递参数

3、事件对象是我们事件的一系列相关数据的集合与事件相关的,比如鼠标点击里面就包含了鼠标的相关信息。

4、事件对象可以自己命名。比如event,evt,e

5、事件对象也有兼容性问题ie678通过window.event兼容性的写法

十六、事件对象的常见属性和方法

事件对象属性方法 说明
e.target 返回触发事件的对象 标准
e.srcElement 返回触发事件的对象 非标准ie6-8使用
e.type 返回事件的类型
e.cancelBubble 该属性阻止冒泡 ie678使用
e.returnValue 该属性阻止默认事件 ie678使用
e.preventDefault() 该方法阻止默认事件 标准
e.stopPropagation() 阻止冒泡 标准

注:e.target返回的是触发事件的对象,this返回的是绑定事件的对象

阻止默认事件

<body>
    <div>123div>
    <a href="http://www.baidu.com">百度a>
    <form action="http://www.baidu.com">
        <input type="submit" value="提交" name="sub">
    form>
    <script>
        // 常见事件对象的属性和方法
        // 1. 返回事件类型
        var div = document.querySelector('div');
        div.addEventListener('click', fn);
        div.addEventListener('mouseover', fn);
        div.addEventListener('mouseout', fn);

        function fn(e) {
            console.log(e.type);

        }
        // 2. 阻止默认行为(事件) 让链接不跳转 或者让提交按钮不提交
        var a = document.querySelector('a');
        a.addEventListener('click', function(e) {
            e.preventDefault(); //  dom 标准写法
        })
        // 3. 传统的注册方式
        a.onclick = function(e) {
            // 普通浏览器 e.preventDefault();  方法
            // e.preventDefault();
            // 低版本浏览器 ie678  returnValue  属性
            // e.returnValue;
            // 我们可以利用return false 也能阻止默认行为 没有兼容性问题 特点: return 后面的代码不执行了, 而且只限于传统的注册方式
            return false;
            alert(11);
        }
    script>
body>

阻止冒泡的两种方式

1】标准写法:利用事件对象里的e.stopPropagation();

2】非标准:window.event.cancelBubble=true;

阻止冒泡的兼容性写法

if(e && e.stopPropagation){
      e.stopPropagation();
  }else{
      window.event.cancelBubble = true;
  }

十七、事件委托(代理、委派)

事件委托原理

给父节点添加侦听器,利用事件冒泡影响每个子节点

作用:只操作一次DOM提高程序性能

<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';
            // 点了谁,就让谁的style里面的backgroundColor颜色变为pink
        })
    script>
body>

以上案例:给 ul 注册点击事件,然后利用事件对象的 target 来找到当前点击的 li,因为点击 li,事件会冒泡到 ul 上, ul 有注册事件,就会触发事件监听器。那么每个li都会触发ul的事件

十八、禁止选中文字和禁止右键菜单

1、禁止鼠标右键菜单

contextmenu主要控制应该何时显示上想问菜单,主要用于程序员取消默认的上下文菜单

document.addEventListener('contextmenu',function(e){
e.preventDefault();
})

2、禁止鼠标选中

selectstart

<body>
    <h1>我是一段不愿意分享的文字h1>
    <script>
        // 1. contextmenu 我们可以禁用右键菜单
        document.addEventListener('contextmenu', function(e) {
                e.preventDefault(); // 阻止默认行为
            })
            // 2. 禁止选中文字 selectstart
        document.addEventListener('selectstart', function(e) {
            e.preventDefault();
        })
    script>
body>

十九、获得鼠标在页面坐标

鼠标事件对象MouseEvent

鼠标事件对象 说明
e.clientX 返回鼠标相对于浏览器窗口可视区的X坐标
e.clientY 返回鼠标相对于浏览器窗口可视区的Y坐标
e.pageX(重点) 返回鼠标相对于文档页面的X坐标 IE9+ 支持
e.pageY(重点) 返回鼠标相对于文档页面的Y坐标 IE9+ 支持
e.screenX 返回鼠标相对于电脑屏幕的X坐标
e.screenY 返回鼠标相对于电脑屏幕的Y坐标
<body>
    <script>
        // 鼠标事件对象 MouseEvent
        document.addEventListener('click', function(e) {
            // 1. client 鼠标在可视区的x和y坐标
            console.log(e.clientX);
            console.log(e.clientY);
            console.log('---------------------');
            // 2. page 鼠标在页面文档的x和y坐标
            console.log(e.pageX);
            console.log(e.pageY);
            console.log('---------------------');
            // 3. screen 鼠标在电脑屏幕的x和y坐标
            console.log(e.screenX);
            console.log(e.screenY);
        })
    script>
body>

二十、常用键盘对象

键盘事件 触发条件
onkeyup 某个键盘按键被松开时触发
onkeydown 某个键盘按键被按下时触发
onkeypress 某个键盘按键被按下时触发,但是它不识别功能键,比如 ctrl shift 箭头等
  • 如果使用addEventListener 不需要加 on
  • onkeypress 和前面2个的区别是,它不识别功能键,比如左右箭头,shift 等
  • 三个事件的执行顺序是: keydown – keypress — keyup
<body>
    <script>
        // 常用的键盘事件
        //1. keyup 按键弹起的时候触发 
        // document.onkeyup = function() {
        //         console.log('我弹起了');

        //     }
        document.addEventListener('keyup', function() {
            console.log('我弹起了');
        })

        //3. keypress 按键按下的时候触发  不能识别功能键 比如 ctrl shift 左右箭头啊
        document.addEventListener('keypress', function() {
            console.log('我按下了press');
        })
        //2. keydown 按键按下的时候触发  能识别功能键 比如 ctrl shift 左右箭头啊
        document.addEventListener('keydown', function() {
            console.log('我按下了down');
        })
        // 4. 三个事件的执行顺序  keydown -- keypress -- keyup
    script>
body>

键盘对象属性

键盘事件对象 属性 说明
keyCode 返回该值的ASCII
  • onkeydownonkeyup 不区分字母大小写,onkeypress 区分字母大小写。
  • 在我们实际开发中,我们更多的使用keydown和keyup, 它能识别所有的键(包括功能键)
  • Keypress 不识别功能键,但是keyCode属性能区分大小写,返回不同的ASCII值
<body>
    <script>
        // 键盘事件对象中的keyCode属性可以得到相应键的ASCII码值
        // 1. 我们的keyup 和keydown事件不区分字母大小写  a 和 A 得到的都是65
        // 2. 我们的keypress 事件 区分字母大小写  a  97 和 A 得到的是65
        document.addEventListener('keyup', function(e) {
            console.log('up:' + e.keyCode);
            // 我们可以利用keycode返回的ASCII码值来判断用户按下了那个键
            if (e.keyCode === 65) {
                alert('您按下的a键');
            }
            else {
                alert('您没有按下a键')
            }
        })
        document.addEventListener('keypress', function(e) {
            console.log('press:' + e.keyCode);
        })
    script>
body>

(2)BOM

一、概述

BOM即浏览器对象模型,提供了独立于内容而与浏览器窗口进行交互的对象,其核心对象是window。

BOM由一系列相关的对象构成,并且每个对象都提供了很多方法与属性

BOM缺乏标准,最初是Netscape浏览器标准的一部分

DOM针对的是文档,而BOM是把浏览器当作一个对象shi浏览器厂商在各自浏览器上定义的,兼容性差

BOM包含DOM

  • BOM的构成

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-beBvaOTK-1673928790991)(C:\Users\ZYJ\AppData\Roaming\Typora\typora-user-images\image-20221216132347517.png)]

window对象是浏览器的顶级对象,具有双重角色

1、是js访问浏览器窗口的一个接口

2、是一个全局对象,定义在全局作用域中的变量、函数都会变成window对象的属性和方法。在调用时可以省略window,前面学习的对话框属于window对象方法,如alert(),prompt()等其完整写法是window.alert()。

注意:window下有个特殊属性window.name,所以不要声明name变量

二、window对象常见事件

2.1窗口加载事件

window.onload=function(){}
或者window.addEventListener("load",function(){})

window.onload是窗口加载事件,当文档内容完全加载完成会触发该事件(包括图像、脚本文件、css文件等),就调用的处理函数

一般需要标签在js段之上才能触发事件,因为html是从上往下执行,而加上window.οnlοad=function(){}将js代码写入{}内就可以将js放置在任何地方,应为他会等待页面全部加载完毕才会执行该js

  • 有了window.onload就可以把js代码写到页面元素的上方,因为onload是等页面内容全部加载完毕再去执行处理函数
  • window.onload传统注册事件方式只能写一次,如果有多个,会以最后一个window.onload为准
  • window.addEventListener(‘load’,function(){})可以写任意次推荐用这种方法。
document.addEventListener('DOMContentLoaded',function(){})

DOMContentLoaded事件触发时,仅当DOM加载完成,不包括样式表、图片、flash等等ie9以上才支持

如果页面图片很多的话,从用户访问到onload触发可能需要较长的事件教书效果就会延迟实现,必然影响用户的体验,此时用DOMContentLoaded事件比较合适

2.2窗口调整大小事件

window.onresize=function(){};
或者window.addEventListener('resize',function(){});

window.onresize是窗口调整大小事件。

  • 只要窗口尺寸变化就会触发这个事件
  • window.innerWidth可以获取当前屏幕的宽度

2.3定时器

window对象提供两种定时器

  • setTimeout()
  • setInterval()

setTimeout

window.setTimeout(调用函数,[延迟的毫秒数])

setTimeout()方法用于设置一个定时器,该定时器在定时器到期后执行调用函数。

  • window可以省略
  • 调用函数可以直接写函数,或者写函数名
  • 延迟的毫秒数省略默认是0
  • 定时器有很多可给经常使用的定时器赋值一个标识符(timeoutID)

这个调用函数也称为**回调函数callback,**意思就是回头调用函数,下一件事情干完(时间或者条件到了)再回头调用这个函数

清除定时器

window.clearTimeout(timeoutID)
  • window可省略
  • 里面的参数就是定时器的标识符(变量)

开启定时器setInterval

window.setInterval(调用函数,[间隔时间ms])
  • window可以省略
  • 每隔间隔时间就会调用一次函数,可以一直调用

停止定时器clearInterval

 window.clearInterval(timeoutID)
  • window可以省略

2.4this

this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指的是谁,一般情况下this的最终指向是调用它的对象

  • 全局作用域或者普通函数中this指向的是window
  • 定时器里的this指向window
  • 方法调用中谁调用this就指向谁
  • 构造函数中this指向构造函数的实例

三、js同步和异步

js一大特点就是单线程,即同一时间只能做一件事。

单线程意味着所有任务都需要排队

同步

程序执行结果和排列顺序一致

异步

同一时间宏观上做多个任务

js执行机制

  • 同步任务:在主线程上执行,形成一个执行栈
  • 异步任务:js的异步通过回调函数实现,

​ 一般而言异步任务有一下三种类型

​ 1、普通事件:click、resize等

​ 2、资源加载,如load、error等

​ 3、定时器

​ 异步任务相关回调函数会放入任务队列(消息队列)中

机制:

  • 先执行同步任务
  • 遇到回调函数,放入任务(消息)队列中
  • 再执行下一个同步任务
  • 一旦执行栈中所有同步任务完成,系统就会依次执行任务队列中的任务

四、location对象

1、location属性用于获取或设置窗体的URL,并且可以用于解析URL。因为这个属性返回的是一个对象,所以我们将这个属性称为location对象。

URL:统一资源定位符

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7BeKBMmF-1673928790992)(C:\Users\ZYJ\AppData\Roaming\Typora\typora-user-images\image-20221216145136595.png)]

2、location对象属性

location对象属性 返回值
location.href 获取或者设置(跳转)整个URL
location.host 返回主机(域名)www.baidu.com
location.port 返回端口号,如果未写返回空字符串
location.pathname 返回路径
location.search 返回参数
location.hash 返回片段 #后面内容常见于链接 锚点

重点记住: hrefsearch

3、获取URL参数

  • location.search返回参数

  • 去除? 利用substr(‘起始位置’,截取字符数) 省略字符数则截取到最后

  • split(‘=’)利用=分隔字符串为数组

  • <body>
         <form action='index.html'>
         	用户名:<input type='text' name='uname'>
        	<input type='submit' value='登录'>
        form>
    body>
    

    index.html:

<body>
   <div>div>
   <script>
   	 var params=location.search.substr(1);
 	 var arr=params.split('=');
     var div=document.querySelector('div');
       div.innerHTML=arr[1]+'欢迎你';
   script>
    
body>

4、location常见方法

location.assign(‘URL’)跳转网页到指定URL,可以浏览器后退页面

location.repleace(‘URL’)跳转网页,但不记录历史无法后退

location.reload()刷新页面 参数为true则强制刷新

五、navigator对象-了解

包含浏览器的相关信息,有很多属性,常用userAgent可以返回由客户机发送服务器的user-agent头部的值

下面前端代码可以判断用户那个终端打开页面,如果是用 PC 打开的,我们就跳转到 PC 端的页面,如果是用手机打开的,就跳转到手机端页面

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 = "";     //电脑
 }

不用背

六、History对象

与浏览器历史记录进行交互

包含用户访问过的URL

history对象方法 作用
back() 可以后退功能
forward() 前进功能
go(参数) 前进后退功能,参数如果是 1 前进1个页面 如果是 -1 后退1个页面

七、PC端网页特效

7.1offset

offset翻译就是偏移量,使用offset相关属性可以动态的得到元素的位置、大小等

  • 获得元素距离带有定位父元素的位置(父级必须带定位,否则以body为准)
  • 获得元素自身的大小
  • 返回的数值都不带单位

offest常用属性

属性 作用
element.offsetParent 返回作为该元素带有定位的父级元素,如果父级都没用定位则返回body
element.offsetTop 返回元素相对带有定位父元素上方的偏移
element.offsetLeft 返回元素相对带有定位父元素的左边框的偏移
element.offsetWidth 返回自身包括padding、边框、内容区的宽度,返回数值不带单位
element.offsetHeight 返回自身包括padding、边框、内容区的高度,返回数值不带单位

7.2offset与style的区别

offset style
可以得到任意样式表的样式值 只能得到行内样式表中的值
得到的数值没有单位 带有单位
offsetWidth包含padding+border+width 不包含padding和border
只读属性,只能获取不能赋值 可读可写
适合用于获取元素大小位置 用于修改元素样式

7.3cilent

翻译过来就客户端,我们使用client的相关属性来获取元素可视区的相关信息。通过client系列的相关属性可以动态的得到元素的边框大小、元素大小

属性 作用
element.clientTop 返回元素上边框大小
element.clientLeft 返回元素左边框大小
element.clientWidth 返回自身包括padding、内容区的宽度、不含边框、返回数值不带单位
element.clientHeight 返回自身包括padding、内容区的高度,不含边框,返回数值不带单位

7.4立即执行函数

立即执行函数不需要调用直接执行

语法

(function(形参){
    
})(实参);
或者
(function(形参){
    
}(实参));

第二个小括号可以看作是调用函数,里面可以传实参

作用:将整个js代码写在立即执行函数中,里面的变量都是立即执行函数里的局部变量,在引用多个js文件时可以避免冲突,如下:

(function flexible(window,document){
	代码
}(window,document));

7.5pageshow事件

有三种情况会刷新页面触发load事件:

1、a标签

2、F5或者刷新

3、前进后退按钮

但是火狐中,有个特点,有个“往返缓存”,这个缓存中不仅保存着页面数据,还保存了DOM和JavaScript的状态;实际上是将整个页面都保存在了内存里。所以此时后退按钮不能刷新页面。

此时可以使用pageshow事件来触发。这个事件在页面显示时触发,无论页面是否来自缓存。在重新加载页面中,pageshow会在load事件触发后触发,根据事件对象中的persisted来判断是否是缓存中的页面触发的pageshow事件,注意这个事件给window添加。

7.6scroll事件

滚动事件,可以获得元素的大小和滚动距离

属性 作用
element.scrollTop 返回被卷上去的上侧距离,返回数值不带单位
element.scrollLeft 返回被卷上去的左侧距离,返回数值不带单位
element.scrollWidth 返回自身实际的宽度不含边框(包含内容超出容器的部分),返回数值不带单位
element.scrollHeight 返回自身实际的高度(包含内容超出容器的部分),不含边框,返回数值不带单位
div.addEventListener('scroll',function(){
	console.log(div.scrollTop);
})

补充:mouseover和mouseenter区别

当鼠标移动到元素上就会触发

  • mouseover

​ 经过父盒子和子盒子都会触发一次(会冒泡)

  • mouseenter

​ 只有经过自身盒子才会触发

八、动画函数封装

8.1动画实现原理

核心原理:通过定时器setInterVal()不断移动盒子位置

实现步骤:

1、获得盒子当前位置(盒子记得加定位)

2、让盒子在当前位置加上一个移动距离

3、利用定时器不断重复这个操作

4、加一个结束定时器的条件

5、注意此元素需要添加定位,才能使用element.style.left

8.2简单动画函数封装

注意需要两个参数 动画对象和移动距离

<script>
    var div=document.querySelector('div');
	function animate(obj,target){//封装
        var timer=setInterval(function(){
            if(obj.offsetLeft>=target){
                clearInterval(timer);
            }
            obj.style.left=obj.offsetLeft+1+'px';
        },30);
    }
    animate(div,400);//调用
script>

8.3给不同元素记录不同定时器

给封装的对象创建一个属性值timer令其等于一个定时器

obj.timer=setInterval(function(){})

所以优化8.2的代码为

<script>
    var div=document.querySelector('div');
	function animate(obj,target){//封装
        clearInterval(obj.timer);//先清除定时器防止一个对象的多个定时器同时运行
        obj.timer=setInterval(function(){
            if(obj.offsetLeft>=target){
                clearInterval(timer);
            }
            obj.style.left=obj.offsetLeft+1+'px';
        },30);
    }
    animate(div,400);//调用
script>

九、缓动动画

缓动动画就是让元素运动速度有所变化,最常见的就是让速度慢慢停下来

思路:

  • 让盒子每次移动距离变小
  • 核心算法:步长=(目标值-现在的位置)/10 作为每次移动的距离
  • 步长尽量取整数
  • 盒子位置到目标位置就停止定时器

9.1缓动效果代码

function animate(obj, target) {
    // 目的是让元素只能有一个定时器,防止定时器效果累加
    clearInterval(obj.timer);
    obj.timer = setInterval(function () {
        // 步长值写在定时器里面
        // 把步长值改为整数,尽量避免小数的出现
        // 前进:向上取整
        // 后退:向下取整
        var step = (target - obj.offsetLeft) / 10;
        step = step > 0 ? Math.ceil(step) : Math.floor(step);
        //必须是取最大整数,这样没有到0就会1像素前进保证能够刚好到达目的地,因此目标位置和起始位置也应该为整数,以保证下面if语句必然触发
        if (obj.offsetLeft == target) {
            clearInterval(obj.timer);
        }
        obj.style.left = obj.offsetLeft + step + 'px';
    }, 30)
}

例子:

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>Documenttitle>
    <style>
        .screen {
            position: relative;
            left: 50%;
            margin-left: -450px;
            width: 900px;
            height: 300px;
            border: 1px solid #999;
        }
        
        .box {
            position: absolute;
            top: 150px;
            margin-top: -25px;
            width: 50px;
            height: 50px;
            background-color: skyblue;
        }
    style>

head>

<body>
    <div class="screen">
        <div class="box">div>
    div>
    <script>
        var box = document.querySelector('.box');

        function animate(obj, target) {
            clearInterval(obj.timer);
            obj.timer = setInterval(function() {
                var s = (target - obj.offsetLeft) / 10;
                s = s > 0 ? Math.ceil(s) : Math.floor(s); //必须是取最大整数,这样没有到0就会1像素前进保证能够刚好到达目的地,因此目标位置和起始位置也应该为整数,以保证下面if语句必然触发
                if (target == obj.offsetLeft) {
                    clearInterval(obj.timer);
                } else {
                    obj.style.left = obj.offsetLeft + s + 'px';
                }
                console.log(s);
            }, 30);
        }
        box.onclick = function() {
            animate(box, box.offsetLeft + 200);
        }
    script>
body>

html>

9.2动画函数添加回调函数

回调函数:函数作为参数麻将这个函数作为参数传到另一个函数中,当那个函数执行完成后再去执行传进去的这个函数,这个过程叫做回调

function animate(obj, target, callback) {
    clearInterval(obj.timer);
    obj.timer = setInterval(function () {
        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();
            }
        }
        obj.style.left = obj.offsetLeft + step + 'px';
    }, 30)
}

十、网页轮播图

推荐看视频

十一、移动端网页特效

十二、本地存储

  • 数据存储在用户浏览器中
  • 设置、读取方便、甚至刷新不丢失数据
  • 容量大,sessionStorage约5M,localStorage约20M
  • 只能存储字符串,可以将对象JSON.stringify()编码后存储

12.1 sessionStorage

  • 生命周期为 关闭浏览器窗口消失
  • 在同一窗口(页面)下数据可以共享
  • 键值对的形式存储使用

存储数据

sessionStorage.setItem('key',value)
var ipt =document.querySelector('input');
var set=document.querySelector('.set');
set.addEventListener('click',function(){
	var val=ipt.value;
	sessionStorage.setItem('uname',val);
})

获取数据

sessionStorage.getItem('key');

删除数据

sessionStorage.removeItem('Key');

删除所有数据

sessionStorage.clear();

12.2localStorage

  • 生命周期永久生效,除非手动删除否则关闭页面也存在

  • 可以多窗口共享(同一浏览器共享)

  • 以键值对形式使用

存储数据

localStorage.setItem('Key',value);

获取数据

localStorage.getItem('key');

删除数据

localStorage.removeItem('key');

清除所有数据

localStorage.clear();
        height: 50px;
        background-color: skyblue;
    }

```

9.2动画函数添加回调函数

回调函数:函数作为参数麻将这个函数作为参数传到另一个函数中,当那个函数执行完成后再去执行传进去的这个函数,这个过程叫做回调

function animate(obj, target, callback) {
    clearInterval(obj.timer);
    obj.timer = setInterval(function () {
        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();
            }
        }
        obj.style.left = obj.offsetLeft + step + 'px';
    }, 30)
}

十、网页轮播图

推荐看视频

十一、移动端网页特效

十二、本地存储

  • 数据存储在用户浏览器中
  • 设置、读取方便、甚至刷新不丢失数据
  • 容量大,sessionStorage约5M,localStorage约20M
  • 只能存储字符串,可以将对象JSON.stringify()编码后存储

12.1 sessionStorage

  • 生命周期为 关闭浏览器窗口消失
  • 在同一窗口(页面)下数据可以共享
  • 键值对的形式存储使用

存储数据

sessionStorage.setItem('key',value)
var ipt =document.querySelector('input');
var set=document.querySelector('.set');
set.addEventListener('click',function(){
	var val=ipt.value;
	sessionStorage.setItem('uname',val);
})

获取数据

sessionStorage.getItem('key');

删除数据

sessionStorage.removeItem('Key');

删除所有数据

sessionStorage.clear();

12.2localStorage

  • 生命周期永久生效,除非手动删除否则关闭页面也存在

  • 可以多窗口共享(同一浏览器共享)

  • 以键值对形式使用

存储数据

localStorage.setItem('Key',value);

获取数据

localStorage.getItem('key');

删除数据

localStorage.removeItem('key');

清除所有数据

localStorage.clear();

你可能感兴趣的:(javascript,前端,css)