复习js部分(每日更新)
函数
函数中,如果实参的个数和形参的一样,则输出正常。
函数中,如果实参的个数大于形参的个数,则会取到形参的个数的长度;
函数中,如果实参的个数小于形参的个数,则多的形参会定义为underfined;
函数的返回值:
function(){return 需要返回的结果 }
1、函数只是实现某种功能,最终的结果需要返回给函数的调用者;
2、只要函数遇到return,就把后边的结果,返回给函数的调用者;
function getResult(){return 666 } getResult() //等于是 getResult() = 666
function getMax(num1,num2){if(num1> num2){return num1;}else {return num2; } } getMax(1,6) //最终结果是返回的是6
利用函数算数组中的最大值:
function getArr(arr){let max = arr[0]for(let i =1;i<arr.length;i++){if(arr[i] > max){max = arr[i]}}return max} let max = getArr([1,2,3,5,6]) //最终结果是6
return 只能返回一个值,并且return后边的语句不执行。
如果不return返回值,则调用时的值就是underfined
arguments的使用
function arr(){console.log(arguments); //会以假数组方式显示, } arr([1,2,3])
1、具有数组的length属性,
2、按照索引的方式进行存储
3、它没有真正数组的一些方法
(它是一个函数内置的)
函数有两种声明方式:
1、第一种是命名函数:
function fn(){}
fn()
2、匿名函数
var fun = function(){}
调用方式是fun()
注:此时的fun()是变量
作用域:
分为两种:一种是全局作用域,另一种是局部作用域。
1、全局作用域就是整个script标签,或者一个单独的js文件。
2、局部作用域(函数作用域),在函数内部就是局部作用域,
作用域链:内部函数访问外部函数的变量,采取的就是查找的方式来决定取哪个值,这样的结构称为“作用域链”,就近原则。
let Num = 10; function fn(){let Num = 20;function fun() {console.log(Num);} }
打印输出结果为:20,就近原则
JS引擎运行js分为两部:
1
(1)、预解析:js引擎会把js里边的var 还有 function提升到当前作用域的最前边;
(2)、顺序执行,按照书写顺序从上往下执行;
2、
预解析分为:变量预解析(变量提升)和函数预解析(函数提升)
(1)、变量提升就是把所有的变量声明提升到当前作用域最前边,赋值的不提升;
(2)、函数提升就是把所有的函数声明提升到当前作用域的最前边,不调用函数
对象
对象就是一个具体的事物;在js中对象就是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串,数值,数组等;
对象是由属性和方法组成
属性:就是事物的特征,在对象中用属性来表示;
方法:事物的行为,在对象中用方法来表示;
创建对象的三种方法:
一、利用字面量创建对象
let obj = {uname: 'abc',age: 20,sayHi: function(){} }
里边的属性采取键值对形式;
多个属性和方法之间用逗号隔开;
方法后边跟着是一个匿名函数;
1、使用对象属性:
对象.属性
2、使用对象方法:
对象.方法
二、变量、属性、方法、函数的区别
变量和属性:都是用来存放数据的
区别:
变量:单独声明并赋值,使用时候直接写变量名,单独存在;
属性:不需要单独声明,但是使用时必须是对象.属性
函数和方法:都是用来实现某种功能,做某件事
区别:
函数是单独声明的,并且调用时,函数名()
方法是在对象里边,使用时,对象.方法()
二、利用new object()创建对象
let obj = new Object(); obj.uname = 'aaa' obj.age = 10 obj.sayHi = function(){}
调用时:
obj.sayHi(); obj.uname;
利用构造函数创建对象:
构造函数:
function 构造函数名(){this.属性 = 值this.方法 = function(){}} new 构造函数名()
function Star(uname, age, sex){this.name = unamethis.age = agethis.sex = sex } let a = new Star('姓名',30,'男')
1、构造函数名首字母大写;
2、构造函数不需要return,就可以返回结果
3、调用构造函数必须要有new
构造函数和对象的区别:
构造函数:泛指一大类;
对象:是一个具体的事物;
构造函数创建对象的执行过程为:
1、new 构造函数可以在内存中创建一个空对象,
2、this 指向这个空对象;
3、执行构造函数里边的代码,添加属性和方法
4、返回这个新对象,所以不需要在再外边return 了
如何遍历一个对象:
使用for......in
for(变量 in 对象){}
for(let i in obj){console.log(i); }
这样写时,遍历出来的是变量名
------------------------------------------------------------------
for(let j in obj){console.log(obj[j]); }
当这样写时,输出的结果是属性值;
数组对象
数组去重
目标:把旧数组的里边不重复的元素选取出来,放到新的数组中,重复的去掉;
核心算法:遍历旧的数组,然后每遍历出来一个就拿这个去和新数组中的每一个进行查询,如果存在就不添加,反之添加;
(如果返回的是-1,表示没有)
function arr(arr) {var newArr = []for(let i =0;i<arr.length;i++){if(newArr.indexOf(arr[i]) === -1){newArr.push(arr[i]);}}return newArr }let ab = arr([11,2,11,3,5,6])
返回结果就是[11,2,3,5,6]
数组转字符串
字符串对象
var str = ‘andy’console.log(str.length) 会打印输出4
这样的过程就是基本包装类型:把简单的数据类型,包装成为复杂数据类型
相当于这样:
let temp = new String ('andy') 1、构造函数,把简单数据类型包装为复杂数据类型
str = temp 2、把临时变量值赋值给str
temp = null; 3、销毁这个临时变量
基本包装类型类型:
一共有三种,分别是:String Number Boolean,把简单数据类型包装为复杂数据类型就可以拥有属性和方法。
字符串对象——字符串的不可变性
当改变字符串的变量时,实际上是又开辟了一个空间。
let ab = 'zifuchuan' ab = 'zhi'
实际上是开辟了两个空间
字符串对象的——根据字符返回位置
1、indexOf('要查找的字符', 开始的位置): 返回指定内容在元字符串中的位置,如果找不到就是-1,找到就返回索引号。
2、lastIndexOf(): 从后往前找,只找第一个匹配的。
let str = 'obasdffbobaobadobaob' let index = str.indexOf('o'); let num = 0 while(index !== -1){ num ++;index = str.indexOf('o', index + 1) }
字符串对象——根据位置返回字符
charAt:返回指定位置的字符(Index字符串的索引号)
let str = 'asdf' for(let i =0;i<str.length;i++){console.log(charAt(i)); }
charCodeAt(index) :获取指定位置字符的ASCII 码,
例如:str.charCodeAt(0); 也就是 a ,a的ASCII码为97
str[index] 获取指定位置字符,str[0] ,a
案例:
let str = 'asdfsadf' let obj = {} for(let i = 0;i< str.length; i++){let chars = str.charAt(i); //根据位置返回字符if(obj[chars]){ //判断对象里是否已经存在这个属性obj[chars]++; //如果已经存在就把它加1} else { obj[chars] = 1; //如果对象里边没有这个属性就赋值为1;}}
现在对象obj里边存的是每个字符出现的次数,现在要算出最大值:
遍历对象for ......in
let maxNum = 0 let ch = '' for (let a in obj){if(obj[a] > maxNum) {maxNum = obj[a]ch = a} } console.log(maxNum); 得到出现最多的次数 console.log(ch); 得到出现最多的属性名
字符串操作方法
concat(str1, str2) : concat()方法用于连接两个或者多个字符串。拼接字符串,等效于+
substr(start, length) : 从start 位置开始(索引号),length 取的个数。
slice(Starr,end) : 从start位置开始,一直截取到 end 位置,包括end 。
substring(start, end ) : 从 start 位置开始,截取到 end 位置,但是不包括end
replace('被替换的', ' 替换为的字符') ,
split( '分隔符' ) : 把字符串,从指定的分隔符分隔为几个数组,(join()把数组转换为字符串)
简单数据类型和复杂数据类型关系
1、简单数据类型
(1)、简单数据类型里边有一个特殊的null,它返回的是一个空对象object
堆和栈:
1、栈:
简单数据类型存放到栈里边,在里边直接开辟一个空间存放值;
2、堆:
复杂数据类型存放在堆中,首先在栈中存放地址,用十六进制表示,然后这个地址指向堆中的数值;所以当改变堆中的数据是,由于指向的是同一个地址,所以值会发生改变;
获取特殊元素(body,html)
1、获取到body元素
document.body
2、获取到html元素,
document.documentElement
事件三要素:
分别是: 事件源,事件类型,处理程序
事件源:要触发的对象;
事件类型:单击,移动等;
处理程序:点击事件触发的逻辑;
事件基础:
innerHTML和innerText的区别:
1、innerText不识别html标签,并且去除换行和空格
2、innerHTML识别html标签
这两个属性是可读写的,可以获取元素里边的内容
操作元素——表单
<button></button> <input type = 'text' value = "请输入内容"> <script>let btn = document.querySelector('button');let ipt = document.querySelector('input');btn.onclick=function(){ipt.value = '修改了表变里边的input的值';}</script>
注:在元素的事件中,this指向的是函数的调用者
let btn = document.querySelector('button'); let ipt = document.querySelector('input'); btn.onclick=function(){ipt.value = 'input的值发生变化'this.disabled = true //此时this就是相当于btn这个按钮 }
在上边的实例中,this就是指向的btn。
操作元素——属性,样式
可以通过js修改元素的大小,颜色,位置等样式。
1、element.style 行内样式操作
let div = document.querySelector(div); div.onclick = function(){this.style.backgroundColor = 'pink'this.style.width = '300px' }
里边的样式采取驼峰命名法,并且由于是使用的style行内样式权重较高。
2、element.className 类名样式操作:
.change{font-size: 25pxcolor: white;margin-top: 10px}<div>使用element.className</div><script>let dv = document.querySelector('div');dv.onclick = function(){dv.className = 'change'}</script>
注:如果样式较少或者功能简单,可以采用行内样式方式修改元素;
如果样式较多,情况下可以使用类名的方式;由于class是一个保留字,所以类名是用的className 来操作;
className会直接更改元素的类名,会覆盖原来的类名;
如果想不替换原来的类名可以在添加类样式时,把原来的类名放在前边,空格后边加上新添加的类名。
操作元素总结:
操作元素内容:innerHTML
操作常见元素属性: src href title等
操作表单元素属性: type value disabled等
操作元素样式属性: element.style className
排他思想:
<button>按钮1</button> <button>按钮2</button> <button>按钮3</button> <button>按钮4</button> <button>按钮5</button> <script>let btns = document.getElementsByTagName('button');for(let i = 0;i<btns.length;i++){btn[i].onclick = function(){for(let j = 0;j<btns.length;j++){btns[j].style.backgroundColor = '';}btn[i].style.backgroundColor = 'pink'}}</script>
表格隔行变色:
.bg{background-color: pink }<body><table><thead></thead><tbody></tbody></talbe><script>//获取到所有的在tbody里边的行,trlet trs = document.querySelector('tbody').querySelectorAll('tr');//利用循环注册绑定事件for(let i = 0;i<trs.length;i++){trs[i].onmouseover= function(){this.className = 'bg'}trs[i].momouseout= function(){this.className = ''}}</script></body>
案例重点:全选,单选
首先:全选和取消全选的:
let chaAll = document.getElementById('chaAll'); let chas = document.getElementById('chas'); chaAll.onclick=function(){console.log(this.checked); checked可以得到当前复选框的选中状态,选中就是true,反之falsefor(let i = 0;i<chas.length;i++){chas[i].checked = this.checked ; // 把当前全选状态赋值给下边遍历的字选项, } }
然后:下边子选项判断是否全部选中,给所有子选项绑定点击事件,每次点击都循环查看是否有选中的,如果有一个没有选中,则全选就不勾选;
let chaAll = document.getElementById('chaAll'); let chas = document.getElementById('chas'); chaAll.onclick=function(){console.log(this.checked); checked可以得到当前复选框的选中状态,选中就是true,反之falsefor(let i = 0;i<chas.length;i++){chas[i].checked = this.checked ; // 把当前全选状态赋值给下边遍历的字选项, } }for(let j = 0;j<chas.length;j++){chas[j].onclick=function(){let flag = truefor(let i =0;i<chas.length;i++){if(!chas[i].checked){flag = falsebreak;}}chall.checked = falg} }
获取到元素:
可以通过document.querySelector,等方法获取到元素,并且可以通过使用
dir,打印输出元素的属性,方法,console.dir()
可以通过使用document.getElementByTagName('li')获取到元素,返回的是一个伪数组的对象集合(如果没有元素,返回的是一个空的伪数组)
如果需要获取到某个元素里边的元素,可以通过这样方式使用:
元素.getElementByTagName(),由于返回的是伪数组,所以需要指定索引号,指定元素;
获取元素的属性值:
有两种方式:1、可以通过element.属性 ,可以获取内置属性,自身自带属性;
2、element.getAttribute('属性'),获取的自定义属性;
设置元素属性值:
(1)element.属性 = '值'
(2)element.setAttribute('属性', 值): element.setAttribute('index', 2):
移除元素的属性值:
removeAttribute('属性'): div.removeAttribute('index');
tab栏案例:
分析:1、tab栏切换有两个大模块
2、上边的选项卡,点击哪个,哪个样式就发生变化
3、下边的模块内容,会跟随上边的选项卡变化,所以下面的模块变化写到点击事件里边;
4、规律:下面的模块显示内容和上面的选项卡一一对应,相匹配。
5、核心思路:给上面的栏,每个添加一个自定义属性'inde',属性值从零开始
6、当我们点击上边的哪个栏的,就获取到当前点击的自定义index属性值,其他的隐藏;
let tabList = document.querySelector('.tab_list'); let lis = document.querySelector('li'); let items = document.querySelector('.item'); for循环绑定点击事件 for(let i = 0;i<tabList.length;i++){lis[i].setAttribute('index', i);lis[i].onclick=function(){for(let j=0;j<lis.length;j++){ //排它思想,清空其他的背景lis[j].className = ''}lis[i].className = 'current' //给点击的设置背景2。下边显示内容模块let index = this.getAttribute('index'); //获取到当前点击的index属性值for(let i =0;i<item.length;i++){item[i].style.display = 'null'}item[index].style.display = 'block'}}
H5自定义属性
自定义属性的目的:为了保存并使用数据,有些数据可以保存到页面中而不用保存到数据库中。
自定义属性是通过:getAttribute('属性')获取
但是有些自定义属性容易引起歧义,不容易判断是元素内置属性还是自定义属性。所以H5新添加了自定义属性。
H5规定,自定义属性要以 'data-' 作为开头并且赋值。
如:<div data-index = '1' > </div>
H5新增的获取自定义属性的方法:element.dataset.index 获取 element.dataset['index']
<div getTime="20" data-index = '2' data-list-name = 'andy'></div> <script>let div = document.querySelector('div');console.log(div.getAttribute('getTime'));div.setAttribute('data-time', 20)h5新增的获取自定义属性的方法,它只能后去data-开头的dataset是一个集合里存放了所有以data开头的自定义属性console.log(div.dataset);如果自定义属性里边有多个 ‘-’ 链接的单词,我们获取的时候采取驼峰命名法。</script>
节点操作:
获取节点通常两种方式:
1、利用DOM 提供的方法获取元素,
例如:document.querySelector,
document.getElementById
document.getElementByTagName()
2、利用节点层级关系获取元素;
利用父子,兄弟节点获取元素
node.parentNode(获取到的是当前元素最近的父级元素)
节点概述:
一般节点至少拥有三个基本属性:nodeType节点类型;nodeName节点名称;nodeValue节点值
元素节点 nodeType为1
属性节点 nodeType 为 2
文本节点 nodeType 为 3 (空格,换行,文字等)
父节点操作parentNode:
<body><ul>父元素<li>子元素</li></ul> <script> let lis = document.querySelector('子节点'); console.log(lis.parentNode); 打印输出当前的lis的父节点;</script></body>
注:就近原则。(只能获取到最近的父级节点)
子节点操作parentNode.childNodes
但是,此方式会获取到所有的节点,元素节点,属性节点,文本节点。
<ul><li></li> </ul><script> let uls = document.querySelector('ul'); for(let i =0;i<uls.childNodes.length;i++){if(uls.childNodes[i].nodeType ==1){console.log(uls.childNodes[i]);} }</script>
所以如果获取子元素节点可以使用:parentNode.children
是一个只读属性,返回所有的子元素节点。
获取到第一个子节点:parentNode.firstChild
但是此方法会获取到是包含,元素节点,属性节点,文本节点的第一个节点;
如果只获取到第一个子元素节点:parentNode.fristElementChild,
获取到最后一个子元素几点: parentNode.lastElementChild
实例:
let nav = document.querySelector('.nav'); let lis = nav.children; //获取到下边的子元素节点 for(let i =0;i<lis.length;i++){lis[i].children[1].onmouseover=function(){this.children[1].style.display = 'block'}lis[i].children[1].onmouseout=function(){this.children[1].style.display = 'none'} }
兄弟节点:
1、node.nextSibling:返回当前元素的下一个兄弟节点(包括元素节点,属性节点,文本节点),找不到则返回Null,同样包括全部的节点;
2、node.previousSibling :返回当前元素的上一个兄弟节点(包括元素节点,属性节点,文本节点),找不到则返回Null,也是返回全部的节点。
3、node.nextElementSibling: 返回当前元素的下一个元素节点,找不到返回Null;
4、node.previousElementSibling;返回当前元素的上一个元素节点,找不到返回Null
创建节点:
document.createElement('节点');
例如:document.createElement('li');
<ul></ul>let li = document.createElement('li'); 首先创建一个节点 let ul = document.querySelector('ul'); ul.appendChild(li); 创建的元素追加到当前元素里边。
如果需要向页面前边追加一个新的元素:元素.insertBefore
节点案例:简单留言发布
let btn = document.querySelector('button'); let text = document.querySelector('textarea'); let ul = document.querySelector('ul'); btn.onclick=function(){if(text.value !==''){let li = document.createElement('li');li.innerHTML = text.valueul.insertBefore(li);} else{return}}
删除节点:
node.removeChild(child) :这个方法是从DOM 中删除一个子节点,返回删除的节点
javascript:;禁止默认行为
let btn = document.querySelector('button'); let text = document.querySelector('textarea'); let ul = document.querySelector('ul'); btn.onclick=function(){if(text.value !==''){let li = document.createElement('li');li.innerHTML = text.value + "<a href='javascript:;'>删除</a>"ul.insertBefore(li, ul.children[0]); 把当前li追加到ul的第一个位置let as = document.querySelectorAll('a');for(let i =0;i<as.length;i++){as[i].onclick=function(){ul.removeChild(this.parentNode);}}} else{return}}
克隆节点(赋值节点)
node.cloneNode( true| false): 方法返回调用该方法的节点的一个副本。也称为克隆节点/拷贝节点
如果为true:表示为深拷贝;
如果不添加或者为false,表示为浅拷贝;
深拷贝表示节点,内容都拷贝;
浅拷贝表示只拷贝节点;
案例动态生成表格:
<body><table cellspacing="0"><thead><tr><th>name<th><th>class<th><th>age<th><th>num<th></tr></thead><tbody></tbody></table><script>let datas={[{name:'张三',class: '一般'age: 20 },{name:'张三',class: '一般'age: 20 },{ name:'张三',class: '一般'age: 20} ]}let tbody = document.querySelector('tbody');for(let i=0;i<datas.length;i++){let tr = document.createElement('tr');tbody.appendChild(tr);//行里边创建单元格td,单元格的数量取决于每个对象里边的属性的个数,for...in...遍历出来对象for(let k in datas[i]){//创建节点tdlet tds = document.createElement('td');tds.innerHTML = data[i][k]tr.appendChild(td)//把对象里边的属性值 data[i][k]赋值给td}//创建删除的单元格let td = document.createElement('td');td.innerHTML = "<a href='javascript:;'></a>"向当前行里边追加删除单元格tr.appendChild(td)}点击删除,删除整行let as = document.querySelectorAll('a') 获取到所有的删除的afor(let i = 0;i<as.length;i++){ //遍历所有的啊,给每个添加点击事件as[i].onclick=function(){tbody.removeChild(this.parentNode.parentNode) //移除节点,点击删除,它的父几点是单元格,单元格的父几点是行}}</script> </body>
创建元素的三种方式:
1、document.write():如果页面文档流加载完毕后,在调用这段代码,会使得页面重绘;
2、document.innerHTML;
3、document.createElement();
document.innerHTML和document.createElemnet的区别:
document.innerHTML:如果采用拼接字符串的方式,效率会很低;但是如果采用先拼接到数组里,然后把这个数组用join()分隔为字符串就效率高;
document.createElement: 这样方式效率略低于innerHTML的数组方式,但是结构清晰。
DOM重点核心:
文档对象模型简称:DOM,是可扩展标记语言的编程接口;
DOM操作主要针对元素的:增删改查;
创建 :document.write
document.innerHTML
document.createElement
增加:appchild innerBefore
修改:
删除:removeChild
查询:
事件高级:
注册事件的两种方式:
传统注册事件:
1、onclick ,onmouseover等;
事件侦听注册事件:
2、addEventListener
里面的事件类型是字符串,必定加引号,而且不带on,
同一个元素,同一个事件可以添加多个侦听器
let btns = document.querySelectorAll('button'); btns[0].addEventListener('click',function(){alert('弹出一个对话框'); }) btns[0].addEventListener('click',function(){alert('弹出一个对话框'); })
当点击按钮时可以先后弹出两个对话框
删除事件:
传统删除事件的方式:元素.事件名 = null
let divs = document.querySelector('div') divs[0].onclick = function(){alert(); } divs[0].onclick = null
事件侦听删除事件:
removeEventListener('事件名称', 函数)
divs[1].addEventListener('click', fun) 删除事件时候,就需要使用命名函数了function fun(){alert();div[1].removeEventListener('click', fun); }
DOM事件流
DOM事件流分为三个阶段:1、捕获阶段 2、当前目标阶段 3、冒泡阶段
DOM 事件流在js代码中只能执行捕获或者冒泡其中一个阶段
onclick事件: 冒泡事件
在事件侦听中,addEventListener的第三个参数如果是true是捕获阶段,如果是false或者不写就是冒泡阶段。
什么是事件对象?
event就是一个事件对象,元素.onclick = function(event){}
例如:div.onclick = function(event){}
事件对象就是我们事件的一系列的相关数据的集合,与事件相关,比如点击事件里边包含了与点击事件有关的信息,属性,方法;鼠标移动事件包含所有的和鼠标相关的属性和方法等。
这个事件对象可以自己命名,比如e;
事件对象常见的属性和方法:
1、e.target()返回触发事件的对象,div,span
2、e.type 返回事件的类型,click ,mouseover
3、e.preventDefault() 阻止默认事件,比如不让链接跳转;
4、e.stopPropagation() 阻止事件的冒泡
e.target和this的区别:
e.target返回的是触发事件的对象(元素),
this返回的是绑定事件的对象(元素)
阻止默认行为:preventDefualt()
<a href="#"></a>
let a = document.querySelector('a');
a.addEventListener('click', function(e){
e.preventDefult(); //标准写法
})
阻止事件冒泡:stopPropagation()
事件委托:
事件冒泡本身特性,有时不需要冒泡,有时使用冒泡可以有很好的作用。
原理:
不单独给子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子阶段。
<body><ul><li>子节点</li><li>子节点</li><li>子节点</li></ul><script>//给父节点添加事件侦听器,利用事件冒泡给子节点添加。let ul = document.querySelector('ul')ul.addEventListener('click',function(){alert('点击子节点,根据点击冒泡,触发父节点事件');})</script> </body>
鼠标事件对象
event对象代表事件的状态,跟事件相关的一些列信息的集合。
e.clientX :返回鼠标相对于浏览器窗口可视区的X坐标;
e.clientY : 返回鼠标相对于浏览器窗口可视区的Y坐标;
e.pageX: 返回鼠标相对于文档页面的X坐标
e.pageY : 返回鼠标相对于文档页面的Y坐标
e.screenX : 返回鼠标相对于电脑屏幕的X坐标;
e.screenY: 返回鼠标相对于电脑屏幕的Y坐标;
实例:
<img src='image.png'> <script>let img = document.querySelector('img')document.addEventListener('mousemove', function(e){let x = e.pageXlet y = e.pageYimg.style.left = y + 'px'img.style.top = x + 'px'});</script>
常用的键盘事件:
1、onkeyup(事件侦听:keyup) : 键盘按键松开时触发;
2、onkeydown(事件侦听:keydown): 键盘按钮按下时触发;
3、onkeypress(事件侦听:keypress): 键盘按键被按下时触发(但是不识别特殊功能键)
键盘事件对象:
keyCode:返回的是对应键盘的ASCII码值。
keyup 和 keydown 这两个事件,不区分字母大小写,即a和A 返回keyCode的值一样
<script>document.addEventListener('keyup', function(e){console.log(e.keyCode);});document.addEventListener('keydown',function(e){console.log(e.keyCode)})</script>
但是keypress区分大小写:
A返回97
a返回65
document.addEventListener('keypress', function(e){console.log(e.keyCode) })
案例按键按下指定键,页面有相应操作:
思路:首先判断是否按下的s键,如果按下的是s键光标定位在输入框;
然后:使用键盘事件对象的keyCode判断;
搜索框获得焦点:使用js里面的focus方法
<input type='text'> <script> let search = document.querySelector('input'); document.addEventListener('keyup',function(e){if(e.keyCode = 83){search.focus()} })</script>
案例:输入框输入,显示放大数字
<body><div><div class = 'con'></div><input type = 'text' placeholder="请输入内容" class = 'jd'></div><script>let con = document.querySelector('.con');let int = document.querySelector('input');int.addEventListener('keyup',function(e){if(int.value === ''){con.display = 'none'} else {con.display = 'block'con.innerText = int.value}})</script> </body>
BOM部分
即浏览器对象模型;提供了独立于内容而与浏览器进行交互的对象;
BOM 把一个浏览器当做一个对象来看待;顶级对象是window;
BOM中包含DOM
BOM的构成:window对象是浏览器的顶级对象,具有双重角色;
1、它是JS访问浏览器的一个接口;
2、它是一个全局对象,定义在全局作用域中的变量,函数都会变成window的属性和方法;
所有在调用时候可以省略window;
window对象常见的事件:
一、窗口的加载事件(方法一):
window.onload = function(){}
或者:
window.addEventListener('load',function(){})
就是当文档内容(包括,图片,样式,文本,脚本文件等)完全加载完毕后会触发这个事件。
注意:
window.onload()传统注册事件只能执行一次,如果多个只会执行最后一个window.onload
window.addEventListener('load',function(){})可以有多个;
二、窗口加载事件(方法二)
window.addEventListener('DOMContentLoaded',function(){});
仅当DOM加载完毕后就可以触发,不包括样式,图片脚本等;
定时器倒计时效果:
<script>let hour = document.querySelector('.hour');let minute = document.querySelector('.minute');let second = document.querySelector('.second');let inputTime = +new Date('2023-6-1 18:00:00'); //获取当指定时间的时间戳countDown(); //为了防止定时器页面刷新空白时间,先执行一次定时器setInterval(counTDown, 1000); //定时器每隔几秒执行一次function countDown() { //倒计时时间戳函数let nowTime = +new Date();let times = (inputTime - nowTime) / 1000; 当前剩余秒数let h = parseInt(times / 60 / 60 % 24); 获取剩余小时let m = parseInt(times / 60 % 60)let s = parseInt(times % 60)h = h < 10 ? '0' + h : h;m = m < 10 ? '0' + h : m;s = s < 10 ? '0' + s : s;hour.innerText = hminute.innerText = msecond.innerText = s}</script>
清除定时器:
<button class = 'beg'>开始定时器</button> <button class = 'stop'>关闭定时器</button> <script>let beg = document.querySelector('beg');let stp = document.querySelector('stop');let timers = nullbeg.addEventListener('click', function(){let timers = setInterval(()=>{console.log('123132');},2000)})stp.addEventListener('click', function(0){clearInterval(timer)})</script>
this的指向问题
1、全局作用域或者普通函数的this指向全局对象window(注意:定时器里面的this指向window)
function fun(){console.log('this在全局作用域或者普通函数指向的是window') } window.fun()
2、在方法中this的指向,
let a = {sayHi: function(){console.log(this)}} a.sayHi();------------------------- let btn = document.querySelector('button'); btn.onclick = function(){console.log();}
3、构造函数中this指向的是new的创建的实例
重点:
JS执行机制——同步和异步
同步:前一个任务结束后才可以执行后一个任务。程序的执行顺序和任务的顺序是一致的。通俗的就是,一次只能做一件事,只有这件事做完才可以做另一件事。
异步:可以执行好几个任务
<script>console.log('123')setTimeout(function(){console.log('456')})console.log('789') </script>
程序执行结果是:123789456
js执行时会先执行主线程里边的同步任务,执行完后再执行任务列队(消息队列)中的异步任务。
先执行执行栈中的同步任务,
异步任务放入任务队列中;
一旦同步任务都执行完毕,开始执行异步任务。
一般异步任务有三种类型:
1、普通事件;
2、资源加载;
3、定时器;
当多个同步异步任务都有时:
首先会先放到异步进程处理里边,事件,定时器,资源加载都会先放进这里边,对于事件,如果没有触发就不放到异步任务队列里边,定时器如果没有到事件也不会放进入。
同时,每次异步进程都会去查看任务队列里是否有任务,
location对象
window对象给我们提供了一个location属性用于获取或设置窗体的URL,并且可以用于解析URL。因为这个属性返回的是一个对象,所以我们将这个属性也称为Location对象。
案例:获取不同页面之间的数据传递
<body><form action = 'index.html'>用户名:<input type = 'text' name = 'uname'><input type = 'submit' value ='登录'></form> </body>//从页面一向页面二跳转<body><div></div><script>//location.search获取到的就是传过来url上的?后边的参数let params = location.search.substr(1); //uname = andylet arr = params.split('='); // 利用 = 把字符串分割为两个数组let divs = document.querySelector('div')div.innerHTML = arr[1] + '欢迎您'</script> </body>
location的常见用法:
1、location.assign():与href一样,可以跳转页面(重定向页面),带历史记录,可以后退
<body><button></button><script>let btn = document.querySelector('button');btn.addEventListener('click', function(){location.assign('http://www.baidu.com')})</script> </body>
2、location.replace():替换当前页面,因为不记录历史,所以不能后退;
<body><button></button><script>let btn = document.querySelector('button');btn.addEventListener('click', function(){location.replace('http://www.baidu.com')})</script> </body>
3、location.reload():重新加载页面,相当于刷新按钮或者F5,如果参数为true,强制刷新;
<body><button></button><script>let btn = document.querySelector('button');btn.addEventListener('click', function(){location.reload() //location.reload(true) 强制刷新})</script> </body>
navigator对象
包含浏览器的信息,有很多属性,最常用的userAgent,这个属性可以返回客户机发送服务器的user-agent头部的值。
history对象
offset相关介绍
offset简介:动态获取到当前该元素的位置(偏移),大小等。
1、获得元素距离带有定位父元素的位置。
2、获得元素自身大小(宽度高度)
3、注:返回的值不带单位。
常用的offset属性有:
①element.offsetParent:返回当前元素带有定位的父级元素,如果父级都没有定位则返回body;
(注意:它和node.parentNode有区别,前者返回带定位父元素,后者是最近一级父元素)
②element.offsetTop:返回元素相对带有定位父元素上方的偏移;
③element.offsetLeft:返回元素相对带有定位父元素左边框的偏移;
④element.offsetWidth:返回元素自身包括padding,边框,内容区的宽度,返回数值不带单位;
⑤element.offsetHeight:返回元素自身包括padding,边框,内容区的高度,返回数值不带单位;
<div style="position:relation" class = 'f'>父元素<div style="position:" class = 's'>子元素</div> </div><script>let f = document.querySelector('.f');let s = document.querySelector('s');console.log(s.offsetParent)console.log(s.offsetTop);console.log(s.offsetLeft);console.log(s.offsetWidth);console.log(s.offseTHeight) </script>
offset和style的区别:
offset可以获取到任意样式表中的样式值;
但是获取到的值没有单位;
offsetTop和offsetLeft是包含padding和边框和内容宽度,高度的;
并且offset系列不可以修改值;
-------------------------------------
style只可以获取到行内样式表的样式值,
但是获取到的值是带有单位的;
style.width不包含有padding和border值,
style.height是可读写属性,可以获取到值,也可以赋值,所以如果需要更改样式大小值,可以使用;
<body><div style="width: 300px"></div><script>let d = document.querySelector('div');d.style.width = '400px'</script></body>
实例:获取到鼠标移动时在盒子里的坐标(e.pageX, e.pageY)
<body><div class = 'divClass'></div><script>let di = document.querySelector('.divClass')di.addEventListener('mousemove', function(e){console.log(e) //打印输出的是事件对象let x = e.pageX - di.offsetLeftlet y = e.pageY - di.offsetTopconsole.log('当前点击盒子里坐标x 为'+x+'y坐标为:'+ y);})</script></body>
实例拖拽模态框案例
由于代码稍微多,具体请看pink老师教程:
【JavaScript前端课程-dom-bom-js-es6新语法-jQuery-数据可视化echarts黑马pink老师前端入门基础视频教程(500多集)持续】 https://www.bilibili.com/video/BV1Sy4y1C7ha/?p=292&share_source=copy_web&vd_source=0b14fab0cad18656d9ffed500fb3ca30关键代码如下:
<script>let login = document.querySelector('.login');let mask = document.querySelector('.beijing');let link = document.querySelector('#link');let title = document.querySelector('.tit');let closeBtn = document.querySelector('#btn');点击弹出让登录框,背景显示出来link.addEventListener('click', function(){mask.style.display = 'block'mask.style.display = 'block'})closeBtn.addEventListener('click', function(){mask.style.display = 'none'mask.style.display = 'none'})title.addEventListener('mousedown', function(e){//获取到当前鼠标按下后的下盒子里坐标let x = e.pageX - login.offsetLeftlet y = e.pageY - login.offsetTop //鼠标移动时,把当前鼠标在页面坐标减去在盒子里坐标赋值给Logindocument.addEventListener('mousemove', mov)function mov(e){login.style.left = e.pageX - xlogin.style.top = e.pageY - y}document.addEventListener('mouseup', function(){document.removeEventListener('mousemove', mov);})})</script>
元素可视区client系列
client翻译过来就是客户端,使用client系列的相关属性来获取元素可视区的相关信息。通过client的相关属性可以动态得到该元素的边框大小,和元素大小等。
client系列属性(不包括边框)
element.clientTop: 返回元素上边框的大小,没有单位
element.clientLeft: 返回元素左边框的大小,没有单位
element.clientWidth: 返回自身包括padding,内容区的宽度,没有单位
element.clientHeight: 返回自身包括padding ,内容区高度的值(没有单位)
立即执行函数:不需要调用直接执行
两种写法:
1、(function(){})()
(function(a,b){
console.log('123')
})(1,2)
括号里传参
2、(function(){}())
(function sum(a,b){
console.log('abc');
}(2,3))
元素滚动scroll系列
动态的可以获取到元素的大小,滚动距离等。
element.scrollTop:返回被卷去的上边距离,不带单位。
element.scrollLeft: 返回被卷去的左侧距离,不带单位。
element.scrollWidth: 返回元素实际自身的宽度,不包括边框,不带单位。
element.scrollHeight: 返回元素自身的高度,不包括边框,不带单位
新方法:window.pageYOffset
window.pageXOffset 分别表示:返回窗口距离X轴方向的距离,返回Y轴方向距离
<bod><div><span>返回头部</span></div><div class = 'header w'>头部</div><div class = 'banner w'>banner</div><div class = 'main w'>主体部分</div><script>let sliderbar = document.querySelector('.slider-bar')document.addEventListener('scroll', function(){console.log(window.pageYoffsetLeft);console.log(window.pageXoffsetTop);if(window.pageYoffset >= 172){sliderbar.style.position = 'fixed'}else {sliderbar.style.position = 'absolute'}}) </script> </body>
三个系列总结:
1、首先:element.offsetWidth:获取自身的宽度高度,包括边框宽度,padding的宽度;
offset系列经常用于获取元素的位置offsetLeft和offsetTop;
2、element.scroll:获取的是被卷去部分的宽度,高度,不包括边框;scroll系列经常用于获取滚动距离,scrollLeft,scrollTop;
3、element.client:获取的是包括自身,也包括Padding,不包括边框的值,因为它可以获取边框宽度,经常用于获取滚动的距离scrollTop,scrollLeft
注:页面滚动的距离是通过window.pageXoffset或者window.pageYoffset获取到;
mouseenter和 mouseover的区别:
<body><div class = 'f'>父盒子<div class = 's'>子盒子</div></div><script>let f = document.querySelector('f');let s = document.querySelector('s');s.addEventListener('mouseenter', function(){console.log('子盒子鼠标滑过不会触发父盒子')})// ----------------------s.addEventListener('mousemover',function(){console.log('会冒泡到父盒子,');})</script> </body>
动画函数的简单封装:
注:这个简单函数需要传递两个参数。
<script>function fun(obj,num){let timer = setInterval(function(){if(obj.offsetLeft >= num){clearInterval(timer)} else{obj.offsetLeft = obj.offsetLeft + 1 + 'px'}},500)}let div = document.querySelector('div')fun(div,500)</script>
怎样给不同元素记录不同定时器
如果多个元素都使用这个定时动画函数,每次都会创建一个定时器,会影响效率。
所以可以采用为每个对象使用不同定时器(对象使用自己的定时器)
核心原理:js是一个动态语言,可以为当前对象添加属性;
同时:为了防止每次执行函数都会创建一个定时器的问题,每次执行函数之前先清除前一个定时器;
<body><div></div><script>function animate(obj, num){clearInterval(obj.timer) //为了防止创建多个相同定时器,每次执行先清除前一个定时器obj.timer = setInterval(function(){if(obj.offsetLeft >= num){clearInterval(tim)} else {obj.offsetLeft = obj.offsetLeft + 10 + 'px'}}, 500)}animate(div,200)</script> </body>
动画函数封装——动画缓动效果
原理:就是让元素运动速度有所变化;
思路:
1、让每次移动的距离慢慢变小,速度就相应的慢下来;
2、核心算法:(目标值 - 现在位置) / (步长数) = 每次移动的距离;
3、停止条件:让盒子位置等于目标位置就停止定时器;
<body><div></div><script>// obj是元素,num是目标值function animate(obj, num){clearInterval(obj.timer)//为了防止创建多个相同定时器,每次执行先清除前一个定时器obj.timer = setInterval(function(){let step = (target - obj.offsetLeft) / 10;step = step > 0 ? Math.ceil(step) : Math.floor(step)if(obj.offsetLeft >= num){clearInterval(obj.timer);}obj.style.left = obj.offsetLeft + step + 'px';}, 500)}animate(div,200)</script> </body>
动画添加回调函数:
<head><script src='animate.js'></script> </head> <body><div class = 'sliderbar'><span>箭头</span><div class = 'con'>滑动滑块</div></div><script>let sliderbar = document.querySelector('.sliderbar');let con = document.querySelector('.con');sliderbar.addEventListener('mouseenter', function(){animate(con, -200, function(){sliderbar.children[0].innerHTML = '滑到右边'})})sliderbar.addEventListener('mouseleave', function(){animate(con, 0, function(){sliderbar.children[0].innerHTML = '滑动回来'})})</script> </body>
节流阀:
防止动画执行太快,当上一个执行完毕再执行下一个;
案例:筋斗云案例
思路:
1、利用动画效果实现;
2、原始位置是0,;
3、鼠标经过某个小Li就把当前Li的OffsetLeft作为目标值;
4、鼠标离开某个小li就把目标值设为0;
5、点击那个li,就把当前li点击位置存到原始位置遍历;
<script>let current = 0;for(let i =0;i<lis.length;i++) {lis[i].addEventListener('mouseenter', function(){animate(cloud, lis[i].offsetLeft);})lis[i].addEventListener('mouseleave', function(){animate(cloud, current)})lis[i].addEventListener('click', function(){current = this.offsetLeft;})}</script>
移动端事件:
触屏touch事件
touchstart :手指触摸到一个DOM元素时触发;
touchmove: 手指在一个DOM元素滑动时触发;
touchend; 手指从一个DOM元素上移开时触发;
let div = document.querySelector('div'); div.addEventlistener('touchstart', function(){console.log('移动端开始触摸事件')})--------------------------- div.addEventlistener('touchmove', function(){console.log('移动端在元素上移动事件'); }) ----------------------- div.addEventlistener('touchend', function(){console.log('移开元素')})
1、触摸事件对象(TouchEvent)
有三个常见对象列表:
1.touches:正在触摸屏幕的所有手指的一个列表,有几个手指在触摸返回几个;
2.targetTouches:正在触摸当前DOM元素上的手指的一个列表;
3.changedTouches:手指状态发生了改变的列表,从无到有,从有到无的变化;
本地存储
特性:
1、数据是存储在浏览器中;
2、设置,读取方便,页面刷新也不会丢失数据;
3、容量大,但是只能存储字符串,可以将对象JSON.stringify()编码后存储;
一、window.sessionStorage
生命周期为关闭浏览器窗口;
在同一个页面,窗口下数据共享;
以键值对形式存储使用;
(1)、存储数据到本地浏览器中;
(window.)sessionStorage.setItem(key, value)
(2)、获取到本地浏览器中存储的数据;
sessionStorage.getItem(key)
(3)、删除数据;
sessionStorage.removeItem(key)
(4)、清空所有浏览器中数据
sessionStorage.clear()
二、window.localStorage
声明周期永久生效,除非手动删除;
同样也是以键值对形式存储数据;
多窗口,页面共享数据;
(1)、存储数据;
localStorage.setItem(key,value)
(2)、查询数据;
localStorage.getItem(key)
(3)、删除数据
localStorage.removeItem(key)
(4)、清空
localStorage.clear()
小实例:
<script><input type = 'text' id = 'username'> <input type = 'checkbox'>勾选</input> </input>let username = document.querySelector('#username');let remember= document.querySelector('#remember');if(localStorage.getItem('username')) {username.value = localSorage.getItem('username');remember.checked = true}remember.addEventListener('change', function(){if(this.checked) {localStorage.setItem('username', username.value)} else {localStorage.removeItem('username')}})</script>
------------------------
JQuery
是一个快速的JavaScript库;
JQuery的基本使用——入口函数
$(function(){
})
或者:
$(document).ready(function(){})
使用方式一:
<body><script>$(document).ready(function(){$('div').hide()})</script><div></div></body>
使用方式二:
<body><div></div><script>$(function(){$('div').hide()})</script></body>
1、等DOM结构渲染完毕后即可执行内部代码,不必等到所有外部资源加载完成;
2、相当于原生js中的DOMContentLoaded;
3、不同于原生js中的load事件,外部资源文件加载完才执行内部代码;
jQuery的基本使用——顶级对象“$”
“$” 是jQuery的别称,在代码中可以使用jQuery代替;
DOM对象和jQuery对象
1、使用原生js获取到的对象就是DOM对象
let divs = document.querySelector('div')
2、jQuery方法获取的元素就是jQuery对象,其本质就是$对DOM对象包装后产生的对象。
$('div'): 获取到的是jQuery对象
jQuery对象只能用jQuery的方法,
$('div').css('background', 'pink')
DOM对象使用的是原生的js属性和方法;
divs.style.display = 'none'
DOM对象和jQuery对象可以相互转换
1、DOM对象转为jQuery对象
<body><video src = 'mv.mps'></video><script>$('video'); let myvideo = document.querySelector('video')myvideo.play();</script></body>
(1)、直接获取视频,得到的就是jQuery对象;
2、jQuery对象转为DOM对象(两种方式)
1、$('div')[index] : index是索引号
<video></video> <script>$('video')[0].play()//或者$('video').get(0).play() </script>
2、$('div').get(index) : index是索引号
jQuery选择器
jQuery基础选择器:$("选择器") //里边选择器直接写css选择器即可,需要加引号
层级选择器:
(1、)子代选择器:
$('ul > li') : 只获取到“儿子”层级元素;
(2、)后代选择器:
$('ul li') : 获取到父级下边所有元素;
jQuery隐式迭代
<div></div> <div></div> <ul><li></li><li></li> </ul> <script> //直接获取到元素,然后设置背景$('div').css('background', 'red')//隐式迭代$('ul li').css('background', 'red') </script>
复习js部分(每日更新)相关推荐
- IT招聘(每日更新)
IT招聘[每日更新] 写在前面 招聘信息 写在前面 招聘职位皆为我公司真实在招职位, 首先声明的是这里的工作都是外派工作[我司为大型外包公司], 外派的单位主要面向国企和一线大厂, 大家如有需求可根据 ...
- Arxiv最新论文,深度学习热点论文,Arxiv每日更新
最新论文 https://arxiv.org/list/cs/recent 深度学习热点论文 https://deeplearn.org/ github 顶会摘要 每日更新 https://githu ...
- JS设置每日定时任务
JS设置每日定时任务 文章目录 JS设置每日定时任务 方式一.手写简单实现 方式二.使用npm包node-schedule 方式一.手写简单实现 主要函数: /*** 设置每日定时任务* @param ...
- Java开发面试高频考点学习笔记(每日更新)
Java开发面试高频考点学习笔记(每日更新) 1.深拷贝和浅拷贝 2.接口和抽象类的区别 3.java的内存是怎么分配的 4.java中的泛型是什么?类型擦除是什么? 5.Java中的反射是什么 6. ...
- 【JS】问题——解决JS文件页面更新不生效问题
解决JS文件页面更新不生效问题 问题产生 昨天在本地测试一个web项目,启动后页面某个按钮点击没反应,通过浏览器控制台,追了追代码发现js写法不支持,就顺手把js文件给改了.然后重新发布,点击按钮发现 ...
- iOS8高清壁纸 - 专为iOS8量身定做,每日更新
特色功能介绍: 1.海量的高清精美壁纸 2.每日更新,让您紧跟潮流壁纸的步伐 3.提供多达21个类别以供筛选 4.专为iOS8系统iPhone量身定做,壁纸保存后无需修改,可直接选作壁纸
- Python爬虫,爬取快看漫画每日更新模块
文章目录 前言 一.爬虫是什么? 二.使用步骤 1.引入库 2.文件夹准备 3.将列表存储为txt格式文件 4.爬取每日更新页面具体代码: 5.运行结果 总结 前言 根据基本的爬虫知识,爬取快看漫画每 ...
- 浏览器中的js不能同步更新的解决方案
解决方案有三种,分别是: 1.清浏览器缓存 2.清服务器缓存 3.更改项目中对应的js文件名(大招) 在项目的整合过程出现了浏览器中的js和项目里面的js不是同步的.起初,由于需求变动,需要前端多传三 ...
- 李佳琦10月24日美妆节预告,李家琦双十一预告每日更新
李佳琦10月24日美妆节预告,李家琦双十一预告每日更新 2022年双11预售已经开始了,李家琦将在10月24日20点双11直播,第一天10.24是美妆节,爆款麦庄产品抢先预定,本文小编为姐妹们带来了李 ...
- 【04-05】最新精选绿色软件每日更新(小熊整理)
[媒体播放] ScenicPlayer 科建情景课件播放器 2.08.3174 [媒体播放] Media Player Classic 6.4.9.1 SVN 49 简体中中文版 [媒体转换] 私房i ...
最新文章
- 最小乘积生成树和最小乘积最大匹配
- windbg内存断点学习总结
- sklearn-标准化标签LabelEncoder
- Java实训项目:GUI学生信息管理系统(2019)【中】
- Java应用程序的基本框架
- 腾讯上线视频社交App:让你与陌生人美颜视频通话聊天
- App 开发穷途末路?
- python 一些练习 (初学)
- IDEA插件: 一键自动部署jar到远程服务器 使用 Cloud Toolkit 来部署应用到腾讯云、阿里云服务器
- 项目管理面试常见问题及答案
- C/S与P2P的主要区别以及相同点
- Python 文件处理
- 大学计算机基础教程excel实验报告,大学计算机基础教程excel实验报告.doc
- 微信小程序-组件样式覆盖
- 采集需要登录后的网页(重定向后cookie丢失问题)
- C语言中void具体有什么作用
- 预告 | 今天16点,来看VC投资的机遇与挑战;本周四,你最关心的区块链与数字金融投资机遇又来了!
- 软件定义存储的定义与分类
- RTX基于32位Windows实时操作系统
- 老虎证券Java面经_老虎证券前端一面