JS 笔记
1. js的作用:
- 表单校验
- 网页特效
- 桌面程序
2. 浏览器执行流程:
-
渲染引擎:解析HTML与CSS的,俗称内核,Chrome的blink
-
js引擎:js解释器,读取JavaScript的代码,处理后运行,Chrome的v8引擎
浏览器本身不会执行js,通过内置js引擎来执行js代码,脚本 语言,逐行解释。
3. js 的组成
- ECMAScript js语法
- DOM 页面文档对象模型
- BOM 浏览器对象模型
4. js 的书写位置 (js 里的字符串多用 单引号)
- 行内式
- 内嵌式
- 外部引入
5. 输入输出语句:
- prompt
- alert
- console.log
js变量
1. js 变量
- 当变量只声明不赋值,为undefined
- 当变量不声明而使用,变为全局变量
- 变量命名规范:同 java
2. js 数据类型
-
Number 类型
特殊值:
- Infinity 无穷大
- -Infinity 无穷小
- NaN not a number 不是一个数字 如字符串与数字运算
isNaN() 方法判断是否是非数字 带引号的数字也算
-
String 类型
- str.length 获取字符长度
-
Boolean 类型 与 undefined 与 null
-
flag 可以参与运算 true 为 1 false 为 0
-
小惊喜 undefined 与 null :
var str = undefined; console.log(str + 'zed'); //undefinedzed console.log(str + 1); // NaN var str = null; console.log(str + 'pink'); //nullpink console.log(str + 1); //1
-
-
用 typeof 获取变量的数据类型
-
var v = null; console.log(typeof(v)); //object
-
prompt 获取的为string类型
-
控制台颜色同样可以判断:黑色为string 蓝色为数字
-
-
数据类型转换
转字符串的三种方式:
var v = 1; console.log(v); console.log(v.toString()); console.log(String(v)); console.log(v + '');
转换为数字型的四种方式:
console.log(parseInt('2')); console.log(parseFloat('0.2')); console.log(Number('3')); console.log('123' - '3'); // - * / 都可以进行隐式转换
转换为布尔类型:
代表为空、否定的值会被转换为false 如:""、0、NaN、null、undefined 其余值转为true ‘0’ 为 true
js运算相关
1. 运算符
var v = 10;
var r = v++ + ++v; // 10 + 12
console.log(r); //22
console.log(v); //12
== 判断会进行隐式转换,字符转成数字
=== 判断会进行全等判断,判断数据与数据类型
2. 逻辑运算符:
-
布尔值参与逻辑运算 同 java
-
非布尔值参与逻辑运算
短路运算(逻辑中断):当左边的表达式可以确定结果将不再进行运算
逻辑与中断:
如果第1个表达式为真,返回表达式2
如果第1个表达式为假,返回表达式1
console.log(12 && 34); //34 console.log(0 && 2); //0 console.log('' && 12); //0 console.log(undefined && 12); //undefined console.log(null && 12); //null
逻辑或中断:
表达式1结果为真,返回表达式1
表达式1结果为假,返回表达式2
console.log(12 || 34); //12 console.log(0 || 34); //34 console.log(null || 12); //12 console.log(undefined || 12); //12 var num = 0; console.log(123 || num++); console.log(num); //num = 0
3. 控制语句:
同java
4. 数组
创建数组的方式:
var arr = new Array();
var arr2 = [];
var arr3 = [1, '李四', 'jackson'];
console.log(arr3[3]); //数组越界 undefined
新增元素的方式:
修改 arr.length
var arr = [1, 3, 5];
arr.length = 5;
修改索引号 追加元素 也能直接修改元素
var a = [3, '榴莲', 5];
a[3] = 'pink';
console.log(a);
a[0] = 1;
console.log(a);
5. js 函数
参数问题:
function getSum(num1, num2) {
return num1 + num2;
}
console.log(getSum(1, 2, 3)); //3 只取前两个数
console.log(getSum(1)); //NaN 其中num2会变为undefined
当函数没有return 则返回undefined
6. arguments 的使用
function getMax() {
var max = arguments[0];
for (var i = 1; i < arguments.length; i++) {
if (max < arguments[i]) {
max = arguments[i];
}
}
return max;
}
console.log(getMax(1, 3, 5, 1, 5, 9));
arguments 是伪数组,不是真正意义上的数组,具有length属性,没有pop() 和 push() 等方法
7. 函数的声明方式
利用函数关键字自定义函数(命名函数)
function fn1() {
console.log(1);
}
fn1();
函数表达式(匿名函数)
//var 变量名 = function(){};
var fn = function() {
console.log(1);
}
fn();
//fn 是变量名,不是函数名
8. js 的作用域
js 没有块级作用域,es6 新增块级作用域
if (3 < 5) {
var num = 3;
}
console.log(num); // 3
if (5 < 3) {
var num = 3;
}
console.log(num); //undefined
作用域链:
就近查找
预解析:
console.log(num); //undefined
var num = 1;
fn();
function fn() {
console.log(1); //1
}
fn2();
var fn2 = function() {
console.log(1); //报错
}
js 引擎运行分两步:预解析,代码执行
(1)预解析js引擎会把js里的所有var和function 提升到当前作用域的最前面
(2)代码执行 按照代码书写的顺序从上往下执行
预解析分为:变量预解析(变量提升)与函数预解析(函数提升)
(1)变量提升 把所有变量的声明放到当前作用域最前面 不提升赋值操作
(2)函数提升 把所有函数的声明提升到当前作用域最前面 不调用函数
js 预解析 习题:
//案例1
var num = 10;
fun();
function fun() {
console.log(num); //undefined
var num = 20;
}
//案例1 具体步骤
var num;
function fun() {
var num;
console.log(num); //undefined
num = 20;
}
num = 10;
fun();
//案例2
var num = 10;
function fn() {
console.log(num); //undefined
var num = 20;
console.log(num); //20
}
fn();
//案例3
var a = 18;
f1();
function f1() {
var b = 9;
console.log(a); //undefined
console.log(b); //9
var a = '123';
}
//案例4
f1();
console.log(c); //9
console.log(b); //9
console.log(a); //报错 a is not defined
function f1() {
var a = b = c = 9; //相当于 var a = 9; b = 9; c = 9; 即只有a是局部变量
console.log(a); //9
console.log(b); //9
console.log(c); //9
}
9. js 的
创建对象的方法:
-
字面量创建对象 { }
var obj = { name : 'zhangsan', age : 18, sayHi : function() { console.log('Hi'); } } console.log(obj.name); console.log(obj['age']); obj.sayHi();
-
new 关键字创建对象
var obj = new Object(); obj.name = '李四'; obj.age = 18; obj.sex = '男'; obj.sayHi = function() { console.log('Hi~~'); } console.log(obj.name); console.log(obj.sex); console.log(obj['age']); obj.sayHi();
-
采用构造方法创建对象 同 java
function Star(name, age, sex) { this.name = name; this.age = age; this.sex = sex; this.sing = function(song) { console.log(song); } } var obj = new Star('刘德华', 60, '男'); obj.sing('冰雨'); //直接调用了方法 打印出冰雨
-
遍历对象属性 for……in
function Star(name, age, sex) {
this.name = name;
this.age = age;
this.sex = sex;
this.sing = function(song) {
console.log(song);
}
}
var obj = new Star('刘德华', 18, '男');
for (var k in obj) {
console.log(k); //属性名
console.log(obj[k]); //属性值
}
10. js的内置对象
js对象三大类:自定义对象,内置对象,浏览器对象
前两种属于ECMAScript 第三种属于独有的 JS API
查阅MDN官方文档
console.log(Math.PI); //3.141592653589793
console.log(Math.max(1, 3, 5));//5
console.log(Math.max()); //-Infinity
var myMath = {
PI : Math.PI,
min : function() {
var min = arguments[0];
for (var i = 1; i < arguments.length; i++) {
if (arguments[i] < min) {
min = arguments[i];
}
}
return min;
},
max : function() {
var max = arguments[0];
for (var i = 1; i < arguments.length; i++) {
if (arguments[i] > max) {
max = arguments[i];
}
}
return max;
}
} //封装自己的数学对象
// 获取绝对值
console.log(Math.abs(-1)); //1
console.log(Math.abs('-1')); //隐式转换 1
console.log(Math.abs('aaa')); //NaN
//向下取整
console.log(Math.floor(-1.2)); //-2
console.log(Math.floor(1.2)); //-2
//向上取整
console.log(Math.ceil(2.1)); //3
console.log(Math.ceil(-1.9)); //-1
//四舍五入
console.log(Math.round(3.5)); //4
console.log(Math.round(-3.5)); //-3
随机数的产生:
//Math.random() 函数返回一个浮点数, 伪随机数在范围从0到小于1
//获取闭区间数值
function getRandomIntInclusive(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min; //含最大值,含最小值
}
创建日期:
var date1 = new Date(2019, 10 ,1);
console.log(date1); //返回11月
var date2 = new Date('2019-10-1 12:12:12')
console.log(date2); //正常打印
//格式打印日期
var now = new Date();
var year = now.getFullYear();
var month = now.getMonth() + 1;
var date = now.getDate();
var arr = ['星期天', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
console.log(year + '年' + month + '月' + date + '日 ' + arr[now.getDay()]);
//获取时间
function getTime() {
var date = new Date("2019-8-8 8:8:8");
var h = date.getHours();
h = h < 10 ? '0' + h : h;
var m = date.getMinutes();
m = m < 10 ? '0' + m : m;
var s = date.getSeconds();
s = s < 10 ? '0' + s : s;
return h + ':' + m + ':' + s;
}
日期毫秒数:
var date = new Date();
//获取距离1970.1.1的毫秒数
console.log(date.getTime());
console.log(date.valueOf());
//常用写法
var date2 = +new Date();
//h5新增
console.log(Date.now());
//倒计时
function countDown(time) {
var now = +new Date();
var end = +new Date(time);
var times = end - now;
var d = parseInt(times / 1000 / 60 / 60 / 24);
d = d < 10 ? '0' + d : d;
var h = parseInt(times / 1000 / 60 / 60 % 24);
h = h < 10 ? '0' + h : h;
var m = parseInt(times / 1000 / 60 % 60);
m = m < 10 ? '0' + m : m;
var s = parseInt(times / 1000 % 60);
s = s < 10 ? '0' + s : s;
return d + '天' + h + '小时' + m + '分钟' + s + '秒';
}
数组相关:
//数组创建
var arr = [1, 3, 5];
console.log(new Array(2)); //长度为2的空数组
console.log(new Array(2, 3)); //[2, 3]
console.log(arr); //arr
//instanceof 运算符 判断是否为某类实例
var arr = [];
var obj = {};
console.log(arr instanceof Array);
console.log(obj instanceof Array);
//Array.isArray() 方法判断 ie9以上支持
console.log(Array.isArray(obj));
var arr = [1, 3, 5];
//尾部添加
arr.push(1);
console.log(arr); //[1, 3, 5, 1]
//头部添加
arr.unshift(99);
console.log(arr); //[99, 1, 3, 5, 1]
//取出尾部元素(原数组改变)
arr.pop();
console.log(arr); //[99, 1, 3, 5]
//取出头元素(原数组改变)
arr.shift();
console.log(arr); //[1, 3, 5]
//数组排序
var numbers = [4, 2, 5, 1, 3];
numbers.sort(function(a, b) {
return a - b;
});
console.log(numbers);
//也可以写成:
var numbers = [4, 2, 5, 1, 3];
numbers.sort((a, b) => a - b);
console.log(numbers);
字符串不可变,同java
字符串的所有方法都不会修改字符串本身(字符串不可变),操作完成都是返回新字符串。
var str = '15795400';
console.log(str.indexOf(5)); //返回第一个所找的数索引
console.log(str.indexOf(5, 2)); //从2索引位置开始,寻找第一个数
//统计字符串中某字符出现次数以及下标
var str = 'abcoefoxyozzopp';
var index = str.indexOf('o');
var count = 0;
while (index != -1) {
count++;
console.log(index);
index = str.indexOf('o', index + 1);
}
console.log(count);
var str = 'abcoefoxyozzopp';
console.log(str.charAt(0)); //a
console.log(str[0]); //a
console.log(str.charCodeAt(0)); //97 返回0索引处字符的ASCII码
//返回各个字符的出现次数 类似Java的map
var str = 'abcoefoxyozzopp';
var obj = {};
for (var i = 0; i < str.length; i++) {
var chars = str[i];
if (obj[chars]) {
obj[chars]++;
} else {
obj[chars] = 1;
}
}
console.log(obj);
//返回最大次数的那个字符,并返回次数
var max = 0;
var themax = '';
for (var k in obj) {
if (obj[k] > max) {
max = obj[k]
themax = k;
}
}
console.log(max);
console.log(themax);
字符串操作方法:
var str = '123456789';
console.log(str.substr(3, 3)); //从3索引开始取3个字符
//替换字符串
var str = '123345369';
while (str.indexOf(3) != -1) {
str = str.replace(3, '*');
}
console.log(str); //12**45*69
//字符串转换为数组
var str = 'a, b, c';
console.log(str.split(',')); //["a", " b", " c"]
var str = 'a& b& c';
console.log(str.split('&')); //["a", " b", " c"]
//转换大小写
var str = 'asbDSsdf';
console.log(str.toUpperCase());
console.log(str.toLowerCase());
11. 数据类型
简单数据类型(基本数据类型、值类型)
string, number, boolean, undefined, null
//简单数据类型null 用typeof 返回是 object
var str = null;
console.log(typeof(str)); //object
WebAPI
1. 获取元素的方法
console.dir( ) 更好的查看属性和方法
var nav = document.getElementById('nav');
var lis = nav.getElementsByTagName('li');
for (var i = 0; i < lis.length; i++) {
console.log(lis[i]);
}
//注意复数形式
//h5 新增获取元素的方法
// 通过类名获取
var boxs = document.getElementsByClassName('box');
//返回指定选择器的第一个元素
var box1 = document.querySelector('.box');
console.log(box1);
var box2 = document.querySelector('#b1');
console.log(box2);
//获取指定选择器所有元素
var boxs = document.querySelectorAll('.box');
//获取body
var bodyEle = document.body;
console.log(bodyEle);
//获取HTML元素
var htmlEle = document.documentElement;
console.log(htmlEle);
2. 操作元素
改变元素内容:
div.innerText 不识别html的标签 写的时候原封不动写出,读的时候不显示html标签,取出空格与换行
div.innerHtml 识别html标签 写的时候自动转换标签,读的时候保留原有的所有格式,并保留html标签
仿京东密码栏
// label 标签绑定文本框,点击时鼠标光标移至输入框
<label for="pwd">
<img src="images/open.png" id="eye">
</label>
<input type="password" id="pwd">
改变样式:
// 记住先使用style引出 后面的属性使用小驼峰(严格)
div.onclick = function() {
div.style.backgroundColor = 'skyblue';
this.style.width = '300px';
}
//使用 className 调用css样式快速改变样式
div.onclick = function() {
this.className = 'change';
}
排他思想:
- 清除所有元素样式
- 给当前元素设置样式
// 鼠标经过
trs[i].onmouseover = function() {
this.style.backgroundColor = 'pink';
}
// 鼠标移出
trs[i].onmouseout = function() {
this.style.backgroundColor = '';
}
表单全选与反选:
// 全选
for (var i = 0; i < checkboxs.length; i++) {
checkboxs[i].onclick = function() {
for (var i = 0; i < checkboxs.length; i++) {
if (!checkboxs[i].checked) {
btn.checked = false;
return;
}
}
btn.checked = true;
}
}
属性的获取
<div id="dd" indexsss="one"></div>
// 用 . 获取自带的属性
console.log(div.id);
console.log(div.getAttribute('id'));
// 用 . 无法获取自定义属性
console.log(div.indexsss);
// 用getAttribute获取自定义属性
console.log(div.getAttribute('indexsss'));
属性的设置
var div = document.querySelector('div');
// 用 setAttribute 赋值自定义属性
div.setAttribute('indexsss', 'tow');
// 用 setAttribute 赋值class 这里不用 className
div.setAttribute('class', 'more');
// 移除属性
div.removeAttribute('class');
自定义属性
目的:保存使用数据,直接保存到页面中而不用保存到数据库中。
设置自定义属性:规定以 data- 开头
获取自定义属性:
- element.getAttribute(‘data-index’)
- element.dadaset.index 或者 element.dataset[‘index’] (ie11 才开始支持)
<div data-index="1"></div>
<div data-index="2"></div>
<div data-index-time="3"></div>
var divs = document.querySelectorAll('div');
console.log(divs[1].dataset.index);
console.log(divs[0].dataset['index']);
// 带 - 自动转换为 小驼峰
console.log(divs[2].dataset.indexTime);
3. 操作节点
利用父子兄弟节点关系获取元素,逻辑性强但兼容性差。
节点概述:
节点至少拥有nodeType、nodeName、nodeValue三个基本属性。
nodeType:
- 元素节点 nodeType 为 1
- 属性节点 nodeType 为 2
- 文本节点 nodeType 为 3(包含文字、空格、换行)
相关节点的方法:
// 获取所有子节点 包含文本节点 (不推荐使用)
ul.childNodes; // 11个
for (var i = 0; i < ul.childNodes.length; i++) {
if (ul.childNodes[i].nodeType == 1) {
console.log(ul.childNodes[i]);
}
}
// 获取所有子元素的节点 推荐使用
parentNode.children;
// 获取最近的父节点
node.parentNode;
// 获取第一个与最后一个节点 包括文本节点 (不常用)
console.log(ol.firstChild);
console.log(ol.lastChild);
// 只获取第一个与最后一个元素节点的方法 ie9以上
console.log(ol.firstElementChild);
console.log(ol.lastElementChild);
// 实际中使用 (常用)
console.log(ol.children[0]);
console.log(ol.children[ol.children.length - 1]);
// 记住使用 this
for (var i = 0; i < lis.length; i++) {
lis[i].onmouseover = function() {
this.children[1].style = 'display: block';
}
lis[i].onmouseout = function() {
this.children[1].style = 'display: none';
}
}
// 获取兄弟节点
console.log(div.nextSibling);
console.log(span.previousSibling);
// 只获取兄弟元素节点 ie9 以上支持
console.log(div.nextElementSibling);
console.log(span.previousElementSibling);
// 封装函数解决兼容性问题
function getNextElementSibling(element) {
var el = element;
while (el = el.nextSibling) {
if (el.nodeType == 1) {
return el;
}
}
return null;
}
创建与添加、删除节点:
var li = document.createElement('li');
var ul = document.querySelector('ul');
// 添加子节点 往后追加 要先创建
ul.appendChild(li);
// 在ul里面插入新的节点,位于某一子节点之前
ul.insertBefore(li, ul.children[0]);
// 删除子节点 ul.removeChile(child)
ul.removeChild(ul.children[0]);
// 链接不跳转
<a href='javascript:;'>删除</a>
var c1 = ul.children[0].cloneNode();
ul.appendChild(c1);
// 复制内容的深拷贝 为true或其他代表true的
var c2 = ul.children[0].cloneNode(true);
ul.appendChild(c2)
// 创建某一个元素后不可以重复使用(添加)
三种创建元素方式的区别:
// 会导致页面重绘(了解)
document.write('<div>12</div>');
// innerHTML 创建多个元素效率更高,但是是使用创建数组然后拼接的方式,而不是直接拼接字符串的方式
var arr = [];
for (var i = 0; i < 5000; i++) {
arr[i] = '<a href="#">百度</a>';
}
div.innerHTML = arr.join('');
// createElement 的方式
for (var i = 0; i < 5000; i++) {
var a = document.createElement('a');
div.appendChild(a);
}
事件高级
1. 注册与解绑
传统的注册事件 on
// 后注册的会覆盖前面注册过的(唯一性)
var btn = document.querySelector('button');
btn.onclick = function() {
alert('这是什么')
}
btn.onclick = function() {
alert('这是2')
}
监听注册事件 addEventListener
// 可绑定多个事件
eventTarget.addEventListener(type, listener[, useCapture])
// type 事件 listener 事件处理函数 useCapture 可选参数
// attachEvent 只能ie9以前支持 要加on
btn.attachEvent('onclick', function() {
alert('123');
})
btn.attachEvent('onclick', function() {
alert('456');
})
解绑事件
// 绑定一次点击后移除
btn.addEventListener('click', fn)
function fn() {
alert('按钮被点击');
btn.removeEventListener('click', fn);
}
// 传统方式移除事件
btn.onclick = function() {
alert('按钮被电机');
btn.onclick = null;
}
// ie9以前支持
btn.attachEvent('onclick', fn);
function fn() {
alert('123');
btn.detachEvent('onclick', fn);
}
2. DOM事件流
捕获:事件监听从大到小,document -> html -> body -> div 逐渐下沉
冒泡:事件监听从小到大 div -> body -> html -> document 逐渐冒泡
注意:
- js代码中只能执行捕获或冒泡中的一个阶段
- onclick 与 attachEvent 只能得到冒泡阶段
- addEventListener(type, listener[, useCapture])第三个参数是true,表示捕获。不写默认为false,表示冒泡。
- 有些事件没有冒泡,如 onblur, onfocus, onmouseover, onmouseleave
// 事件冒泡 false可不写
var son = document.querySelector('.son');
son.addEventListener('click', function() {
console.log(1);
}, false);
var father = document.querySelector('.father');
father.addEventListener('click', function() {
console.log(2);
}, false);
// 事件捕获 true
var son = document.querySelector('.son');
son.addEventListener('click', function() {
console.log(1);
}, true);
var father = document.querySelector('.father');
father.addEventListener('click', function() {
console.log(2);
}, true);
事件对象
var btn = document.querySelector('button');
// event 即为事件对象 是个形参,可以任取 可以log相关的事件信息
btn.onclick = function(event) {
console.log(event);
}
// ie 678 特殊用法
window.event;
// this 与 e.target 的区别
var ul = document.querySelector('ul');
ul.addEventListener('click', function(e) {
// 绑定函数的对象
console.log(this);
// 专指点击事件的目标
console.log(e.target);
})
// 非标准的ie678
e.srcElement
// 阻止默认行为 防止跳转 或 不提交
a.addEventListener('click', function(e) {
e.preventDefault();
})
// 调试过好像没用
a.onclick = function(e) {
e.preventDefault();
// ie678 可用
e.returnValue;
// 兼容
return fales;
}
// 阻止冒泡
e.stopPropagation();
// 非标准
e.cancelBubble = true;
// 禁用右键菜单
document.addEventListener('contextmenu', function(e) {
e.preventDefault();
})
// 禁止选中文字
document.addEventListener('selectstart', function(e) {
e.preventDefault();
})
事件委托的原理:
不给每个子节点单独设置事件监听器,而是利用冒泡原理,在父节点上添加监听器。
ul.addEventListener('click', function(e) {
alert('弹出对话框');
e.target.style.backgroundColor = 'pink';
})
常用鼠标事件
document.addEventListener('click', function(e) {
// 相对于可视区的距离
console.log(e.clientX);
console.log(e.clientY);
console.log('----------------');
// 相对于整个页面
console.log(e.pageX);
console.log(e.pageY);
console.log('----------------');
// 获得与电脑屏幕边缘的距离
console.log(e.screenX);
console.log(e.screenY);
})
// 移动天使
var img = document.querySelector('img');
document.addEventListener('mousemove', function(e) {
var x = e.pageX;
var y = e.pageY;
img.style.top = y + 'px';
img.style.left = x + 'px';
})
键盘事件:
// 顺序依次 这是键盘按下事件 包括功能键
document.addEventListener('keydown', function(e) {
console.log(1);
})
// 这是键盘按下事件 不包括功能键
document.addEventListener('keypress', function(e) {
console.log(1);
})
// 鼠标弹起事件
document.addEventListener('keyup', function(e) {
console.log(1);
})
// 与 keydown 一样, 不区分大小写
document.addEventListener('keyup', function(e) {
console.log(e.keyCode);
})
// 区分大小写
document.addEventListener('keypress', function(e) {
console.log(e.keyCode);
})
BOM 相关
- 他是js访问浏览器窗口的一个接口。
- 他是一个全局对象,定义在全局作用域中的变量、函数都会变成window对象的属性和方法。
// 传统注册方式 页面加载完毕 只能注册一个
window.onload = function () {
}
// 监听器方式 可注册多个
window.addEventListener('load', function() {
})
// 仅当dom加载完成,不包括css、图片、flash等 ie9以上
document.addEventListener('DOMContentLoaded', function() {
})
// 浏览器尺寸变化时触发
window.addEventListener('resize', function(){
// 当前屏幕的宽度
console.log(window.innerWidth);
})
1. 定时器
window.setTimeout (调用函数, [延迟的毫秒数]);
// 延迟时间的单位是毫秒
setTimeout(function() {
alert('时间到了');
}, 2000);
// 可以通过函数名调用
setTimeout(boom, 2000);
function boom() {
alert('爆炸了');
}
// 不同的变量名区分定时器
var timer1 = setTimeout(function() {
console.log(1);
}, 2000);
var timer2 = setTimeout(function() {
console.log(2);
}, 3000);
// 定时器命名
var timer1 = setTimeout(function() {
alert('爆炸');
}, 5000);
var btn = document.querySelector('button');
btn.onclick = function() {
// 清除定时器的倒计时
clearTimeout(timer1);
}
setInterval(回调函数,[间隔的毫秒数]);
每隔一段时间调用一次函数。
// 不能带参数调用
setInterval(countDown, 1000);
// 关闭定时器,记得定义全局变量
var timer = null;
bt1.addEventListener('click', function() {
timer = setInterval(function() {
console.log(1);
}, 500);
})
bt2.addEventListener('click', function() {
clearInterval(timer);
})
this 指向问题
// this 指向问题 一般情况下this的最终指向的是那个调用它的对象
// 1. 全局作用域或者普通函数中this指向全局对象window( 注意定时器里面的this指向window)
console.log(this);
function fn() {
console.log(this);
}
window.fn();
window.setTimeout(function() {
console.log(this);
}, 1000);
// 2. 方法调用中谁调用this指向谁
var o = {
sayHi: function() {
console.log(this); // this指向的是 o 这个对象
}
}
o.sayHi();
var btn = document.querySelector('button');
btn.onclick = function() {
console.log(this); // this指向的是btn这个按钮对象
}
btn.addEventListener('click', function() {
console.log(this); // this指向的是btn这个按钮对象
})
// 3. 构造函数中this指向构造函数的实例
function Fun() {
console.log(this); // this 指向的是fun 实例对象
}
var fun = new Fun();
js 执行机制
js 是单线程的
为了解决这个问题,H5 提出 web worker 标准,允许 js 脚本创建多个线程,于是 js 出现了同步和异步
同步任务:都在主线上执行,形成一个执行栈
异步任务:通过回调函数实现
- 普通事件 如 click、resize 等
- 资源加载 如 load、error 等
- 定时器 报告 setInterval、setTimeout 等
js 执行机制:
- 先执行执行栈中的同步任务 。
- 异步任务放入任务队列。
- 一旦同步任务执行完成,就会按次序读取任务队列中的异步任务,进入执行栈,开始执行。
核心:异步进程处理
1. location、navigator、history
location 对象
location 对象属性 | 返回值 |
---|---|
location.href | 获取或者设置 整个URL |
location.host | 返回主机(域名) |
location.port | 返回端口号 没写则返回空 |
location.pathname | 返回路径 |
location.search | 返回参数 |
location.hash | 返回片段 #后面内容 常见于链接锚点 |
locatioin 对象的方法
location 对象的方法 | 返回值 |
---|---|
locaiton.assign() | 与href一样,可以跳转页面 |
locatioin.replace() | 替换当前页面,不记录历史 |
location.reload() | 重新加载页面,相当于刷新按钮或F5 如果参数为true 强制刷新ctrl+F5 (消除缓存) |
navigator 对象
包含有关浏览器的信息,有很多信息,最常用的是userAgent,该属性可以返回客户机发送服务器的user-agent头部的值。
history 对象
history 对象方法 | 作用 |
---|---|
back() | 可以后退功能 |
forward() | 前进功能 |
go(参数) | 1 是前进 -1 是后退 数值任意 |
2. offset、client、scroll
offset 偏移量 使用offset 系列相关属性可以动态的得到该元素的位置、大小
- 获得元素距带有定位的父元素的位置
- 获得元素自身的大小(宽度高度)
- 注意:返回的数值都不带单位
//获取带有定位的父元素 没有则返回body
console.log(son.offsetParent);
//返回 距 带有定位的 父元素 top,与 left
console.log(son.offsetTop);
//返回 自身元素 width 与 height 包含 border padding
console.log(son.offsetWidth);
console.log(son.offsetHeight);
offset 与 style 的区别
-
offset 可以获得任意样式表的样式值,style 只能获取行内样式
-
offset 是不带单位的数字,style 是带单位的字符串
-
offset 包含padding、border,style 不包含
-
offset 只读,style 能修改
总结:offset 读, style 写
/* transform: translate(-50%, -50%); */
/* transform 导致 offset 所量取得值与所得值不一致 */