JS 基础知识
- JS中,简单类型的数据存储在栈中,复杂类型的数据存储在堆中,其引用存储在栈中
- JS中的深拷贝和浅拷贝:
- 浅拷贝:将对象中的所有简单类型的属性拷贝出来,引用类型属性直接赋值null
- 深拷贝:将对象中的所有属性都拷贝出来,引用类型属性对象中的属性一一拷贝
- JS类型检测方法:
- typeof 100:number/string/boolean/undefined/object/function
- 100 instanceof Number:true/false
- Object.prototype.toString.apply(100):[Object Number/String/Function/Null]
- JS中数组定义方式:
- var arr = new Array();
- var arr = new Array(20); // 长度20
- var arr = new Array(1,2,3,4);
- var arr = [1,2,34,4]; var arr = [[1,2,3],[2,3,4]];
- JS中的try/catch/finally:
- JS中的try/catch/finally用法和JAVA中相同
- 抛出异常:throw new Error("这是一个异常");
- 打印异常信息:console.error("打印的异常");
- JS中的函数传参:
- 简单类型的参数,传递的是一个局部变量,其变化后不影响原始值
- 引用类型的参数,传递的是一个指针,其变化后悔影响原始值
- 函数内部可以使用arguments[i]来获取函数的第i个参数
- JS代码执行流程:JS代码由浏览器解析器执行,解析器要先进行预解析,即在同一级作用域中,找出var声明的变量、function函数和函数的参数,将它们提到这个作用域的最前端,然后再逐行解析
- JS中的DOM操作:
- 添加:ele.appendChild(node);
- 插入:ele.insertBefore(newNode, node); //将newNode插入到node前面
- 删除:ele.removeChild(node);
- 修改:ele.replaceChild(newNode, oldNode);
- 创建:document.createElement('div');
- 克隆:var newNode = ele.cloneNode(true); //true会克隆所有子节点
- JS - Date API:
- 获取当前系统时间:var date = new Date();
- 获取某个日期时间:var date = new Date(2016, 12, 25);
- 获取年:getFullYear();获取月:getMonth()+1;获取日:getDate()
- 获取时:getMonth();获取分:getMinutes();获取秒:getSeconds()
- 获取时间戳(毫秒):getTime()
- JS - String API:
- 大小写转换:str.toUpperCase(); str.toLowerCase();
- 字符串分割:str.split('/');
- 查找子串:str.indexOf("abc");
- JS - Math API:
- 绝对值:Math.abs(-10)
- 向上/向下取整:Math.ceil(4.5); Math.floor(4.5);
- X的Y次幂:Math.pow(x, y);
- 开平方:Math.sqrt(16);
- 返回一个0-1的随机数:Math.random();
- JS - Array API:
- 将arr2中的数据链接到arr1后面:arr1.concat(arr2);
- 数组变成字符串:var str = [1,2,3].join('-'); //1-2-3
- 删除并返回数组中的最后一个元素:arr1.pop();
- 删除并返回数组中的第一个元素:arr1.shift();
- 向数组最后添加多个元素,返回新的长度:arr1.push(8);
- 向数组开头添加多个元素,返回新的长度:arr1.unshift(8);
- 逆序数组:arr1.reverse();
- 将数组按升序排序:arr1.sort();
- 将数组按自定义规则排序:arr1.sort(function(a, b) { return a < b; });
- 返回数组中从startpos开始到endpos-1的所有元素(如果endpos是负数,则是到数组中的倒数第几个元素):arr1.slice(startpos, endpos);
JS offset
- JS中的offset用于方便的获取元素尺寸
- offsetWidth和offsetHeight:
- DOM对象的这两个属性,可以检测元素所占位置的宽高
- 这里的宽高包括宽高本身和padding、边框,但不包括margin
- offsetWidth和offsetHeight的返回值是number类型,没有
px
单位
- offsetLeft和offsetTop:
- DOM对象的这两个属性,可以检测元素距离父容器边界的距离
- 这里的父容器必须是具有
position
属性的容器,如果直系父容器没有position
属性,则找爷爷容器 - 如果所有父容器都没有
position
属性,则返回与body边界的距离 - offsetLeft和offsetTop只包括父容器的padding,不包括父容器的边框和margin
- offsetLeft和offsetTop的返回值是number类型,没有
px
单位
- offsetParent:
- 返回距离该元素最近的,有
position
属性的父容器对象 - 这里的
position
属性可以是relative
、absolute
、fixed
,但不可以是static
- 如果该元素上层的所有父容器都没有设置
position
属性,则返回body对象
- 返回距离该元素最近的,有
JS 动画
- 闪现动画:直接设置元素的位置即可
- 匀速动画:设置定时器,每隔一定时间移动一定的位置
btn.onclick = function() {
setInterval(function() {
div.style.left = div.offsetLeft + 5 + "px";
}, 100);
} - 变速动画:
- 变速动画,就是一个开始时运动快,运动过程中越来越慢的动画效果
- 变速动画的优点:有非常逼真的动画效果,实现的动画效果更加细腻
- 变速动画的缺点:如果不清除定时器,则会一直运行下去
- 变速动画原理:
盒子位置 = 盒子本身位置 + (目标位置 - 盒子本身位置) / 10
- 变速动画实现代码:
var timer = null;
btn.onclick = function() {
timer = setInterval(function() {
div.style.left = div.offsetLeft + Math.ceil((400 - div.offsetLeft) / 10) + 'px';
console.log(1);
if(Math.abs(div.offsetLeft) === 400) {
clearInterval(timer);
}
}, 30);
};
JS HTML基本结构获取方法
- 文档标题title:document.title
- 所有HTML:document.documentElement
- 文档头标签head:document.head
- 文档内容body:document.body
JS JSON
- JSON定义:
var json = {'param1':'aaa', 'param2':123, ...};
- JSON数据的遍历,代码如下:
for(var k in json) {
console.log(k); // 属性
console.log(json[k]); // 属性值
}
JS scroll
- scrollWidth和scrollHeight:
- DOM对象的这两个属性,可以检测元素内容的宽高
- 这里的宽高包括对象本身的宽高和padding值,不包括margin和border
- 如果内容超出对象,则以内容为准;否则以对象本身为准
- scrollLeft和scrollTop:
- DOM对象的这两个属性,可以获取网页被卷去的头部的像素大小
- 由于这两个方法有浏览器兼容问题,获取的时候需要考虑兼容,代码如下:
console.log(document.body.scrollTop || document.documentElement.scrollTop);
// 也可以按下面的方法写
console.log(document.body.scrollTop + document.documentElement.scrollTop);
// 也可以按下面的方法写
console.log(window.pageYOffset); - 当前的主流写法:
console.log(window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop);
- 通过代码设置页面滚动到某个坐标值:
window.scrollTo(x, y);
- 监听页面的滚动事件:
window.onscroll = function() {};
JS 事件对象Event
- 如果事件函数中没有参数,系统默认会提供一个event参数,代码如下:
div.onclick = function() {
console.log(event); // event有值
} - 如果带了参数且参数不为event,则event仍可用,但有些浏览器不支持这个函数参数
- 如果带了参数且参数为event,则有些浏览器不会再识别event,如IE浏览器
- 针对上面的问题,需要有一个兼容的写法,代码如下:
div.onclick = function(event) {
event = event || window.event;
console.log(event);
} - event属性:
- event.target:触发事件的对象
- event.type:事件的类型(click)
- event.button:获取事件是鼠标的哪个按钮被点击(左键0,滑轮1)
- event.pageX:光标相对于该网页顶部的水平位置(IE不支持该属性)
- event.pageY:光标相对于该网页左边的垂直位置(IE不支持该属性)
- event.screenX:光标相对于屏幕顶端的水平位置
- event.screenY:光标相对于屏幕左端的垂直位置
- event.clientX:光标相对于该网页可见区域的水平位置
- event.clientY:光标相对于该网页可见区域的垂直位置
- event事件冒泡机制:
- 当一个盒子触发一个事件之后,会将这个事件依次传递给它的父盒子、父父盒子......
- 注意:一个事件只能触发同类事件,如onclick只能触发onclick
- 也就是说,当点击一个盒子之后,会依次触发其父盒子的onclick、其父父盒子的onclick......(如果这些盒子都有onclick事件的话)
- 事件冒泡的顺序:div -> body -> html -> document -> window
- 以下事件不冒泡:onmouseenter、onmouseleave、onload、onunload、onfocus、onblur
- 阻止冒泡的代码:
if (event || event.stopPropagation) {
event.stopPropagation();
} else {
event.cancelBubble = true;
}
- event事件传播的三个阶段:
- 捕获阶段:事件从DOM树顶层向下查找,直到捕获到事件源
- 冒泡阶段:事件依次向上冒泡
- 目标阶段:事件依次执行
JS client
- clientWidth和clientHeight:
- DOM对象的这两个属性,用于获取网页可视区域的宽高
- 不同对象的这两个属性,拥有不同的意义
- 如果调用这两个属性的是一个盒子,则表示这个盒子的宽高
- 如果调用这两个属性的是body/html,则表示网页可视区域的宽高
- clientX和clientY:这两个属性仅用于事件中获取鼠标位置
- clientTop和clientLeft:
- clientWidth = width + padding
- clientHeight = height + padding
JS 三大家族总结
- 三大家族包括:offset、scroll、client
- offsetWidth/height = width/height + padding * 2 + border * 2
- scrollWidth/height = width/height
if(window.pageYOffset !== undefined){
return {
"top": window.pageYOffset,
"left": window.pageXOffset
};
}else if(document.compatMode === "CSS1Compat"){
return {
"top": document.documentElement.scrollTop,
"left": document.documentElement.scrollLeft
};
}else{
return {
"top": document.body.scrollTop,
"left": document.body.scrollLeft
};
} - clientWidth/height = width/height + padding * 2
if(window.innerHeight !== undefined){
return {
"width": window.innerWidth,
"height": window.innerHeight
}
}else if(document.compatMode === "CSS1Compat"){
return {
"width": document.documentElement.clientWidth,
"height": document.documentElement.clientHeight
}
}else{
return {
"width": document.body.clientWidth,
"height": document.body.clientHeight
}
} - offsetTop/offsetLeft:
- 调用者:任意元素
- 作用:距离父系盒子中有定位的(有position属性的)父盒子的距离
- scrollTop/scrollLeft:
- 调用者:document.body
- 作用:被浏览器卷去的网页上边和左边的内容宽高
- clientX/clientY:
- 调用者:事件event
- 作用:鼠标距离浏览器可视区域边界的距离