第一天
一.ES5
一.ES5带来的新特性
1.保护对象:属性和方法
1)底层具有四大特性:
{
"value":"值" -->实际保存值的地方
"writable":true -->开关:控制着能否被修改
"enumerable":true -->开关:控制着可否被for in循环遍历到
"configurable":true -->开关:控制着是否可以被删除
四大特性在需要修改时不需要都写,需要用哪个改变哪个就可以了,但是注意
configurable也是一个总开关,一旦它变成了false
对象的属性和方法的其他三大特性都不能被再次修改,自己也不可逆转
}
如何修改四大特性:
Object.definePropertise(对象名,{
"属性名":{四大特性},
...
})
2)三个级别:
第一:防扩展:防止添加:Object.preventExtensitions(需要操作的对象名)
第二:密封:防止添加、删除:Object.seal(需要操作的对象名)
第三:冻结:防止添加、删除、修改:Object。freeeze(需要操作的对象名)
3)但是这个基本没用
如果不使用面对对象开发,就保护不了
而且前辈们都没保护,你更不需要保护
二.数组的新API:3组6个
1.判断:
every:每一个,理论上完全等效于&&,必须全部满足才能为true,一个不满足就为false
var bool=arr.every(function(val,i,arr){
return 条件
})
some:有一些,理论上完全等效于||,必须全部不满足才为false,有一个满足就为true
语法和用法同上,把every换成some即可
2.遍历:
forEach:直接修改原数组
arr.forEach(function(val,i,arr){
操作
})
map:不修改原数组,需要用东西去保存
var newArr=arr.map(function(val,i,arr){
return 操作
})
3.过滤和汇总:
filter:过滤,根据条件筛选出需要的部分,用新数组接住
var subArr=arr.filter(function(cal,i,arr){
return 过滤条件
})
reduce:汇总,把元素汇总到一起
arr.reduce(function(prve,val,i,arr){
return prve+val
},这里可以放一个基础值)
以上6个API,都是简化了for循环,而且回调函数在ES6可以简化为箭头函数,不过前提是数组
三.根据父对象设置子对象
Object.create()
var 要创建的子对象=Object.create(父对象{
"属性名":{四大特性}
...
})
四.严格模式
开启:在任意作用域的顶部加上一句"use strict"
功能:1.禁止了给未声明的变量赋值-解决了全局污染
2.静默失败会升级为报错-一旦报错后面的代码并不执行
五.call、apply、bind:不是自己的方法也可以用
call/apply【临时】替换了函数中的this--相当于借用
语法:函数名.call(借用的对象,实参,...)-单独传入每一个实参
函数名.apply(借用的对象,arr)-只能传入一个数组实参
强调:这两个相当于立刻调用函数
bind【永久】替换了函数中的this
做了3件事:
1.创建了一个跟原函数功能完全相同的新函数
2.将新函数中的this永久绑定成了使用bind的这个函数
3.还可以将新函数中的部分参数永久绑定
用法:var 新函数=原函数.bind(需要用的对象,永久的实参,...) -这个新函数需要自己对他进行调用
强调:这样bind出来的函数没办法再被call/apply走
固定套路:
1.Math.max/min.apply(Math,arr);
2.Object.prototype.toString.call/apply(x);
3.类数组转为普通数组:
var 普通数组名=Array.prototype.slice.call/apply(类数组对象)
var 普通数组名=Array.from(类数组对象)
二.ES6
一.模板字符串:可以在字符串中放入变量-不需要再做字符串拼接
`我的名字叫${变量名}`
二.let 关键字:创建变量的,以后优先使用let而不是var
let 变量名=值
作用:
1.他会禁止声明提前
2.添加了块级作用域-在使用let的{}就是一个块
3.它会自动记录当前触发事件的元素的下标
三.箭头函数:简化一切回调函数
口诀:function删掉,在()和{}中间添加=>,形参如果只有一个省略(),{}里只有一句话省略{},
如果只有一句话,而且是return,return也省略
四.for of循环
for(var v of arr){
v;
}
缺点:1.没有下标,无法修改原数组
2.不能便利hash数组和对象
第二天
一.DOM
一.什么是DOM:Document Object Model(文档对象模型):
它将页面上每一个标签、元素、属性、文本、注释,都看作一个DOM节点/元素/对象
(提供了一些操作元素的属性和方法)
HTML/XHTML/DHTML/XML分别是什么
HTML:网页
XHTML:更严格的网页
DHTML:动态的网页
它是整合现有技术的统称 DHTML=HTML+CSS+JS(dom)
XML:数据格式
DOM:原本可以操作一切结构化文档的HTML和XML,后来被细分成了三部分
1.核心DOM:【非常强】,即可以操作HTML,又可以操作XML
缺点:API比较繁琐
2.HTML DOM:只能操作HTML,API非常简单
缺点:比如属性部分,只能访问/设置标准属性,不能操作自定义属性
3.XML DOM:只能操作XML,XML已经淘汰了,现在都流行JSON
优先使用HTML DOM,它解决不了再用核心DOM
二.DOM树:
树根:document-不需要我们创建
可以通过树根找到每一个DOM元素/节点/对象
三.DOM元素三大属性:
1.xx.nodeType-描述了节点的类型
document节点:9
element节点:1
attribute节点:2
text节点:3
2.xx.nodeValue-获取元素的属性值的
因为以前没有getAtrribute,只有getAttributeNode
3.xx.nodeName-节点的名称-判断xx是什么标签
但是注意,它得到的结果是一个全大写的标签名
二.找元素/节点&找数据
一.通过关系找元素:
父:xx.parentNode
子:xx.children
第一个儿子:xx.firstElementChild
最后一个儿子:xx.lastElementChild
前一个兄弟:xx.previousElementSibling
后一个兄弟:xx.nextElementSibling
二.递归:
简单来说就是在函数中又一次调用了函数自己,但是迟早会停下来
何时使用:用于遍历【层级不明确】的情况,既可以遍历不明确的DOM,又可以遍历不明确的数据
如何使用:
function 函数名(root){
1.第一层你需要做的操作
2.等你第一层的操作做完了,判断有没有下一级,有就再次调用,记得实参也要变化
}
函数名(实际的根)
算法:深度优先!先遍历当前节点的子节点,子节点的子节点这样,遍历完毕再到兄弟节点
缺点:同时开启大量的函数调用,只有【层级不明确】才会使用
递归 vs 纯循环
递归:优点:直观易用
缺点:性能低下
纯循环:优点:性能高,几乎不占用内存
缺点:难得批爆
三.遍历层级不明确的API:
语法:1、创建tw对象
var tw=document.createTreeWalker(根元素,NodeFilter.SHOW_ELEMENT)
2、反复调用tw的nextNode()函数找到每一个元素
while((node=tw.nextNode())!=null){
node要干什么操作
}
缺点:1、必然跳过根元素,不会对根元素做操作
2、不可以遍历层级不明确的数据,仅能遍历层级不明确的DOM元素
四.通过API直接找元素:
1.通过HTML的一些特点去找元素:
1)id:var elem=document.getElementById("id值")
2)标签名和class名和Name名:let elems=document/parent.getElementsByTagName/ClassName/Name("标签名/class名")
name这个属性,input必写,那我们以后input就可以不class了
2. 通过css选择器获取元素:
1)单个元素 let elem=document.querySelector("任意css选择器")
强调:找到多个值返回第一个
没找到返回null
2)多个元素 let elem=document.querySelectorAll("任意css选择器")
强调:找到了返回集合
没找到返回空集合
getxxxx和queryxxxx的不同:
1.getxxxx返回的是动态集合
2.queryxxxx返回的是静态集合
动态集合会根据DOM树的改变悄悄的一起变化,每次修改DOM树都会悄悄查找一次
缺点是性能低却不能使用forEach
静态集合不会随着DOM树的改变而变化
优点是复杂查找时简单性能高,而且可以使用forEach
第三天
一.操作元素
一.元素的内容:
1、*elem.innerHTML:获取或设置开始标签到结束标签之间的HTML代码,可以识别标签
获取:elem.innerHTML
设置:elem.innerHTML="新内容"
2、elem.textContent:获取或设置开始标签到结束标签之间的纯文本,具有兼容性问题,不能识别标签
获取:elem.textContent
设置:elem.textContent="新文本"
老IE:elem.innerText - 第一次碰到小三上位,
原本这个只有老IE可用,但随着各个浏览器的升级发展也支持了,
老IE没有将就大家 ,反而大家在将就老IE
3、*input.value:获取或设置input的值
获取:input.value
设置:input.value="新值"
二.元素的属性:
1.获取属性值:
核心DOM:elem.getAttribute("属性名")
HTML DOM:elem.属性名
2.设置属性值
核心DOM:elem.setAttribute("属性名","属性值")
HTML DOM:elem.属性名="新值"
3.删除属性值:
核心DOM:elem.removeAttribute("属性名")
HTML DOM:elem.属性名=""
4.判断有没有:、
核心DOM:elem.hasAttribute("属性名")
HTML DOM:elem.属性名!=""
强调:HTML DOM确实简单很多,但是需要注意:
1)class必须写成className
3)只能操作标准属性,不能操作自定义属性
3)删除属性把它设置为空有些仍然能生效,没删除干净
三.元素的样式:
1.内联样式:优先级最高,一定会覆盖其他的样式
仅仅当前元素可用,不会牵一发动全身
获取:elem.style.css属性名
设置:elem.style.css属性名="css属性值"
唯一的小缺陷:获取样式时,只能获取到内联的样式 - 忍一忍就过了
2.样式表:
//1、获取你想要操作的样式表
var sheet=document.styleSheets[i]
//2、获取所有的样式规则
var rules=sheet.cssRules
//3、所有的规则中挑选出你需要操作的规则
var rule=rules[i]
//4、做获取 或 设置
console.log(rule.style.width)
rule.style.width="100px"
四.创建元素并且渲染DOM树:
1.创建空元素:
let elem=document.createElement("标签名")
2.为这个元素设置必要的属性和事件:
elem.属性名="";
elem.on事件名=function(){操作}
3.将这个元素渲染到树上:
父元素.appendChild(elem)
父元素.insertBefore(elem,已有子元素)
父元素.replaceChild(elem,已有子元素) - 将elem追加到父元素里面,并且替换已有子元素
五.删除元素:elem.remove()
六.HTML DOM提供了一些常用对象:并对这些对象进行了简化,但不是人人都可以简化
1.image对象:图片对象,仅仅简化了创建
let img=new Image()
2.form对象:简化了查找
查找form元素:var forms=document.forms
查找当前这个form元素下面的input:var inps=forms[1].elements
专属事件:
form.onsubmit=function(){//提交事件,只会在提交的一瞬间触发,防止用户输错还能提交
return false
}
3.select对象:
属性:1)select.options
2)select.selectedIndex
方法:select.add(option)
专属事件:select.onchange=function()
4.option对象:
let opt=new Option("innerHTML","value")
以上两个组合:非常方便的创建
select.add(new Option("innerHTML","value"))
第三天
BOM
一.BOM:Browser Object Model(浏览器对象模型)
二.window对象:扮演者两个角色
1.在前端:他代替了全局对象global,保存着全局变量和全局函数
window.变量名
window.函数名()
不过window可以省略不写
2.指当前窗口本身
一.网页打开新链接的方式
1)替换当前页面,可以后退
HTML:<a/ href="url">内容</a>
JS:open("url","_self")
2)在新窗口打开,可以打开多个
HTML:<a/ href="url" target="_blank">内容</a>
JS:open("url","_blank")
3)在新窗口打开,只能打开一个:使用场景:打开结账页面时
HTML:<a/ href="url" target="自定义name">内容</a>
窗口的底层其实是有名字的,如果重新打开相同的名字,新打开的窗口会替换掉旧的窗口
JS:open("url","自定义name")
4)替换当前页面,禁止后退:使用场景:结账后不允许后退
history对象:保存着当前窗口打开过的历史记录url,只有产生了窗口历史才能前进后退
location对象:保存着当前窗口正在打开的url
JS:location.replace("url")
替换网址后页面肯定变化,但是替换并不叫跳转,不会产生任何的历史纪录
扩展:a标签的其他用处:
1、跳转
2、锚点
3、下载:<a href="xx.exe/zip/rar">下载</a>
4、打开:<a href="xx.txt/jpg...">图片/文本</a>
5、直接执行js操作:<a href="javascript:js代码;">图片/文本</a>
二.window窗口的属性和方法:
属性:
获取大小:
1.浏览器的完整大小:outerWidth/Height
2.获取浏览器文档显示区域的大小:innerWidth/Height
3.获取完整屏幕的大小:screen.width/height
方法:
1.打开新窗口
let newW=open("url","自定义name","width=?,height=?,left=?,top=?")
//第三个形参没有新窗口就跟原浏览器融为一体
//第三个形参如果传入,新窗口就会脱离成为一个独立窗口
//第三个形参的数据没有单位
2.关闭新老窗口:window/newW.close()
//以下两个操作:仅仅只能对脱离浏览器的新窗口可用
3.移动新窗口:newW.moveTo(x,y)
4.改变新窗口的大小:newW.resizeTo(new宽,new高)
5.定时器:
何时使用:只要过一段时间就希望执行的特效或操作,必须使用定时器
如何使用:
1、周期性:只要不停止会等待时间,反复不断的执行
开启:timer=setInterval(callback,间隔毫秒数)
停止:clearInterval(timer)
2、一次性:等待时间后只会执行一次,就结束
开启:timer=setTimeout(callback,间隔毫秒数)
停止:clearTimeout(timer)