javascript 笔记
以下是这些网站接单的渠道:
码市:https://codemart.com/
英选 :https://www.yingxuan.io/
猪八戒 https://zbj.com
解放号:https://www.jfh.com/
猿急送:https://www.yuanjisong.com/
开源众包 :https://zb.oschina.net/projects/list.html
外包大师:http://www.waibaodashi.com/
程序员客栈:https://www.proginn.com/
语义化标签
nav
headerm
footer
section
article
aside
命名规则
1.变量名必须以英文字母、_、$开头
2.变量名可以包括英文字母、_、$、数字
3.不可以用系统的关键字、保留字作为变量名
基本语法
值类型—-数据类型
不可改变的原始值(栈数据)
Number,String,Boolean,undefined,null
引用值(堆数据)
array,object,function
类型转换
1.显示类型转换
Number(mix)
parseInt(string,radix)
parseFloat(string)
toString(radix)
String(mix)
Boolean()
预编译
1.创建AO对象
2.找形参和变量声明,将变量和形参名作为AO属性名,值为undefined
3.将实参值和形参统一
4.在函数体里面找函数声明,值赋予函数体
什么是可替换元素?—显示内容取决于元素属性
非可替换元素?—显示内容取决于元素内容
行盒内边距,边框,外边距特点:水平方向有效,垂直方向不会实际占据空间
通过构造函数创建新对象时,new操作符具体做了什么?
①创建一个新对象
②将将构造函数的作用域赋给新对象(因此this指向了这个新对象)
③执行构造函数中的代码(为这个新对象添加属性)
④返回新对象
原型和原型链
<script>
Grandpa.prototype.lastname = “grandpa”;
function Grandpa(){
this.name = “grandpa”;
}
var grandpa = new Grandpa();
Father.prototype = grandpa;
function Father(){
this.age = 50;
}
var father = new Father();
Son.prototype = father;
function Son(){};
var son = new Son();
</script>
constructor是一个对象的属性,这个属性存在在此对象的prototype中, 指向此对象的构造函数,
语法:被构造的对象名点constructor
Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__.
call和apply改变this指向,任何方法都可以点call,call和apply是方法里的
<script>
function ab(){
this.name = 'sdf';
console.log(name)
}
var b = {}
ab.call(b) //调用ab()函数,.call改变ab()函数的this指向为b对象,查看b对象
</script>
call和apply的区别,传参列表不同
justify-content,align-items,flex-direction
对象方法的重写,person.toString()原来的值是多少,改写后的值是多少
<script>
Person.prototype = {
toString : function (){
return 'hehe';
}
}
function Person(){
}
var person = new Person()
</script>
有趣的this
<script>
function ab(){
this.name = 'sdf';
var name = "aaa";
this.age = 18;
console.log(this.name)
console.log(name)
}
</script>
继承模式有多少种,各有什么缺点?
1.传统模式,原型链 缺点:过多的继承了没用的属性
<script>
Grandpa.prototype.lastname = “grandpa”;
function Grandpa(){
this.name = "yeye";
}
var grandpa = new Grandpa();
Father.prototype = grandpa;
function Father(){
this.age = 50;
}
var father = new Father();
Son.prototype = father;
function Son(){};
var son = new Son();
</script>
2.借用构造函数,这其实算不上继承,是利用别的函数完成自己的属性建立
缺点:不能继承借用构造函数的原型,每次构造函数都要多走一个函数
function Person(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
}
function Student(name,age,sex,grade){
Person.call(this,name,age,sex)
this.grade = grade
}
var student = new Student("张三",18,"男","三年级");
console.log(student)
3.共享原型,缺点:不能改动自己的原型
Father.prototype.lastName = "Deng"
function Father(){
}
function Son(){
}
Son.prototype = Father.prototype
var son = new Son();
console.log(son.lastName)
4圣杯模式(new一个新对象中转一下)
function inherit(Target,Origin){
function F(){};
F.prototype = Origin.prototype; //这段代码运行,原型的constuctor会被覆盖
Target.prototype = new F(); //跟着Target的原型里面的constuctor也被覆盖
Target.prototype.constuctor = Target; //还原constuctor
Target.prototype.uber = Origin.prototype; //知道继承谁的
}
Father.prototype.lastName = "Deng";
function Father(){
}
function Son(){
}
inherit(Son,Father);
var father = new Father();
var son = new Son();
console.log(father.lastName);
console.log(son.lastName);
CSS属性中的width:auto;或不设跟width:100%;的区别
width: auto或不设置宽度
* 子元素(包括content+padding+border+margin)撑满整个父元素的content区域。
* 子元素有margin、border、padding时,会减去子元素content区域相对应的width值
* 父元素的content = 子元素(content + padding + border + margin )
width: 100%
* 强制将子元素的content区域 撑满 父元素的content区域
* 子元素有margin、border、padding时,不改变子元素content区域的width,而是溢出父盒子,保持原有值
* 父元素的content = 子元素的content
flex布局
flex -container(flex盒子),flex-items(flex盒子里边的盒子),主轴main,主轴开始main-start,主轴结束main-end,交叉轴cross axis,
交叉轴开始cross-start,交叉轴结束cross-start,主轴的大小main size,交叉轴的大小cross size
应用在flex container上的css属性
flex-flow:缩写属性-》flex-direction 和 flex- wrap
flex-direction:决定主轴的方向
flex items默认都是沿着main axis(主轴)从main start开始往main end方向排布
值:row主轴从左到右
:row-revers主轴从右到左
: column主轴从上到下,改成列
:column-revers主轴从下到上
flex-wrap:决定flex-items是一行显示,还是多行显示,默认值是一样显示,
值:nowrap:默认,单行
:wrap:多行
:wrap-reverse:多行(对比wrap,cross start 与cross end 相反)
justify-content:决定flex-items在主轴的对齐方式
值:flex-start(默认值):与main start对齐
:flex-end:与main end对齐
:center:居中对齐
:space-between:
flex items之间的距离相等,
与main start、main end两端对齐
:space-evenly:
flex items之间的距离相等,
flex items与main start、main end之间的距离等于flex items之间的距离
:space-around:
flex items之间的距离相等,
flex items与main start、main end之间的距离是flex items之间距离的一半
align-items:决定了flex items在cross axis上的对齐方式
值:normal:在弹性布局中,效果和stretch一样
:stretch:档flex items在cross axis方向的size为auto时,会自动拉伸填充至flex container
:flex-start:与cross start对齐
:flex-end:与cross end对齐
:center:居中对齐
:baseline:与基准线对齐
align-content:决定多行的flex-tiems在交叉轴上的对齐方式,用法与justify-content类似
值:stretch(默认值):与align-items的stretch类似
:flex- start:与cross start对齐
: flex-end:与cross end 对齐
:center:居中对齐
:space-between:
flex items之间的距离相等,
与main start、main end两端对齐
:space-evenly:
flex items之间的距离相等,
flex items与main start、main end之间的距离等于flex items之间的距离
:space-around:
flex items之间的距离相等,
flex items与main start、main end之间的距离是flex items之间距离的一半
应用在flex items上的css属性
flex:是flex-grow 和 flex-shrink和flex-basisi的简写,flex属性可以指定1个,2个或3个值。
单值语法;值必须为以下其中之一:
一个无单位数number,它会被当作flex-grow的值
一个有效的宽度width值,他会被当做flex-basis的值、
关键字none,auto或initial
双值语法:第一个值必须为一个无单位数,并且它会被当作flex-grow的值
第二个值必须为以下之一
一个无单位数:它会被当作flex-shrink的值
一个有效的宽度值:它会被当作flex-basis的值
三值语法
第一个值必须为以个无单位数,flex-grow的值
第二个值必须为一个无单位数,flex-shrink的值
第三个值必须为一个有效的宽度值,并且它会被当作flex-basis的值
flex-grow:决定了flex items如何扩展
可以设置任意非负数字(正小数、正整数、0),默认值是0
当flex container 在main axis方向上有剩余size时,flex-grow属性才会有效
如果所有flex items的flex-grow总和sum超过1,每个flex item扩展的size为
flex container的剩余 size*flex-grow /sum,
flex items扩展后的最终size 不能超过max-width\max-height
flex-basis:用来设置flex items在main axis方向上的base size
值:auto(默认值)、具体的宽度数值(100px)
决定flex items最终base size的因素,从优先级高到低
max-width\max-height\min-width-min-height
flex-basis
width\height
内容本身的size
flex-shrink:决定了flex items如何收缩
可以设置任意非负数字(正小数、正整数、0)默认值是1
当flex items在main axis 方向上超过了 flex container 的size ,flex-shrink 属性才会有效
如果所有flex items的flex-shrink总和超过1,每个flex item收缩的size为
flex items超出 flexcontainer的size*收缩比例/所有flex items的收缩比例之和
order:决定了flex items的排布顺序
值:可以设置任意整数(正整数、负整数、0),值越小就越排在前面
默认值是0
align-self:flex items可以通过align-self覆盖flex container 设置的align-items
auto(默认值):遵从flex container的align-items设置
stretch、flex-start、flex-end、center、baseline,效果根align-items 一致
for in :语法for(var key in 对象名){}
hasOwnProperty:语法:对象名.hasOwnProperty(“属性名”)
in :语法:“属性名”in 对象名 也是看这个属性是不是这个对象的,返回truee,flase
instanceof :语法 A instanceof B ,官方解释A对象是不是B构造函数构造出来的
实际上是看A对象的原型链上 有没有 B的原型
命名空间,老办法是怎么解决的,新办法又是怎么解决的
对象属性的访问方法有多少种,有什么区别
写个大小媳妇呼唤对应的程序
怎么样遍历对象的每个属性,并知道每个属性的名字,又想知道属性的值呢,怎么判断属性
是自己的,还是原型呢?
var deng = {
wife1:"xiaozhang",
wife2:"xiaoliu",
wife3:"xiaowang",
wife4:"xiaokai",
__proto__:{
lastname:"deng"
}
}
function saywife(obj){ //定义一个函数,参数是对象,
for(var key in obj){ //循环遍历这个对象的属性,属性名以字符串的形式存在key变量中
if(obj.hasOwnProperty(key)){ //指示一个对象自身(不包括原型链)是否具有指定名称的属性
console.log(key + " " + obj[key] );
}
}
} //如果要求只输出原型链中的属性,怎么办?
如何判断一个对象能不能调用属性
用in来判断,因为它包含原型链,语法:“字符串属性名” in obj
instanceof 可以判断一个对象是不是这个函数构造出来的,但最终判断的本质又是什么?
如何判断一个变量里存的是数组,还是对象,有几种方法?
1.用constuctor,语法:对象名.constuctor
2.[] instanceof Array //true
var obj = {};
obj instanceof Array //false
3.Object.prototype.toString.call([]);
对象名.hasOwnProperty (“属性名”), 什么意思?
对象名 instanceof 函数名 ,什么意思?
“属性名” in 对象名, 什么意思?
什么是this ,是指针,是范围?
1.函数预编译过程 this —->window
2.全局作用域里 this —>window
3.call/apply 可以改变函数运行时this指向
4.obj.func();func()里面的this指向obj,谁调用的这个方法,这个方法里面的this 就指向谁
arguments.calle,指向函数自身引用,递归里有用
var mum = (function (n){
if (n == 1){
return 1;
}
return n * arguments.callee(n - 1);
}(6))
console.log(mum)
克隆
var obj = {
name:"abc",
age:123,
sex:'female',
card:['visa','master'],
bather:{
name:"dda"
},
wife:{
name:"bcd",
son:{
name:"aaa"
}
}
}
var obj1 = {
}
function copy(or,ta){
var str = Object.prototype.toString,
ta = ta || {};
for(var key in or){
if(or.hasOwnProperty(key)){
if(typeof(or[key])=="object"){
if(str.call(or[key]) == "[object Array]" ){
ta[key] = [];
console.log("a");
}else{
ta[key] = {};
console.log("b");
}
copy(or[key],ta[key]);
}else{
ta[key] = or[key];
}
}
}
}
copy(obj,obj1);
显示类型转换
Number(x):转换成数字类型的
parseInt(x,8):以8进制为基底,吧x转换成10进制
parseFloat(x):把x转换成浮点型数字
toFixed(x):保留x位小数,并且四舍五入
String(x):把x转换成字符类型
Boolean(x):把x转换成布尔类型
x.toString():把x转换成字符串,undefined,和nall不能用
任何数据加空串都可以转换成字符串
隐式类型转换
js进行的三部曲
1.语法分析
2.预编译
3.解释执行
下面有6种值转换布尔值false
undefined
nall
flase
“”
NaN
0
var obj1 = Object.create(原型):意思是
Math.floor()取整
Math.random():0到1的开间数
typeof 共返回6种数据格式:
1.object
2.undefined
3.string
4.number
5.boolean
6.function
arguments.callee指向函数自身引用
表格标签table主要用于呈现格式化数据。
表格属性
border:设置表格边框
width:设置表格宽度
align:设置表格对齐
cellpadding:设置单元格间距
cellspacing:设置像素间隙
结构伪类
li:first-child:第一个
li:last-child最后一个
li:nth-child(n)第n个
li:nth-child(2n)2的倍数
li:nth-child(2n+1)2偶数
li:nth-child(even)偶数
li:nth_child(odd)奇数
伪类是选择器,伪元素是标签(两个冒号)
box-sizing指定盒模型,即可指定为content-box(默认),border-box(css3盒模型)
数组的常用的方法
改变原数组
push(数据):把数据添加到最后
unshift(数据):把数据添加到数组的最前面
shift():删除数组最前面的一位
pop():剪切数组最后一位,可以拿个变量接收一下
splice(从第几位开始,截取多少的长度,在切口处添加新的数据)
reverse():颠倒数组排序
sort()给数组排序,默认按ask码升序,sotr().reverse()降序
sort(自定义规则)
sort(function(a,b){
if(a > b){ //简写 return a - b ;升序, return b - a;降序
return 1;
}else {
return -1;
}
})
①给数组排序②给一个有序的数组乱序Math.random()③给三个对象人,按年龄排序
④给数组里的字符,按字符串长度排序⑤给数组里的字符,按字符的字节长度排序(
封装个方法,计算单个字符组的字节总长charCodeAt())
不改变原数组
concat:连接两个数组并返回
toString:把数组转换成字符串返回
slice(从该位开始截取,截取到该位)并返回
join():以参数字符为连接,连接数组并以字符串的形式返回
split():以参数拆分成数组
错误信息处理
try{
}catch(e){
alert(e.name + “:” + e.message);
} // 在try里面发生错误,不会执行错误后的try里面的代码,在外面的代码会继续执行
Error.name的六种对应的信息:
1.EvalError:eval()的使用与定义不一致
2.RangeError:数值越界
3.ReferenceError:非法或不能识别的引用数值
4.SyntaxError:发生语法解析错误
5.TypeError:操作数类型错误
6.URIError:URI处理使用不当
es5严格模式
“use strict”
不再兼容es3的一些不规则语法。使用全新的es5规范。
两种用法:
全局严格模式
局部函数内严格模式(推荐)
就是一行字符串,不会对不兼容严格模式的浏览器产生影响
不支持with,arguments.calle,func.caller,变量赋值前必须声明,局部
this必须被赋值(person.call(null/undefined))赋值什么就是什么),拒绝
重复属性和参数
document.getElementById(‘id’) :通过id选择元素
document.getElementsByTagName(‘标签’):通过标签选择元素,放到类数组里边去
document.getElementsByName(‘name’):通过name属性选择元素,放到类数组里边去
document.getElementsByClassName(‘className’):通过className选择元素,放到类数组里边去
document.querySelector(‘css的选择语法’):选出来的是单个,不是实时的
document.querySelectorAll(‘css的选择语法’):选出来的是一组,放到类数组里边去,不是实时的
遍历节点树:
parentNode ->父节点
childNodes ->子节点们
firstChild ->第一个子节点
lastChild ->最后一个子节点
nextSibling ->后一个兄弟节点
previousSibling ->前一个兄弟节点
.hasChildNodes():看有没有子节点,有返回true,没有返回flase
遍历元素节点树
parentElement ->返回当前元素的父元素节点
children ->返回当前元素所有的子元素节点
childElementCount === children.length ->返回当前元素的子元素节点的个数
firstElementChild ->返回当前元素的第一个子元素节点
lastElementChild ->返回当前元素的最后一个子元素节点
nextElementSibling / previousElementSibling ->返回后一个/前一个兄弟元素节点
节点的四个属性
nodeName ->元素的标签名,以大写形式表示,只读
nodeValue ->text节点或comment节点的文本内容,可读写
nodeType ->该节点的类型,只读
attributes ->节点的属性集合
节点的一个方法 Node.hasChildNodes()判断是否有子节点;
节点的类型
元素节点 —- 1
属性节点 —- 2
文本节点 —- 3
注释节点 —- 8
document — 9
DocumentFragment —- 11
区分数组对象的3种方法
①看它的构造函数constructor
②deng instanceof Array
③Object.prototype.toString.call([]):看返回值
arguments.callee:指向函数本身引用
类数组,属性要为索引(数字)属性,必须有length属性,最好加上push
let obj = {
"0" : "a",
"1" : "b",
"2" : "c",
"length" : 3,
"push" : Array.prototype.push,
"splice" : Array.prototype.splice //这句一加就策底成数组了
}
是怎么往里边push东西的
Array.prototype.push = function (target ){
this[this.length] = target;
this.length ++;
}
写一个mytype,提示,1.分两类 原始值 引用值 2.区分引用值
写一个数组去重复的方法,思路,新建一个空对象和空数组,循环遍历数组
如果对象属性没有值(!obj[this[i]])就将数组的值作为对象的属性名然后随便
给个字符串值,然后将遍历的数组值this[i],push到新数组里边去,最后返回
新数组
字符串去重
str = "aaaabbbcccddddddfeeefadxx"
String.prototype.repeat = function(){
let obj = {},
arr = [];
for(i = 0;i <= this.length;i++){
if(!obj[this.charAt(i)]){ //undefinde取反
obj[this.charAt(i)] = "abc";
arr.push(this.charAt(i));
}
}
return arr.join("")
}
console.log(str.repeat())
1、求子元素节点 2、封装函数,返回元素e的第n层祖先元素
3、封装函数,返回同级元素节点,正数是后,负数是前
DOM基本操作
增
document.createElement();增加或创建一个元素节点
document.createTextNode();创建文本节点
document.createComment();创建注释节点
document.createDocumentFragment();创建文档碎片
插
.appendChild():列子,把i标签剪切出来,插入选出来的p标签里边去
let p = document.getElementsByTagName("p")[0];
let i = document.getElementsByTagName("i")[0];
p.appendChild(i);
.insertBefore(i,p):父元素调用,把i元素插到p元素之前
删
.removeChild(i):父元素调用,把目前剪切掉了,
.remove():自身调用,删除自身
替换
.replaceChild(new,origin)父级调用,原来的被剪切出来了
Element节点的一些属性
innerHTML:取出或修改元素里边的html内容
div.innerHTML:取出
div.inerHTML = “123”:修改
.innerText:取出或修改元素里边的文本内容
.textContent:和innerText一样
Element节点的一些方法
.setAttribute('class','demo’):给元素设置行间属性,属性名,属性值
.getAttribute(‘class’):取出行间属性的值
js定时器
setlnterval();定时循环器
setTimeout();推迟一段时间,执行
clearInterval();
clearTimeout();
全局对象window上的方法,内部函数this指向window
DOM基本操作
查看滚动条的滚动距离
window.pageXOffset/pageYOffset
IE8和IE8以下的浏览器,以下两个有一个好使,另一个就是0
document.body.scrollLeft/scrollTop
document.documentElement.scrollLeft/scrollTop
<script>
function getScrollOffset() {
//求滚动条距离
if (window.pageXOffset) {
return {
x: window.pageXOffset,
y: window.pageYOffset,
};
} else {
return {
x: document.body.scrollLeft + document.documentElement.scrollLeft,
y: document.body.scrollTop + document.documentElement.scrollTop,
};
}
}
</script>
查看视口的尺寸
window.innerWidth/innerHeight
IE8及IE8以下不兼容
document.documentElement.clientWidth/clientHeight
标准模式下,任意浏览器都兼容
document.body.clientWidth/clientHeight
适用于怪异模式下的浏览器
如何判定现在是标准模式还是怪异模式:
方法一:执行以下代码
alert(window.top.document.compatMode) ;
//BackCompat 表示怪异模式
//CSS1Compat 表示标准模式
方法二:jquery为我们提供的方法,如下:
alert($.boxModel)
alert($.support.boxModel)
封装兼容性方法,返回浏览器视口尺寸getViweportOffset()
<script>
function getViweportOffset() { //求浏览器视口大小
if (window.innerWidth) {
return {
w: window.innerWidth,
h: window.innerHeight,
};
} else {
if (document.compatMode == "BackCompat") {
return {
w: document.body.clientWidth,
h: document.body.clientHeight,
};
} else {
return {
w: document.documentElement.clientWidth,
h: document.documentElement.clientHeight,
};
}
}
}
</script>
查看元素的几何尺寸
domEle.getBoundingClientRect();
兼容性很好
该方法返回一个对象,对象里面有left,top,right,bottom等属性
。left和top代表该元素左上角的X和Y坐标,right和bottom代表元素右
下角的X和Y坐标
height和width属性老版本IE并未实现
返回的结果并不是“实时的”
查看元素的尺寸(包含border和padding)
dom.offsetWidth, dom.offsetHeight
查看元素的位置
dom.offsetLeft, dom.offsetTop
对于无定位父级的元素,返回相对文档的坐标。对于有定位父级的
元素,返回相对于最近的有定位的父级的坐标。
dom.offsetParent
返回最近的有定位的父级,如无,返回body,body.offsetParent返回null
eg:求元素相对于文档的坐标getElementPosition
<script>
let son = document.getElementsByClassName('son')[0];
function getElementPosition(div){
function boxLeft(div){
if(div.offsetParent == null){
return 0;
}else{
return div.offsetLeft + boxLeft(div.offsetParent) + parseInt(getComputedStyle(div.offsetParent,null).borderLeft);
}
}
function boxTop(div){
if(div.offsetParent == null){
return 0;
}else{
return div.offsetTop + boxTop(div.offsetParent) + parseInt(getComputedStyle(div.offsetParent,null).borderTop);
}
}
return {
left : boxLeft(div) + "px",
top : boxTop(div) + "px"
}
}
</script>
让滚动条滚动
window上有三个方法
scroll(x,y),scrollTo(x,y) scrollBy(x,y);
三个方法功能类似,用法都是将x,y坐标传入。即实现让滚动轮
滚到当前位置。
区别:scrollBy()会在之前的数据基础之上做累加。
eg:利用scrollBy()快速阅读的功能
脚本化css
读写元素css属性
dom.style.prop (只能读写行间样式)
可读写行间样式,没有兼容性问题,碰到float这样
的保留字属性,前面应加css
eg:float —>cssFloat
复合属性必须拆解,组合单词变成小驼峰式写法
写入的值必须是字符串格式
查询计算样式
window.getComputedStyle(ele,null);
计算样式只读
返回的计算样式的值都是绝对值,没有相对单位
IE8及以下不兼容
ie8以下用obj.currentStyle.left
封装兼容性方法
function getStyle(obj,attr){
if(obj.currensStyle){
return obj.currentStyle[attr];
}else{
return getComputedStyle(obj,null)[attr];
}
}
如何绑定事件处理函数
1.ele.onclick = function(event){}
兼容性很好,但是一个元素的同一个事件上只能绑定一个处理函数
基本等同于写在HTML行间上
2.obj.addEventListener(type,fn,false)
IE9以下不兼容,可以为一个事件绑定多个处理程序
3.obj.attachEvent(‘on’ + type, fn);
IE独有,一个事件同样可以绑定多个处理程序
window.location.href = "http://www.baidu.com”; js跳转页面
事件处理程序的运行环境
1.ele.onclick = function(event){}
程序this指向是dom元素本身
2.obj.addEventListener(type,fn,false);
程序this指向是dom元素本身
3.obj.attachEvent(‘on’ + type ,fn); 办法:fn = function(){tese.call(obj)}
程序this指向window
封装兼容性的addEvent(elem,type,handle);方法
<script>
let div = document.getElementsByTagName('div')[0];
function addEvent(elem,type,handle){
if(elem.addEventListener){
elem.addEventListener(type,handle,false)
}else if(elem.attachEvent){
elem.attachEvent('on' + type,function(){
handle.call(elem);
})
}else{
elem['on' + type] = handle;
}
}
addEvent(div,'click',ab)
function ab(){
console.log('a');
}
</script>
解除事件处理程序
ele.onclick = false/‘’/null
ele.removeEventListener(type,fn,false);
ele.detachEvent(‘on’+type,fn);
注:若绑定匿名函数,则无法解除
事件处理模型 — 事件冒泡、捕获
事件冒泡:
结构上(非视觉上)嵌套关系的元素,会存在事件冒泡的功能,即同一事件,
自子元素冒泡向父元素。(自底向上)
事件捕获:
结构上(非视觉上)嵌套关系的元素,会存在事件捕获的功能,即同一事件,
自父元素捕获至子元素(事件源元素)。(自顶向下)
IE没有捕获事件
触发顺序,先捕获,后冒泡
focus,blur,change,submit,reset,select等事件不冒泡
取消冒泡和阻止默认事件
取消冒泡:
event:事件对象
W3C标准event.stopPropagation();但不支持ie9以下版本
IE独有event.cancelBubble = true;谷歌也支持
封装取消冒泡的函数stopBubble(event)
document.onclick = function stopBubble(e){
e.stopPropagation();
}
阻止默认事件:
默认事件—表单提交,a标签跳转,右键菜单等
1.return false;以对象属性的方式注册的事件才生效
2.event.preventDefault();W3C标注,IE9以下不兼容
3.event.returnValue = false;兼容IE
封装阻止默认事件的函数cancelHandler(event);
<a href="javascript:void(false)">http:baidu.com</a>:取消a标签默认事件
事件对象
event || window.event用于IE
事件源对象:
event.target 火狐只有这个
event.srcElement le只有这个
这辆chrome都有
兼容性写法
事件委托
利用事件冒泡,和事件源对象进行处理
优点:
1.性能不需要循环所有的元素一个个绑定事件
2.灵活当有新的子元素时不需要重新绑定事件
鼠标移动拖动方块
<div style="left:0;top:0;"></div>
<script>
let div = document.getElementsByTagName('div')[0];
let disX,disY;
div.onmousedown = function(e){
disX = e.pageX - parseInt(getComputedStyle(div,null).left);
disY = e.pageY - parseInt(getComputedStyle(div,null).top);
document.onmousemove = function (e){
div.style.left = e.pageX - disX + "px";
div.style.top = e.pageY - disY + "px";
}
document.onmouseup = function(){
document.onmousemove = null
}
}
</script>
鼠标移动拖动方块高端写法
<script>
let div = document.getElementsByTagName('div')[0];
function drag(div){
if(getComputedStyle(div,null).position != 'absolute'){
return "请设置绝对定位"
}
let disX,disY;
function move(e){
div.style.left = e.pageX - disX + "px";
div.style.top = e.pageY - disY + "px";
}
div.addEventListener("mousedown",function(e){
disX = e.pageX - parseInt(getComputedStyle(div,null).left);
disY = e.pageY - parseInt(getComputedStyle(div,null).top);
document.addEventListener('mousemove',move,false)
document.addEventListener('mouseup',function(){
document.removeEventListener('mousemove',move,false);
},false)
},false)
}
</script>
事件分类
click、mousedown、mousemove(移动)、mouseup、contextmenu(右键事件)、
mouseover(移入)、mouseout(移出)、mouseenter(移入)、mouseleave(移出)
用button来区分鼠标的按键,0/1/2
DOM3标准规定:click事件只能监听左键,只能通过
mousedown和mouseup来判断鼠标左右键
如何解决mousedown和click的冲突,按下计时,松开计时,时差低于300为click;
事件练习
拖拽应用
应用mousedown mousemove mouseup
随机移动的方块
mouseover
键盘事件
keydown keyup keypress
keydown > keypress > keyup
keydown和keypress的区别
keydown可以响应任意键盘按键,keypress只可以相应
字符类键盘按键
keypress返回ASCLL码,可以转换成相应字符
document.onkeypress = function (e){
console.log(String.fromCharCode(e.charCode));
}
文本操作事件
oninput:文本框每变化一次,就触发一次
onfocus:输入框得到焦点时,触发事件
onblur:输入框失去焦点时,触发事件
onchange:聚焦,失去焦点,内容发生改变就触发,
输入框提示和变化
<input type="text" value="请输入用户名" style="color:#999;">
<script>
let input = document.getElementsByTagName('input')[0];
input.onfocus = function (){
if(input.value == "请输入用户名"){
input.value = "";
}
input.style.color = "#424242";
}
input.onblur = function(){
if(input.value == ""){
input.value = "请输入用户名";
input.style.color = "#999";
}
}
</script>
窗体操作类(window上的事件)
onscroll load
小练习:fixed定位js兼容版
作业
1.完善轮播图,加按钮
2.提取密码框的密码
3,输入框功能完善
4.2级菜单栏
5.贪食蛇游戏
6.扫雷游戏
json
json是一种传输数据的格式(以对象为样板,本质上就是对象,但用途有区别
对象就是本地用的,json是用来传输的)
JSON.parse(); string —-> json
JSON.stringify(); json —-> string
异步加载js
js加载的缺点:加载工具方法没必要阻塞文档,过得js加载会影响页面效率,
一旦网速不好,那么整个网站将等待js加载而不进行后续渲染等工作。
有些工具方法需要按需加载,用到再加载,不用不加载
javascript 异步加载的三种方案
1.defer异步加载,但要等到dom文档全部解析完才会被执行。
只有IE能用,也可以将代码写到内部。
2.async异步加载,加载完就执行,async只能加载外部脚本
不能把js写在script标签里,新版浏览器都能使用
1.2执行时也不阻塞页面
3.创建script,插入到DOM中,加载完毕后callBack(回调函数)
var script = document.createElement('script');
script.type = "text/javascript";
script.src = "js.js"
document.head.appendChild(script)
script.onload = function(){ //由于是异步加载,所以得等加载完后,才能调用函数,IE没有
test();
}
IE的方法:script.redyState = “loading”未加载完/“complete”已加载完/“loaded”已加载完
script.onreadystatechange = function() { 加载状态事件,IE独有
if(script.readyState == “complete” || script.readyState == “loaded”){
test();
}
}
正则表达式
转义字符“\”
多行字符串
字符串换行符\n
RegExp
正则表达式的作用:匹配特殊字符或有特殊搭配原则的字符的最佳选择
正则表达式上有个方法reg.test()
字符串上的str.match()
两种创建方式
直接量
new RegExp()
个人推荐用直接量
var reg = /abc/;
var str = "abcd";
console.log(reg.test(str));
reg = /abc/i,加个属性i表示忽视大小写,g全局匹配,m多行匹配
str.match(reg)匹配规则里的字符
new的方式创建
var str = “abc”;
var reg = new RegExp(“abc”,”m”);
var reg1 = new RegExp(reg);
表达式:[]一个方括号,代表一位

浙公网安备 33010602011771号