ES核心语法:可以简化操作
Dom的概念
操作元素(增、删、改、查)
Bom的概念
- EcmAscript:核心语法=>升级简化操作
-
ES5:保护对象:保护对象的属性和方法 1、四大特点可以保护对象,对象的每个属性都有4大特性,3个开关默认为ture { value: 1001,//保存实际值的地方 writable: true,//开关:控制属性是否可以被修改 enumerable: true,//开关:控制属性是否可以被for in循环遍历 configurable: false//开关:控制属性是否可以被删除,总开关,一旦设置为false就不会允许修改其他特性,它本身一旦改为false不可逆 }
2、修改对象的某个属性的四大特性: Object.defineProperties(obj,{ "属性名":{四大特性}, ... })2、三个级别: 1、防扩展:防添加 Object.preventExtensions(obj);
2、密封:防添加防删除 Object.seal(obj) 3、冻结:防添加防删除防修改 Object.freeze(obj);不推荐: 1、如果以后你使用面向过程开发 2、前辈们都没有保护 数组的新的API:3组6个 1、判断:判断数组中的元素是否满足我们的条件 1、every:判断数组中的元素是否【都】满足我们的条件,类似于我们的&&,只要有一个为false则为false 2、some:判断数组中的元素是否【包含】满足我们的条件,类似于我们的||,只要有一个为true则为true 语法:arr.every/some(function(val,i,arr){ //val:当前值 //i:当前值的下标 //arr:数组本身 //虽然提供了3个形参,但是到底要用几个看我们自己 //切忌:函数自带return undefined; return 判断条件; })
2、遍历:把数组中的每个元素取出来执行相同 或 相似的操作 1、*****forEach:直接修改原数组 arr.forEach(function(val,i,arr){ 直接写操作; })
2、*map:不修改原数组,直接返回新数组 var newArr=arr.map(function(val,i,arr){ return 直接写操作; })3、汇总和过滤: 1、过滤:筛选出符合条件的元素: - 不会修改原数组 var subArr=arr.filter(function(val,i,arr){ return 判断条件; })
2、汇总:将所有的数组的元素进行+-*/ var sum=arr.reduce(function(prev,val,i,arr){ return prev+val; },base)以上6个API简化for循环
3、var 子对象=Object.create(父对象,{ "属性名":{四大特性}, ... }) - 根据一个父对象创建一个子对象并且继承已经设置完毕,提前保护对象 4、call/apply/bind:替换了函数中的this 1、call/apply:临时替换了函数中的this - 借 差别:call:要求传入的实参必须单独传入 apply:要求传入的实参必须整理为一个数组,只能传一个数组参数 强调:call/apply相当于立刻调用函数 用法:方法名.call(借用的对象,实参,...) 方法名.apply(借用的对象,[实参,...]) - apply自动打散数组
固定套路: Object.prototype.toString.call/apply(数组) Math.max/min.apply(Math,arr); *关键点:将类数组转为普通数组 lis=Array.prototype.slice.call(lis);2、bind:永久替换了函数中的this - 买 3件事 1、创建了一个函数功能和原函数完全一样 2、将新函数的this永久绑定为了你指向的对象 3、将信函书中的部分固定参数提前永久绑定
用法:var 新方法名=方法名.bind(永久绑定的对象,永久绑定的实参,...); 不会立刻执行,需要我们程序员手动调用个人建议:如果你的这方法要经常反复使用,可以使用bind - 买 *如果你需要一个方法立刻就要执行,建议call/apply - 借 5、严格模式:很严格 开启严格模式:"use strict"; - 可以出现在任何作用域的顶部 用处: 1、禁止给未声明的变量进行赋值 2、将静默失败升级为错误
二、ES6:简化了/改变了语法:
1、模板字符串:支持直接在字符串中书写变量
我的名字叫${name}
再也不用""和''了
2、块级作用域: 将var替换为let用于创建变量:优先使用let 作用: 1、let之前不允许出现未声明的同名变量 - 解决声明提前 2、添加了块级作用域: 一个{}就是一个块 3、*绑定事件时,会记录着当前元素的下标 不需要自己定义自定义下标
3、箭头函数:简化一切的回调函数 回调函数:匿名函数,没有自调,就是回调 公式:去掉function,()和{}之间添加=>,如果形参只有一个省略(),如果函数体只有一句话省略{},如果函数体只有一句话并且是return,{}和return都省略
箭头函数中如果出现this->外部的对象
建议:我们在事件中暂时不要简化为箭头函数
4、for...of循环 - 垃圾 for(var v of arr){ v;//当前值 }
缺点:
1、不能直接修改原数组,只能返回新数组
2、不能遍历hash数组,不能遍历对象(其实可以需要多加一句话)
小案例(摇号:) 思路分析:首先在页面上创建一个无序列表,然后获取页面元素,把类数组变为普通数组,再创建一个空数组用于自定义属性的随机数,生成随机数放入空数组中再将随机数作为自定义属性的值,再通过自定义属性来排序。
var lis=document.getElementsByTagName("li");//类数组
lis=Array.prototype.slice.call(lis);
var nums=[];
while(nums.length<lis.length){
var r=parseInt(Math.random()*(lis.length)+1);
if(nums.indexOf(r)==-1){
nums.push(r); }
}
lis.forEach((val,i)=>val.setAttribute("dy",nums[i]))
lis.sort((a,b)=>a.getAttribute("dy")-b.getAttribute("dy"))
lis.forEach(val=>list.appendChild(val))
三、元素的增删改查
增加: 1、元素:3步 1、var elem=document.createElement("标签名"); 2、elem.属性名="属性值" elem.on事件名=function(){操作;} 3、父.appendChild(elem); 父.insertBefore(elem,已有子元素); 父.replaceChild(elem,已有子元素);
2、内容:elem.innerHTML/innerText/value+="新内容"
3、属性:elem.setAttribute("class","d1 d2");
4、样式:elem.style.css属性名="css属性值";//没有叫添加,有了叫替换
删: 1、元素:elem.remove();
2、内容:elem.innerHTML/innerText/value=""
3、属性:elem.removeAttribute("属性名");
4、样式:elem.style.css属性名="";//没有叫添加,有了叫替换
改: 1、元素:父.replaceChild(elem,已有子元素);
2、内容:elem.innerHTML/innerText/value="新值"
3、属性:elem.setAttribute("class","d2");
4、样式:elem.style.css属性名="css属性值";//没有叫添加,有了叫替换
查: 1、查元素:
1、直接找:
document.getXXX
document.querySelectorXXX
2、通过关系查找
3、层级不明确:递归(元素、数据)、遍历API、纯循环
2、查内容:elem.innerHTML/innerText/value;
3、查属性:elem.getAttribute("属性名");
4、查样式:elem.style.css属性名;//只能获取内联样式
新: 1、属性: 删除: 判断有没有:elem.hasAttribute("属性名"); -- 只能判断有没有不能判断具体值是什么 推荐: if(elem.getAttribute("属性名")=="值"){ 操作;}
2、样式: 样式表: 获取:document.styleSheets[i].cssRules[i].style.css属性名 设置:document.styleSheets[i].cssRules[i].style.css属性名="css属性值"
3、渲染页面:3种
父.appendChild(elem);
父.insertBefore(elem,已有子元素);
父.replaceChild(elem,已有子元素);
最推荐appendChild
删除元素:元素:elem.remove();
4、HTML DOM常用对象:个别可以简化
1、image:var img=new Image();
2、form:
var form=document.forms[i]
var input=form.elements[i]
onsubmit
3、select:
1、options===children
2、selectedIndex === 获取当前选中项的下标
3、add()
4、remove(i) === 删除下标为i的option
5、onchange
4、option:
select.add(new Option("innerHTML","value"))
四、BOM(Browser Object Model)
1、BOM:Browser Object Model 浏览器 对象 模型 提供了专门用于操作浏览器的API - 没有标准,使用的较少,但大部分浏览器厂商已经统一实现了(老IE)
2、BOM对象:window(重点:定时器)、history、location、navigator、event(重点)、screen...
3、window对象:扮演了2个角色: 1、浏览器中,window代替了ES的Global充当全局作用域 包含了所有的全局对象、变量、函数 2、指代当前浏览器的窗口
1、*网页打开新链接的方式
提升用户的体验感:
1、替换当前页面,可以后退:
HTML:<a href="url">文字</a>
JS:open("url","_self");
2、替换当前页面,禁止后退:使用场景:电商网页:结账完毕后,不允许用户后退
history对象:保存了当前窗口的历史记录,功能:前进后退
location:保存了当前窗口正在打开的url
location.replace("新url");//替换当前网址、不会产生历史记录
3、在新窗口打开,可以打开多个:
HTML:<a href="url" target="_blank">文字</a>
JS:open("url","_blank");
4、在新窗口打开,只能打开一个:使用场景:电商网页:跳转到 支付结账页面,只允许用户打开一个
HTML:<a href="url" target="自定义">文字</a>
JS:open("url","自定义");
自定义:窗口的底层都有一个名字,如果出现重复的名字则新窗口会替换掉原来的旧窗口
扩展:a标签可以做的事?
1、跳转
2、锚点
3、下载:<a href="xx.rar/zip/exe">文字</a>
4、打开图片、txt:<a href="xx.图片后缀/txt">文字</a>
5、直接书写js:<a href="javascript:js代码;">文字</a>
2、window对象:属性和方法: 属性:获取浏览器窗口的大小:文档显示区域的大小:body部分innerWidth/innerHeight
完整的浏览器大小:
outerWidth/outerHeight
屏幕的大小:没用 - 桌面应用才用的
screen.width/height
方法:
1、打开新窗口:var newW=open("url","自定义name","width=,height=,left=,top=");
特殊:如果没传入第三个参数,新窗口会和浏览器并为一体
如果传入第三个参数,新窗口会脱离浏览器
建议宽高不小于200
有可能会被浏览器拦截
2、关闭窗口:窗口.close();
3、修改窗口的大小:新窗口.resizeTo(newW,newH);
4、修改窗口的位置:新窗口.moveTo(x,y);
扩展:获取鼠标的坐标:
1、事件中传入一个形参e->获得到事件对象event(其中一个作用获取鼠标的坐标)
2、获取:
e.screenX/Y;//相对于屏幕
e.clientX/Y;//相对于浏览器客户端
*e.pageX/Y;//相对于网页的
鼠标跟随效果:关键点:
1、绑定事件:window.onmousemove
2、图片位置一定和鼠标位置一起
3、图片的加载速度比js的执行速度要慢,img.onload=function(){
//最后才会执行
}
5、定时器:2种:
1、周期性定时器:先等待,在执行一次,在等待,在执行一次...
开启:timer=setInterval(callback,间隔毫秒数);
停止:clearInterval(timer);
2、一次性定时器:先等待,在执行一次,结束
开启:timer=setTimeout(callback,间隔毫秒数);
停止:clearTimeout(timer);
两种定时器底层相同,可以互换,你爱用哪个就用哪个
好玩的小案例,点不到的小窗口按钮中 思路:先用一个div里面包着一个按钮,从屏幕中获得鼠标的位置,并且设置给div的定位属性设置随机数如果随机数,并且设置鼠标移入事件(onmouseover),当鼠标移入div时则改变div在屏幕上的位置。
| var rx=parseInt(Math.random()*((innerWidth-100)+1)+0) | |
|---|---|
| var ry=parseInt(Math.random()*((innerHeight-100)+1)+0) | |
| div2.style.left=rx+"px"; | |
| div2.style.top=ry+"px" | |
| div2.onmouseover=function(e){ | |
| var x=e.pageX; | |
| var y=e.pageY; | |
| var rx=parseInt(Math.random()*((innerWidth-100)+1)+0) | |
| var ry=parseInt(Math.random()*((innerHeight-100)+1)+0) | |
| div2.style.left=rx+"px"; | |
| div2.style.top=ry+"px" | |
| while(1){ | |
| if(!(x>rx&&r<(rx+100)&&y>ry&&y<(ry+100))){ | |
| div2.style.left=rx+"px"; | |
| div2.style.top=ry+"px" | |
| break; | |
| } | |
| } | |
| } |