Javascript

10 篇文章 0 订阅

Javascript
JS中有六种数据类型:
undefined null boolean number string object

typeof返回的六种数据类型:
object undefined string number boolean function

命名规则
大驼峰命名:但凡是单词,首字母都大写
小驼峰命名:首字母小写,之后的每个单词的首字母大写

立即执行函数的三种方式,函数名可有可无,可传参数
(function test(a){}(a));
(function test(a){})(a);
-function test(a){//可在函数前添加-,+,!,让其运行}();

JS模块化
index.js
import {hu} from ‘./hu.js’;

hu.js
export const hu = 123;

index.html

作用域
GO:全局预编译
AO:函数预编译

call和apply的区别
Person.call(this,name,age) = Person.apply(this,[name,age]);
call和apply的区别
call传的是一一对应的实参,apply传的是数组

属性拼接,在运行时
obj.name 会隐式转换成 obj[‘name’]
obj.name => obj[‘name’]

A instanceof B
看A对象的原型链上有没有B的原型

判断数组还是对象
instanceof
toString()
constructor()
constructor(),instanceof都能判断,但是的注意父子域的问题,toString()比较完美

this指向问题
在预编译过程,this->window
在没有创建对象时,也就是没有进行var p = new P()时,this->window
call/apply可以改变this的指向
谁调用指向谁,如obj.fun();fun()中的this指向obj

包装类
数字的两种方式
var num = new Number(123); //能有属性和方法
var num = 123; //原始值数字,不能有属性和方法

String()
Number()
Boolean()

var num = 4;
num.len = 3;//经过两个步骤,一,系统自动装换成new Number(4).len = 3;
二,然后自动删除第一步
console.log(num.len);//经过两个步骤,一,系统自动装换成new Number(4).len = 3;
* 二,然后自动删除第一步
注意:这里和上面的不是同一个东西

	var  str  = ‘abcd’ ;
	str.length  =  2 ;                //经过包装类的过程
	console.log(str);                 //abcd
	console.log(str.length);           //4   string上有length属性

循环对象
var obj = {
name:123;
sex:456;
age:789;
}
for( var prop in obj ){ //prop可以自定义
console.log(prop); //输出属性名
console.log(obj.prop ); //输出属性值
}

原型
Test.prototype.height = 20;//提取公共属性
Test.prototype.width = 50;
function Test(){}
var test = new Test();
1.不能通过对象去修改原型的属性的值和方法,如test.width = 5;只会给Test()添加属性,而并非给原型添加属性

2.想要修改原型上的属性和方法,只能重新赋值Test.prototype.width = 60;

3.删除原型上的属性delete Test.prototype.width, delete test.width只能删除Test()的属性

查看创造test对象的构造函数
test.constructor = function Test(){}

constructor可改
Test.prototype={
constructor:Person
}
function Person(){

}
function Test(){

}

var test = new Test();
test.constructor = function Person(){}

原型上的__proto__
function Test(){

}

var test = new Test();
当实例化一个对象时,会在函数体内发生一个过程
function Test(){
var this = {
proto:Test.prototype
}
}

改变原型上的__proto_
function Test(){}
var test = new Test();
var obj = {name:’obj’};
Test.proto = obj;
test.name= ‘obj’;

原型上的访问
Person.prototype.name = 123;
function Person(){}
var person = new Person();
Person.prototype.name =456;
person.name = 456; //值覆盖

Person.prototype.name = 123;
function Person(){
var this = { proto:Person.prototype}
}
var person = new Person();
Person.prototype ={
name:’456’
};
//Person.prototype和__proto__指向同一个房间,
//虽然Person.prototype更改了,但是__proto__并没有更改,它会先往__proto__寻找
person.name = 123;

Person.prototype.name = 123;
function Person(){
//var this = { proto:Person.prototype}
}
Person.prototype ={
name:’456’
};
var person = new Person();
//这里是在person还没有生成对象之前,便把原型给更改了
person.name = 456;

Person.prototype = {}
proto = Person.prototype

如果父级原型中有引用值,可通过后代修改
function Father(){
this.name = {
hu:123
}
}
var father = new Father();
function Son(){}
Son.prototype = father;
var son = new Son();
执行
son.name.hu = 456; //this引用
结果
father.name.hu = 456;

创建原型的两种方法
function Person(){}
var person = new Person() 等同于 var person = Object create( Person.prototype );

并非所有的对象都继承于Object.prototype,例如
var person = Object create( null );
person没有原型,也没有_proto_,也不可以手动往person里添加__proto__,系统不认

call
function Person(name,age){
this.name = name;
this.age = age;
}
var obj ={};
Person.call(obj,’huya’,18);//第一个参数是改变this的指向,之后的参数是传参
//输出obj ={ name:’huay’;age:18 }

function Person(name,age){
this.name = name;this.age = age;
}
function Test(name,age,sno,sn){ functionTest(name,age,sno,sn){
Person.call(this,name,age); 等同于 this.name = name; this.age = age;
this.sno = sno; this.sn = sn; this.sno = sno; this.sn = sn;
} }
var test = new Test();

继承
圣杯模式
function inherit(Son,Father){
function F(){}
F.prototype = Father.prototype;
Son.prototype = F.prototype;
Son.prototype.constuctor = Son;
}
function Son(){}
function Father(){}
inherit(Son,Father);
var son = new Son()
var father = new Father()

仿JQ无限调用方法
var deng = {
sno:function(){console.log(2017011122);return this;}
sn:function(){console.log(666);return this;}
sex:function(){console.log(‘男’);return this;}
}
deng.sno().sn().sex();

闭包实现私有化功能
var name = ‘bcd’ ;
var init = (function (){
var name = ‘abc’;
function callName(){
console.log(name);
}
return function (){
callName()
}
})();
init(); //输出为abc

函数预编译
在函数预编译过程中,变量声明和函数声明会被提前到当前作用域的最前面,值得注意的是,函数赋值并不会在函数预编译过程中被提前

优先级问题
当变量名和函数名相同时,函数优先与变量

闭包
function test(){
var num = 100;
function a(){
num++;
console.log(num);
}
// a执行时,作用域为 -->0:aAO
–>1:testAO
–>2:GO
function b(){
num–;
console.log(num);
}
return [a,b];
}
var MyArr = test();
MyArr0;
//a()执行时,会改变test()的AO
MyArr1;
//b()执行时,使用的AO是a()执行时,改变了的test()的AO

function a(){
function b(){
aa = 0;
}
var aa = 123;
b();
//b()执行时,会改变a()的AO,也就是改变aa的值为0;
console.log(aa); //0
}
a();

with(obj){},能够改变作用域链,obj为对象,函数体内优先使用obj的AO
var obj = {name:’obj’}
var name = ‘window’ ;
function test(){
var name = ‘scope’;
with(obj){
console.log(name);//obj,
}
}
test();
缺点:改变作用域链,效率丧失
arguments.callee函数引用,常用于立即执行函数
function test(){
console.log(arguments.callee); //输出 function test(){},arguments.callee()可传参
}

var a = (function (n) {
if(n == 1){
return 1;
}
return n*arguments.callee(n-1);
}(100));

Fun.caller
function test(){demo();}
function demo(){console.log(demo.caller)}
test(); //输出demo()在那被执行

try…catch…finally
Error.name的六种对应信息
EvalError:evel()的使用与定义不一致
RangeError:数值越界
ReferenceError:非法或不能识别的引用值
SyntaxError:发生语法解析错误
TypeError:操作类型出错
URIError:URI处理函数使用不当

try{
console.log(‘a’);
console.log(b); //一旦报错,便不会继续往下执行
console.log(‘c’);
}catch(e){
console.log(e.name + ‘:’ + e.message);
}
console.log(‘d’);

arguments[]
function test(a,b,c){
arguments[2] = 10;
console.log©; //10 arguments[2]<->c是相互映射,一个改变,另一个跟着改变
//c = 10;
//console.log(arguments[2]);//10
}
test(1,2,3);

数组方法
concat()
用于连接数组或字符串,使用方法,不会改变现有的数组
var a = [1,2,3];
a.concat(4,5) = [1, 2, 3, 4, 5];

split()
join()
把数组中所有通过指定分隔符进行分隔的元素放入一个字符串,不会改变现有的数组
var a = [1,2,3];
a.join() = “1,2,3”;
join(“可加连接符”),默认为逗号
var a = [1,2,3];
a.join(“hu”) = “1hu,2hu,3”;

shift()
用于把数组的第一个元素从其中删除,并返回第一个元素的值,会改变现有的数组
var a = [1,2,3];
a.shift() = [2,3];//return a[0];

unshift()
向数组的开头添加一个或更多元素,并返回新的长度,会改变现有的数组
var a = [1,2,3];
a.unshift(“4",”5”)= [4,5,1,2,3];//a.length;

pop()
用于删除数组中的最后一个元素并且返回原数组的最后一个元素,会改变现有的数组
var a = [1,2,3];
a.pop() = [1,2];//return a[length];

push()
向数组的末尾添加一个或多个元素,并返回新的长度,会改变现有的数组
var a = [1,2,3];
a.push( “4” , ”5” ) = [1,2,3,4,5]; //return a.length ;

reverse()
用于颠倒数组中元素的顺序,会改变现有的数组
var a = [1,2,3];
a.reverse() = [3,2,1];

slice(start,end)
从已有的数组中返回选定的元素,不会改变现有的数组
var a = [1,2,3];
a.slice(1) = [,2,3];//a.slice(a)是从a[a]开始取到a[“length”]

sort()
用于对数组的元素进行排序
var a = [1,2,3,1,2];
a.sort()=[1,1,2,2,3]
排序
var arr = [1,2,3,8,6,9,5,4,2,3];
arr.sort(function (a,b){
return b-a; //降序
// return a-b;升序
})

乱序
var arr = [1,2,3,4,5,6,7,8];
b = arr.sort(function (){
return Math.random()-0.5;//降序
// return a-b;升序
})

splice()
向/从数组中添加/删除项目,然后返回被删除的项目,会改变现有的数组
var arr = [1,2,3,4];
arr.splice(0,2,’5’)=[‘5’,3,4]; //删除arr[0],arr[1],并添加’5’
arr.splice(a); //删除从下标a开始和之后的所有元素
arr.splice(a,b) //删除从下标a开始到b-1之间所有的元素

数组末尾追加元素,改变原数组
var fruits = [“Banana”, “Orange”, “Apple”, “Mango”];
fruits[fruits.length] = “Kiwi”; //[“Banana”, “Orange”, “Apple”, “Mango”, “Kiwi”]

删除数组中的元素
var fruits = [“Banana”, “Orange”, “Apple”, “Mango”];
delete fruits[0]; // fruits = [empty, “Orange”, “Apple”, “Mango”] length不变

值类型
不可改变的原始值(栈数据)
Number,String,Boolean,undefined,null

引用值(堆数据)
array, object, function

字符串方法
toString()
把数组转换为字符串,并返回结果
var arr = [1,2,3,4,5];
arr.toString()=’1,2,3,4,5’;

charAt(x)
返回字符串中x位置的字符
var Mystring = ‘huyatv’;
string.charAt(5);//v

charCodeAt(x)
返回字符串中x位置处字符的unicode值
var Mystring = ‘huyatv’;
Mystring.charCodeAt(5) //118

A~Z 65~90
a~z 97~122
0~9 48~57

String.fromCharCode()
转换一组Unicode值转换为字符
String.fromCharCode(97,98,99,120,121,122) = abcxyz;

indexOf()
搜索并(如果找到)返回字符串中搜索到的字符或子字符串的索引。如果没有找到,则返 回-1。Start是一个可选参数,指定字符串中开始搜索的位置,默认值为0。
var sentence=“Hi, my name is Sam!”
if (sentence.indexOf(“Sam”)!=-1)
alert(“Sam is in there!”)

lastIndexOf()
方法返回指定文本在字符串中最后一次出现的索引, 如果未找到,则返回-1。 “Start” 是一个可选参数,指定字符串中开始搜索的位置, 默认值为string.length-1。
var myString = ‘javascript rox’;
console.log(myString.lastIndexOf(‘r’)); //11

includes()
用于检查字符串是否包含指定的字符串或字符
var mystring = “Hello, welcome to edureka”;
var n = mystring.includes(“edureka”); //true

trim()
从一个字符串的两端删除空白字符
var str = " Hello Edureka! ";
str.trim()=’Hello Edureka!’;

startWith()
检查字符串是否以指定的字符串或字符结束

endsWith()
检查字符串是否以指定的字符串或字符结束
var mystr = “List of javascript functions”;
var n = mystr.endsWith(“functions”); //true

toLowerCase()
方法用于把字符串转换为小写

toUpperCase()
方法用于把字符串转换为大写

substring()
用于提取字符串中介于两个指定下标之间的字符,方返回的子串包括 start 处的字符,但不包括 stop 处的字符,to 可选,如果省略该参数,那么返回的子串会一直到字符串的结尾
var myString = ‘javascript rox’;
myString = myString.substring(0,10); //javascript

substr()
可在字符串中抽取从 start 下标开始的指定数目的字符。返回一个新的字符串,包含从 start(包括 start 所指的字符) 处开始的 length 个字符。如果没有指定 length,那么返回的字符串包含从 start 到该字符串的结尾的字符。
var text=“excellent”
text.substring(0,4); //returns “exce”
text.substring(2,4); //returns “ce”

JSON.stringify() json->string
方法接收一个变量,并将它转换成 JSON 表示形式
const boy = {
name: ‘John’,
age: 123,
sno:2017
};
JSON.stringify(boy); // {“name”:“John”,“age”:23,”sno”:2017}
JSON.stringify(boy,[‘name’,’sno’]); // {“name”:“John”,”sno”:2017}

JSON.parse() string->json
const boy = {
name: ‘John’,
age: 23,
hobbies: new Map([[0, ‘coding’], [1, ‘earn money’]])
}
JSON.stringify(boy, (key, value) => {
if (value instanceof Map) {
return […value.values()]
}
return value
})
// “{“name”:“John”,“age”:23,“hobbies”:[“coding”,“earn money”]}"

ES5严格模式
‘use strict’;
两种用法:
全局严格模式
局部函数内严格模式(推荐)

在严格模式中
不支持with(),arguments.callee,func.caller
变量赋值前,必须先声明
局部this必须赋值,Person.call(null/undefined),赋值什么就是什么
拒绝重复属性和参数

console方法
console.clear() 清除当前控制台的所有输出,将光标回置到第一行。
console.table() 将复合类型的数据(json,array)转为表格显示

立即执行函数的三种方式,函数名可有可无,可传参数
(function test(形参){}(实参));
(function test(形参){})(实参);
-function test(形参){}(实参); //可在函数前添加-,+,!,让其运行

DOM
获取元素节点
document.getElementById()
//元素id 在Ie8以下的浏览器,不区分id大小写,而且也返回匹配name属性的元素

.getElementsByTagName()[] // 标签名

getElementByName()[];
//需注意,只有部分标签name可生效(表单,表单元素,img,iframe)

.getElementsByClassName()[] // 类名 -> ie8和ie8以下的ie版本中没有,可以多个class一起

.querySelector() // css选择器 在ie7和ie7以下的版本中没有
.querySelectorAll()[] // css选择器 在ie7和ie7以下的版本中没有

.querySelector()和.querySelectorAll()是非实时的,也就是说,一旦赋值之后,它的值将不会改变。如:
var div = document.querySelector(‘div’);//获取页面所有的div元素,假设页面有五个div
var demo = document.querySelector(‘div.demo’);
demo.remove(); //在页面中,移除类名为demo的div元素
.querySelector()和.querySelectorAll()简单点来说,就是不监听页面元素的增删,一旦赋值,便不再更改

节点
.parentNode 父节点
.childNodes[] 子节点
.firstChild 第一个子节点
.lastChild 最后一个子节点
.nextSibling 后一个兄弟节点
.previousSibling 前一个兄弟节点

1 3 45
1,3,5代表文本节点 2代表注释节点 4代表元素节点 var div = document.getElementsByTagName("div")[0]; div.childNodes.length = 5; //div共有5个子节点

节点的类型
元素节点—>1 属性节点—>2 文本节点—>3
注释节点—>8 document—>9 DocumentFragment—>11
基于元素节点树的遍历
parentElement -> 返回当前元素的父元素节点 (IE不兼容)
children -> 只返回当前元素的元素子节点
node.childElementCount=== node.children.length元素节点的子元素节点个数(IE不兼容)
firstElementChild -> 返回的是第一个元素节点(IE不兼容)
lastElementChild -> 返回的是最后一个元素节点(IE不兼容)
nextElementSibling / previousElementSibling 返回前(后)一个兄弟元素节点(IE不兼容)

元素节点使用
document.body 指代标签
document.head 指代标签
document.documentElement 指代标签
div.hasChildNodes 是否有子节点
div.parentElement 返回父元素节点
div.children 返回子元素节点
div.children.length 返回子元素节点的个数
div.firstElementChild 返回第一个子元素结点
div.lastElementChild 返回最后一个子元素节点
div.nextElementSibling 返回下一个兄弟元素结点
div.previousElementSibling 返回上一个兄弟元素子节点

获取节点类型: nodeType
获取节点名称: nodeName 只读不写
获取节点值: nodeValue 可读可写
var div = document.getElementsByTagName(“div”)[0];
div.nodeType===1;

设置属性名和属性值
var div = document.getElementsByTagName(‘div’)[0];
div.setAttribute(‘class’,‘dome’); //往div上添加一个demo的类
console.log(div.getAttribute(‘class’)); //获取div上的所有的类名

元素节点的操作
创建元素节点
var span = document.createElement(‘span’);

插入元素节点
div.appendChild(span);
document.append(span);
用appendChild()和append()插入节点时,插入在当前元素节点的最后的子节点之后

inserBefore
var div = document.getElementsByTagName(‘div’)[0];
var span = document.createElement(‘span’);
div.inserBefore(span,p); //在p标签之前插入span标签

insertAfter
Element.prototype.insertAfter = function (targetNode,afterNode){
var beforNode = afterNode.nextElementSibling;
if(beforNode == null){
this.appendChild(targetNode);
}
else{
this.insertBefore(targetNode,beforNode);
}
};
var div = document.getElementsByTagName(‘div’)[0];
var span = document.getElementsByTagName(‘span’)[0];
var p = document.createElement(‘p’);
div.insertAfter(p,span); //把p标签插入到span后面

删除节点
var div = document.getElementsByTagName(‘div’)[0];
var span = document.getElementsByTagName(‘span’)[0];
div.removeChild(span); //只是剪切掉,可以在删除前找一个变量存储着
span.remove();//直接删除

替换节点
var div = document.getElementsByTagName(‘div’)[0];
var span = document.getElementsByTagName(‘span’)[0];
var p = document.createElement(‘p’);
div.replaceChild(p,span); //拿p标签替换span标签

innerHTML
var div = document.getElementsByTagName(‘div’)[0];
var divcontent = div.innerHTML; //获取div里所有的内容,内容格式为HTML格式
div.innerHTML = ‘div’; //先清空div里的所有内容,然后’div’添加到div里

innerText
var div = document.getElementsByTagName(‘div’)[0];
var divtext = div.innerText; //获取div里所有的文本内容
div.innerText = ‘123’; //先清空div里所有的文本内容,然后’div’添加到div文本里

innerText在火狐里不兼容,火狐里有textContent,和innerText作用是一样,textContent 在老版本IE中不好使
定时循环器
setInterval(function (){this->window},1000);

清除定时循环器
var test = setInterval(function (){},1000);
clearInterval(test);

定时器
setTimeout(function (){this->window},1000)

清除定时器
var test = setInterval(function (){},1000);
clearTimeout( test);

DATE对象
getDate() 从 Date 对象返回一个月中的某一天 (1 ~ 31)。
getDay() 从 Date 对象返回一周中的某一天 (0 ~ 6)。
getFullYear() 从 Date 对象以四位数字返回年份。
getHours() 返回 Date 对象的小时 (0 ~ 23)。
getMilliseconds() 返回 Date 对象的毫秒(0 ~ 999)。
getMinutes() 返回 Date 对象的分钟 (0 ~ 59)。
getMonth() 从 Date 对象返回月份 (0 ~ 11)。
getSeconds() 返回 Date 对象的秒数 (0 ~ 59)。
getTime() 返回 1970 年 1 月 1 日至今的毫秒数。
parse() 返回1970年1月1日午夜到指定日期(字符串)的毫秒数。
setDate() 设置 Date 对象中月的某一天 (1 ~ 31)。
setFullYear() 设置 Date 对象中的年份(四位数字)。
setHours() 设置 Date 对象中的小时 (0 ~ 23)。
setMilliseconds() 设置 Date 对象中的毫秒 (0 ~ 999)。
setMinutes() 设置 Date 对象中的分钟 (0 ~ 59)。
setMonth() 设置 Date 对象中月份 (0 ~ 11)。
setSeconds() 设置 Date 对象中的秒钟 (0 ~ 59)。
setTime() setTime()方法以毫秒设置 Date 对象

date.setMinutes(50); //当前分钟数为50时,才会继续往下执行

键盘键值
判断键值:event.which == 13
16 shift 17 ctrl 18 alt 32 空格 46 Delete
13 Enter
37~40 左上右下
46 Delete
65~90 A~Z
112~123 F1~F12
异步加载
defer 异步加载,但要等到dom文档全部解析完才会被执行。只有IE能用。

async 异步加载,加载完就执行,async只能加载外部脚本,不能把js写在script 标签里。

兼容性选择性加载

异步加载js禁用document.write(),因为它本来也没什么用,如果当加载完页面后,调用此方法输出a会覆盖整个页面,即body的结构为a
window.onload = function (){
document.write(‘a’);
}

link加载外部CSS样式均属异步加载

事件

onabort 图像加载被中断
onblur 元素失去焦点
onchange 用户改变域的内容
onclick 鼠标点击某个对象
ondblclick 鼠标双击某个对象
onerror 当加载文档或图像时发生某个错误
onfocus 元素获得焦点
onkeydown 某个键盘的键被按下
onkeypress 某个键盘的键被按下或按住
onkeyup 某个键盘的键被松开
onload 某个页面或图像被完成加载
onmouseup 某个鼠标按键被松开
onmousedown 某个鼠标按键被按下
onmousemove 鼠标在上面移动时
onmouseleaver 鼠标离开div区域时,就执行一次事件
onmouseout 鼠标离开div或者是div的子元素区域时,就执行一次事件
onmouseover 鼠标在上面移动一次,就执行一次事件
onmouseenter 不管鼠标在上面移动多少次,只执行一次
onreset 重置按钮被点击
onresize 窗口或框架被调整尺寸
onselect 文本被选定
onsubmit 提交按钮被点击
onunload 用户退出页面
oncopy 复制
onselectstart 选取
oncut 剪切
onmousewheel 滚轮
oncontextmenu 右键
onpaste 粘贴

禁止事件
函数返回值为false,或是传入事件源,函数体最后执行e.returnValue = false
input.onpaste = function () {
alert(‘禁止粘贴’);
return false;
};

document.oncontextmenu = function (e) {
alert(‘禁止右键’);
e.returnValue = false;
}

绑定事件的三种方法
1.ele.onxxx = function (event) {}
兼容性很好,但是一个元素只能绑定一个处理程序
基本等同于写在HTML行间上
程序this指向是dom元素本身

2.obj.addEventListener(type, fn, false);
IE9以下不兼容,可以为一个事件绑定多个处理程序
程序this指向是dom元素本身
同一个事件能绑定多个函数,但不能绑定两个相同的函数
div.addEventListener(‘click’,test,false); //不输出,被覆盖
div.addEventListener(‘click’,test,false); //输出a
function test(){
console.log(“a”);
}
同一个事件能绑定多个函数
div.addEventListener(‘click’,function(){},false);
div.addEventListener(‘click’,function(){},false);

3.obj.attachEvent(‘on’ + type, fn);
IE独有,一个事件同样可以绑定多个处理程序
程序this指向window
var div = document.getElementById(“hu”);
div.attachEvent(‘onclick’,test); //输出a
div.attachEvent(‘onclick’,test); //输出a
function test(){
console.log(“a”);
}
同一个事件能绑定多个函数,也能绑定两个相同的函数,并且两个函数互相不影响

解决attachEvent事件指向this的问题
div.attachEvent(‘onclick’,function(){
test.call(div); //this指向div
});
function test(){}

事件兼容性解决
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;
}
}

解除事件
ele.onclick = false/‘’/null;
ele.removeEventListener(type, fn, false);
ele.detachEvent(‘on’ + type, fn);

事件处理模型
事件捕获(只有Google上好使)
结构上(非视觉上)嵌套关系的元素,会存在事件捕获的功能,即同一事件,自父元素捕获至子元素(事件源元素)。(自顶向下)

a.addEventListener(“click”,function(){
console.log(“a”);
},true);
b.addEventListener(“click”,function(){
console.log(“b”);
},true);
c.addEventListener(“click”,function(){
console.log(“c”);
},true);

点击a区域时,输出a
点击b区域时,输出a,b
点击c区域时,输出a,b,c

事件冒泡
结构上(非视觉上)嵌套关系的元素,会存在事件冒泡的功能,即同一事件,自子元素冒泡向父元素。(自底向上)

a.addEventListener("click",function(){ console.log("a"); },false); b.addEventListener("click",function(){ console.log("b"); },false); c.addEventListener("click",function(){ console.log("c"); },false);

点击a区域时,输出a
点击b区域时,输出b,a
点击c区域时,输出c,b,a

触发顺序,先捕获,后冒泡
focus,blur,change,submit,reset,select 等事件不冒泡
一个对象的一个事件类型只能遵循一种事件模型,要么冒泡,要么捕获,不能同时存在冒泡和捕获

取消冒泡
W3C标准 event.stopPropagation(); 但不支持ie9以下版本
IE独有 event.cancelBubble = true; chrome上也有这个方法

document.onclick = function () {
console.log(“你闲的呀”)
};
var div = document.getElementsByTagName(“div”)[0];
div.onclick = function (e){
e.stopPropagation();
// e.cancelBubble = true;
this.style.backgroundColor = “green”;
}

封装一个具有兼容性的阻止冒泡函数
function stopBubble(e){
if(e.stopPropagation){
e.stopPropagation();
}else{
e.cancelBubble = true;
}
}

阻止默认事件
1.return false; 以对象属性的方式注册的事件才生效
2.event.preventDefault(); W3C标注,IE9以下不兼容
3.event.returnValue = false; 兼容IE
4. void(0)或void(false)

事件源对象
事件源对象兼容
div.onclick = function (e){
var event = e || window.event;
}
在IE下,形参e不会接收浏览器的事件源对象,因此用var event = e || window.event;作浏览器的兼容

事件源对象
event.target 火狐独有的
event.srcElement Ie独有的
event.target和event.srcElement chrome上都有

获取事件源对象event.target

var a = document.getElementsByClassName("a")[0]; var b = document.getElementsByClassName("b")[0]; a.onclick = function (e){ var event = e || window.event; var target = event.target || event.srcElement; console.log(target); }

事件委托
通俗的讲就是委托长辈来执行事件。
把事件绑定到事件源对象的祖先元素上,利用事件冒泡原理触发事件。
优点:

  1. 提高性能,不需要循环所有元素一个一个绑定事件。
  2. 灵活,有动态创建进来的新元素不需要重新绑定事件
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
var ul = document.getElementsByTagName("ul")[0]; ul.onclick = function (e){ var event = e || window.event; var target = event.target || event.srcElement; console.log(target.innerText); } 点击li,输出对应li里的文本内容

获取窗口属性
查看滚动条的滚动距离
window.pageXOffset/pageYOffset
IE8及IE8以下不兼容

ie8或以下能用 兼容有问题通常用两值相加
兼容性比较混乱,用时取两个值相加,因为不可能存在两个同时有值
scrollLeft=document.body.scrollLeft+document.documentElement.scrollLeft;
scrollTop=document.body.scrollTop+document.documentElement.scrollTop;

查看视口的尺寸
window.innerWidth/innerHeight IE8及IE8以下不兼容

document.documentElement.clientWidth/clientHeight 标准模式,任意浏览器都兼容

document.body.clientWidth/clientHeight 适用于怪异模式下的浏览器

标准模式指的是有,怪异(混杂)模式指的是没有
查看元素的高
div.offsetWidth = width + 左右padding + 左右boder
div.offsetHeight = height + 上下padding + 上下boder

查看元素的位置
dom.offsetLeft, dom.offsetTop
对于无定位父级的元素,返回相对文档的坐标。对于有定位父级的元素,返回相对于最近的有定位的父级的坐标
div.offsetLeft 是距离最近的具有定位的父级元素的距离
div.offsetTop 是距离最近的具有定位的父级元素的距离

dom.offsetParent
返回最近的有定位的父级,如无,返回body, body.offsetParent 返回null

div.clientWidth = content.width + 左右padding
div.clientHeight = content.height + 上下padding

div.clientTop = border-top
div.clientLeft = border-left

鼠标
clientX、clientY
点击位置距离当前body可视区域的x,y坐标

pageX、pageY
对于整个页面来说,包括了被卷去的body部分的长度

screenX、screenY
点击位置距离当前电脑屏幕的x,y坐标

offsetX、offsetY
相对于带有定位的父盒子的x,y坐标

滚动条
window.scroll(x,y) and window.scrollTo(x,y) 是一样的,从哪到哪
window.scrollBy(x,y) 可以累加,多次执行

获取滚动距离
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,
}
}
}

脚本化CSS
获取伪类样式值
window.getComputedStyle(div,‘after’).width

dom.style.prop
可读写行间样式,没有兼容性问题,碰到float这样的关键字属性,前面应加css
eg:float — > cssFloat

符合属性必须拆解,组合单词变成小驼峰式写法

写入的值必须是字符串格式

封装兼容性方法
function getStyle(elem,prop){
if(window.getComputedStyle){
return window.getComputedStyle(elem,null)[prop];
}else{
return elem.currentStyle[prop];
}
}

克隆
浅度克隆
var obj = { name:“huay” , age:15 , sno:2017011122 };
var obj1 = {};
function clone(origin,target){
var target = target ||{};
for(var prop in origin){
target[prop] = origin[prop];
}
return target;
}
clone(obj,obj1);

深度克隆
var obj = {
name:“虎牙”,
age:123,
hp:[99,2,1],
son:{
no:“huay”,
hu:“nciaca”
}
};
var obj1 = {};
function deepClone(origin,target){
var target = target || {},
toStr = Object.prototype.toString,
arrStr = “[object Array]”;
for(var prop in origin){
if(origin.hasOwnProperty(prop)) {
if (origin[prop]!==“null”&& typeof (origin[prop]) == “object”) {
if (toStr.call(origin[prop]) == arrStr) {
target[prop] = [];
} else {
target[prop] = {};
}
deepClone(origin[prop], target[prop]);
} else {
target[prop] = origin[prop];
}
}
}
return target; }

classList
document.getElementById(“myDIV”).classList.add(“mystyle”);

属性:length

方法:
add(class1, class2, …) 在元素中添加一个或多个类名。
contains(class) 返回布尔值,判断指定的类名是否存在。
item(index) 返回元素中索引值对应的类名。索引值从 0 开始。
如果索引值在区间范围外则返回 null
remove(class1, class2, …) 移除元素中一个或多个类名。
注意: 移除不存在的类名,不会报错。
toggle(class, true|false) 在元素中切换类名。

获取css样式的值
function getStyle(element, attr) {
if(element.currentStyle) {
return element.currentStyle[attr];
} else {
return getComputedStyle(element, false)[attr];
}
}

var myDiv = document.getElementById(“myDiv”);
var computedStyle = document.defaultView.getComputedStyle(myDiv, null);
alert(computedStyle.backgroundColor);
window.getComputedStyle(div,‘after’).width 获取伪类样式表

d属性用来定义路径数据
stroke:描边颜色
stroke-width:描边宽度
fill:填充颜色
stroke-dasharray:间隔多少像素绘制一次
stroke-dashoffset:每次绘制偏离多少,必须配合stroke-dasharray使用

d属性参数有:
M = moveto(M X,Y) :将画笔移动到指定的坐标位置
L = lineto(L X,Y) :画直线到指定的坐标位置
H = horizontal lineto(H X):画水平线到指定的X坐标位置
V = vertical lineto(V Y):画垂直线到指定的Y坐标位置
C = curveto(C X1,Y1,X2,Y2,ENDX,ENDY):三次贝赛曲线
S = smooth curveto(S X2,Y2,ENDX,ENDY):平滑曲率
Q = quadratic Belzier curve(Q X,Y,ENDX,ENDY):二次贝赛曲线
T = smooth quadratic Belzier curveto(T ENDX,ENDY):映射
A = elliptical Arc(A RX,RY,XROTATION,FLAG1,FLAG2,X,Y): 椭圆弧
Z = closepath():关闭路径


var c=document.getElementById(“myCanvas”);
var cxt=c.getContext(“2d”);
cxt.fillStyle="#FF0000";
cxt.fillRect(0,0,150,75);

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值