JS 基础
js输入输出语句
方法 | 说明 | 归属 |
---|---|---|
alert(msg) | 浏览器弹出警示框 | 浏览器 |
console.log(msg) | 浏览器控制台打印输出信息 | 浏览器 |
prompt(info) | 浏览器弹出输入框,用户可以输入 | 浏览器 |
变量的使用
声明、赋值变量
var age; //声明一个名称为age的变量
age = 18;
console.log(age)
var age = 18;
数字型
+Infinity 无穷大 +Infinity 无穷小 +NaN非数字 +IsNaN()这个方法用来判断非数字,如果是数字返回false,如果不是数字返回true
字符串型String
字符串引号嵌套
JS可以用单引号嵌套双引号,或者用双引号嵌套单引号(外双内单,外单内双)
字符串转义字符
都是用\开头 但是这些转义字符都得写到引号里边
转义符 | 解释说明 |
---|---|
\n | 换行符,n是newline的意思 |
\\ | 斜杠\ |
\' | ' 单引号 |
\"" | "双引号 |
\t | tab缩进 |
\b | 空格 |
### 字符串长度 | |
length 属性 |
字符串拼接
字符串 + 任何类型 = 拼接之后的新字符串 ** +号总结口诀:数值相加,字符相连**
检测变量数据类型
typeof来检验
数据类型转换
转换为字符串
方式 | 说明 | 案例 |
---|---|---|
toString() | 转成字符串 | var num = 1;alert(num.toString()); |
String() 强制转换 | 转成字符串 | var num = 1;alert(String(num)); |
加号拼接字符串 | 和字符串拼接的结果都是字符串 | var num = 1;alert(num+"我是字符串") |
转换为数字型(重点)
方式 | 说明 | 案例 |
---|---|---|
parseInt(string)函数 | 将string类型转成整数数值型 | parseInt('78') |
parseFloat(string)函数 | 将string类型转成浮点数数值型 | parseFloat('78') |
Number()强制转换函数 | 将string类型转换为数值型 | Number(12) |
js隐式转换(- * /) | 利用算术隐式转换为数值型 | '12'-0 |
创建数组
利用new创建数组
var 数组名 = new Array(); var arr = new Array(); //创建一个空数组
利用数组字面量创建数组
var arr = [1,2,'pink',true]; //创建了一个空的数组
函数
函数形参和实参个数不匹配问题
参数个数 | 说明 |
---|---|
实参个数等于形参个数 | 输出正确结果 |
实参个数多余形参个数 | 只取到形参的个数 |
实参个数小于形参个数 | 多的形参定义undefined,结果为NaN |
匿名函数
函数表达式声明方式跟声明变量差不多,不过变量里面存的是值而函数表达式存的是函数 函数表达式也可以进行传递参数
var fun = function(){ console.log('我是函数表达式'); console.log(aru); } fun('pink');
作用域
1.就是代码名字在某个范围内起作用和效果 目的是为了提高程序的可靠性更重要的是减少命名冲突 2.js的作用域(es6)之前:全局作用域 局部作用域 3.全局作用域:整个script标签 或者是一个单独的js文件 4.局部作用域 在函数内部就是局部作用域 这个代码的名字只在函数内部起效果和作用
变量作用域
1.全局变量:在全局作用域下的变量 2.局部变量:在局部作用域下的变量 函数的形参也可以看做局部变量 3.从执行效率来看全局变量和局部变量 (1)全局变量只有浏览器关闭的时候才会销毁,比较占内存资源 (2)局部变量 当我们程序执行完毕就会销毁,比较节约内存资源
作用域链
内部函数访问外部函数的变量,采取的是链式查找的方式来决定取哪个值 这种结构我们称为作用域链(就近原则)
预解析
1.我们js引擎运行JS分为俩步:预解析和代码执行 (1)预解析 js引擎会把js 里面所有的var 还有function提升到当前作用域的最前面。 (2)代码执行 按照代码书写的顺序从上往下执行 2.预解析分为 变量预解析(变量提升) 和 函数预解析 (1)变量提升 就是把所有的变量声明提升到当前的作用域,不提升赋值操作 (2)函数提升 把所有的函数声明提升到当前作用域的最前面
Var a = b = c = 9; //相当于var a = 9;b = 9; c = 9;b和c直接赋值 没有var声明 当全局变量看 //集体声明 var a = 9,b = 9;c = 9;
面向对象
创建对象1
1.利用对象字面量创建对象{}
var obj = { uname:'张三丰', age:18, sex:'男', sayHi:function(){ console.log('hi~') } }
(1) 里面的属性或者方法我们采取键值对的形式 键 属性名 :值 属性值 (2) 多个属性或者方法中间用逗号隔开的
2.使用对象 (1)调用对象的属性 我们采用 对象名.属性名 . 我们理解为 的 console.log(obj.uname);
(2)调用属性还有一种方法 对象名['属性名'] console.log(obj['age']); (3) 调用对象的方法 sayHi 对象名.方法名 obj.sayHi();
创建对象2
1.利用 new Object 创建对象 var obj = new Object();
obj.uname = '张三疯';
obj.sayHi = function(){ console.log('hi~'); }
2.构造函数
function 构造函数名() { this.属性 = 值; this.方法 = function(){} } new 构造函数名();
function Star(uname,age,sex){ this.name = uname; this.age = age; this.sex = sex; } var ldh = new Star('刘德华',18,'男'); //调用函数返回的是一个对象
遍历对象属性
for...in语句用于对数组或者对象的属性进行循环操作。
for (var k in obj){ console.log(k);//k 变量 输出 得到的是 属性名 console.log(obj[k]);//obj[k] 得到是 属性值 } // 我们使用for in 里面的变量 我们喜欢写k 或者 key
内置对象
日期Date()
var date = new Date();
日期格式化
方法名 | 说明 | 代码 |
---|---|---|
getFullYear() | 获取当年 | dObj.getFullYear() |
getMonth() | 获取当月(0-11) | dObj.getMonth() |
getDate() | 获取当天日期 | dObj.getDate() |
getDay() | 获取星期几 | dObj.getDay() |
getHours() | 获取当前小时 | dObj.getHours() |
getMinutes() | 获取当前分钟 | dObj.getMinutes() |
getSeconds() | 获取当前秒钟 | dObj.getSeconds() |
数组的添加与删除
方法名 | 说明 | 返回值 |
---|---|---|
push(参数1....) | 末尾添加一个或多个元素,注意修改原数组 | 并返回新的长度 |
pop() | 删除数组最后一个元素,把数组长度减1无参数、修改原数组 | 返回它删除的元素的值 |
unshift(参数1....) | 向数组的开头添加一个或更多元素,注意修改原数组 | 并返回新的长度 |
shift() | 删除数组的第一个元素,数组长度减1无参数、修改原数组 | 并返回第一个元素的值 |
数组排序
方法名 | 说明 | 是否修改原数组 |
---|---|---|
reverse() | 颠倒数组中元素的顺序,无参数 | 该方法会改变原来的数组 返回新数组 |
sort() | 对数组的元素进行排序 | 该方法会改变原来的数组 返回新数组 |
冒泡排序
var arr1 = [13,4,77,1,7]; arr1.sort(function(a,b){ // return a - b; 升序的顺序排列 return b - a; }); console.log(arr1);
数组索引方法
方法名 | 说明 | 返回值 |
---|---|---|
indexOf() | 数组中查找给定元素的第一个索引 | 如果存在返回索引号 如果不存在,则返回-1. |
lastIndexOf() | 在数组中的最后一个的索引 | 如果存在返回索引号 如果不存在,则返回-1 |
数组去重
//封装一个去重的函数 function unique(arr){ var newArr = []; for(var i = 0;i < arr.length;i++){ if(newArr.indexOf(arr[i]) == -1){ newArr.push(arr[i]); } } return newArr; } var demo = unique(['blue','green','blue']); console.log(demo);
方法名 | 说明 | 返回值 |
---|---|---|
toString() | 把数组转换成字符串,逗号分隔每一项 | 返回一个字符串 |
join('分隔符') | 方法用于把数组中的所有元素转换为一个字符串 | 返回一个字符串 |
根据位置返回字符(重点)
方法名 | 说明 | 使用 |
---|---|---|
charAt(index) | 返回指定位置的字符(index字符串的索引号) | str.charAt(0) |
charCodeAt(index) | 获取指定位置处字符的ASCII码(index索引号) | str.charCodeAt(0) |
str[index] | 获取指定位置处字符 | charAt()等效 |
字符串操作方法(重点)
方法名 | 说明 |
---|---|
concat(str1,str2,str3...) | concat()方法用于连接俩个或多个字符串。拼接字符串,等效+,+更常用 |
substr(start,length) | 从start位置开始(索引号),length取的个数 |
slice(start,end) | 从start位置开始,截取到end位置,end取不到 |
substring(start,end) | 从start位置开始,截取到end位置,end取不到 基本和slice相同 但是不接受负值 |
web API
API(应用程序编程接口)
Web API 是浏览器提供的一套操作浏览器功能和页面元素的API(BOM和DOM)
DOM
DOM树
-
文档:一个页面就是一个文档,DOM中使用document表示
-
元素:页面中的所有标签都是元素,DOM中使用element表示
-
节点:网页中的所有内容都是节点(标签、属性、文本、注释等),DOM中使用node表示
获取元素
1.根据ID获取 使用getElementById()方法可以获取带有ID的元素对象 2.根据标签名获取 使用getElementsByTagName()方法可以返回带有指定标签的对象 集合 注意:
-
因为得到的是一个对象的集合,所以我们想要操作里面的元素就需要遍历
-
得到元素对象是动态的 还可以过去某个元素(父元素)内部所有指定标签名的子元素
element.getElementsByTagName('标签名');
注意:父元素必须是单个对象(必须指明是哪一个元素对象),获取的时候不包括父元素自己 3.通过HTML5新增的方法获取 (1)document.getElementsByClassName('类名');//根据类名返回元素对象集合
(2)document.querySelector('选择器');//根据指定选择器返回第一个元素对象
(3)document.querySelectorAll('选择器');
3.获取特殊元素(body,html) 获取body元素document.body //返回body元素对象
获取html元素document.documentElement //返回html元素对象
##事件基础
事件概述
1.事件是有三部分组成 事件源 事件类型 事件处理程序 (1)事件源 事件被触发的对象 谁 按钮 var btn = document.getElementById('btn');
(2)事件类型 如何触发 什么事件 比如鼠标点击(onclick) 鼠标经过 键盘按下 (3)事件处理程序 通过一个函数赋值的方式 完成
btn.onclick = function() { alert('点秋香'); }
执行事件的步骤
1.获取事件源 var div = document.querySelector('div');
2.注册事件 div.onclick
3.添加事件处理程序
div.onclick = function() { console.log('我被选中了'); }
操作元素
改变元素的内容
element.innerText
从起始位置到终止位置的内容,但它去除html标签,同时空格和换行也会去掉,不识别html标签
element.innerHTML
起始位置到终止位置的全部内容,包括html标签,同时保留空格和换行
表单元素的属性操作
'type、value、checked、selected、disabled'
样式属性操作
1.element.style 行内样式操作 2.element.className 类名样式操作 注意 1.JS里面的样式采取驼峰命名法 比如fontsize、backgroundColor 2.JS修改style样式操作,产生的是行内样式,css权重比较高
循环精灵图
// 1. 获取元素 所有的小li var lis = document.querySelectorAll('li'); for (var i = 0; i < lis.length; i++) { // 让索引号 乘以 44 就是每个li 的背景y坐标 index就是我们的y坐标 var index = i * 44; lis[i].style.backgroundPosition = '0 -' + index + 'px'; }
排他思想
1.所有元素全部清除样式(干掉其他人) 2.给当前元素设置样式(留下我自己) 3.注意顺序不能颠倒,首先干掉其他人,再设置自己
// 1. 获取所有按钮元素 var btns = document.getElementsByTagName('button'); // btns得到的是伪数组 里面的每一个元素 btns[i] for (var i = 0; i < btns.length; i++) { btns[i].onclick = function() { // (1) 我们先把所有的按钮背景颜色去掉 干掉所有人 for (var i = 0; i < btns.length; i++) { btns[i].style.backgroundColor = ''; } // (2) 然后才让当前的元素背景颜色为pink 留下我自己 this.style.backgroundColor = 'pink'; } }
表格隔行变色
1.鼠标经过事件 onmouseover 2.鼠标离开事件 onmouseout
表单全选和取消
自定义属性的操作
1.获取属性值
-
element.属性 获取属性值
-
element.getAttribute('属性') get得到获取 attribute 属性的意思 2.设置属性值
-
element.属性='值'
-
element.setAttribute('属性',值) 主要针对于自定义属性 3.移除属性
-
element.removeAttribute('属性');
tab栏切换(重点)
//获取元素 var tab_list = document.querySelector('.tab_list'); var lis = tab_list.querySelectorAll('li'); var items = document.querySelectorAll('.item'); //for循环绑定点击事件 for (var i = 0; i < lis.length; i++) { //开始给5个小li设置索引号 lis[i].setAttribute('index', i); lis[i].onclick = function() { //干掉所有人 其余的li清除 class 这个类 for (var i = 0; i < lis.length; i++) { lis[i].className = ''; } //留下我自己 this.className = 'current'; //2.下面显示内容 var index = this.getAttribute('index'); //干掉所有人 让其余的item 这些div隐藏 for (var i = 0; i < items.length; i++) { items[i].style.display = 'none'; } //留下我自己 items[index].style.display = 'block'; } }
H5自定义属性
1.设置H5自定义属性 h5规定自定义属性data-开头做为属性名并且赋值 <div data-index = "1"></div>
2.H5新增的获取自定义属性的方法 dataset 是一个集合里面存放了所有以data开头的自定义属性 console.log(div.dataset.index);
console.log(div.dataset.['index']);
节点操作
节点概述
一般地,节点至少拥有nodeType(节点类型)、nodeName(节点名称) 和nodeValue(节点值)这三个基本属性。
-
元素节点 nodeType 为 1
-
属性节点 nodeType 为 2
-
文本节点 nodeType 为 3
节点层级
1.父级节点 node.parentNode
//亲爸爸
2.子节点 parentNode.childNodes(标准);
//包含元素节点和文本节点 parentNode.firstChild
//第一个子节点 不管是文本节点还是元素节点 parentNode.lastChild
//最后一个子节点 parentNode.firstElementChild
//返回第一个子元素节点 parentNode.lastElementChild
//返回最后一个子元素节点
开发中的写法 console.log(ol.children[0]);
console.log(ol.children[ol.children.length -1]);
3.兄弟节点 node.nextSibling
//下一个兄弟节点,包括文本节点和元素节点 node.previousSibling
//上一个兄弟节点,包括文本节点和元素节点 node.nextElementSibling
//下一个兄弟元素节点 node.previousElementSibling
//上一个兄弟元素节点
创建节点
document.createElement('tagName');
添加节点
node.appendChild(child);
node父级 child是子级
var ul = document.querySelector('ul'); ul.appendChild(li);
node.insertBefore(child,指定元素)
删除节点
node.removeChild(child);
//删除子节点
###复制节点 node.cloneNode()
注意 1.如果括号参数为空或者false,则是浅拷贝,及只克隆节点本身,不克隆子节点 2.如果括号参数为空或true,则是深拷贝,及克隆节点本身,克隆子节点
var lili = ul.children[0].cloneNode();
三种动态创建元素区别
-
document.write()
-
element.innerHTML
-
doucument.createElement
区别: 1.document.write是直接将内容写入页面的内容流,但是文档执行完毕,则导致页面全部重绘 2.innerHTML是将内容写入某个DOM节点,不会导致页面全部重绘 3.innerHTML 创建多个元素效率更高,结构稍微复杂 4.createElement()创建多个元素效率稍微低一点点,但是结构更清晰
注册事件
传统注册方式
方法监听注册方式
-
addEventListener()它是一个方法
-
特点:同一个元素,同一个事件可以注册多个监听器 ###addEventListener 事件监听方式
eventTarget.addEventListener(type,listener[,useCapture])
+type:事件类型字符串,如click、mouseover,注意这里不要带on +listener:事件处理函数,事件发生时,会调用该监听函数 -
useCapture:可选参数,是一个布尔值,默认是false。
删除事件
删除事件方式
1.传统方式 eventTarget.onclick = null;
2.方法监听注册方式 eventTarget.removeEventListener(type,listener[,useCapture]);
##DOM事件流
##事件对象
什么是事件对象
eventTarget.onclick = function(event){} eventTarget.addEventListener('click',function(event{})) //这个event就是事件对象
e.target和this的区别
e.target点击了那个元素,就返回那个元素 this那个元素绑定了这个点击事件,那么就返回谁
var ul = document.querySelector('ul'); ul.addEventListener('click', function(e) { // 我们给ul 绑定了事件 那么this 就指向ul console.log(this); console.log(e.currentTarget); // e.target 指向我们点击的那个对象 谁触发了这个事件 我们点击的是li e.target 指向的就是li console.log(e.target); })
阻止事件冒泡
+e.stopPropagation() ;
-
e.cancelBubble = true;
事件委托
事件委托的原理 不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点 ##鼠标事件 1.禁用右键菜单
// 1. contextmenu 我们可以禁用右键菜单 document.addEventListener('contextmenu', function(e) { e.preventDefault(); })
2.禁止选择文字
// 2. 禁止选中文字 selectstart document.addEventListener('selectstart', function(e) { e.preventDefault(); })
3.获得鼠标坐标
// 鼠标事件对象 MouseEvent document.addEventListener('click', function(e) { // 1. client 鼠标在可视区的x和y坐标 console.log(e.clientX); console.log(e.clientY); console.log('---------------------'); // 2. page 鼠标在页面文档的x和y坐标 console.log(e.pageX); console.log(e.pageY); console.log('---------------------'); // 3. screen 鼠标在电脑屏幕的x和y坐标 console.log(e.screenX); console.log(e.screenY); })
常用的键盘事件
键盘事件 | 触发条件 |
---|---|
onkeyup | 某个键盘按键被松开触发 |
onkeydown | 某个键盘按键被按下时触发 |
onkeypress | 某个键盘按键被按下时触发 不能是不功能键 |
ocument.addEventListener('keyup', function(e) { console.log('up:' + e.keyCode); // 我们可以利用keycode返回的ASCII码值来判断用户按下了那个键
BOM
什么是BOM
BOM(Browser Object Model)及浏览器对象模型。它提供了独立于内容而与浏览器窗口进行交互的对象,其核心是window。
window对象的常见事件
窗口加载事件
window.onload = function(){} 或者 window.addEventListener("load",function(){}); // load 等页面内容全部加载完毕,包含页面dom元素 图片 flash css 等等
// DOMContentLoaded 是DOM 加载完毕,不包含图片 falsh css 等就可以执行 加载速度比 load更快一些
调整窗口大小事件
window.onresize = function(){} window.addEventListener("resize",function(){});
注意: 1.只要窗口大小发生像素变化,就会触发这事件。 2.我们经常利用这个事件完成响应式布局。window.innerWidth当前屏幕宽度
定时器
俩种定时器
-
setTimeout()
-
setInterval()
setTimeout()定时器
-
这个window在调用的时候可以省略
-
这个延时时间单位是毫秒 但是可以省略,如果省略默认的是0
-
这个调用函数可以直接写函数 还可以写 函数名 还有一个写法 '函数名()'
-
页面中可能有很多的定时器,我们经常给定时器加标识符 (名字)
window.setTimeout(调用函数,[延迟毫秒数]);
setTimeout()这个调用函数我们也称为回调函数 callback
停止setTimeout()定时器
window.clearTimeout(timeoutID)
setInterval()定时器
window.setInterval(回调函数,[间隔的毫秒数]);
区别:1. setTimeout 延时时间到了,就去调用这个回调函数,只调用一次 就结束了这个定时器
-
setInterval 每隔这个延时时间,就去调用这个回调函数,会调用很多次,重复调用这个函数
停止 setInterval()定时器
window.clearInterval(timeoutID)
this的指向问题
1.全局作用域或者普通函数中this指向全局对象window 2.方法调用中谁调用this指向谁 3.构造函数中this指向构造函数的实例
JS执行机制
js是单线程
###同步和异步
##location对象
URL
统一资源定位符是互联网上标准资源地址。
location对象属性
JavaScript Window Location
location对象方法
location对象方法 | 返回值 |
---|---|
location.assign() | 跟href一样,可以跳转页面 |
location.replace() | 替换当前页面,因为不记录历史,所以不能后退页面 |
location.reload() | 重新加载页面,相当于刷新按钮,true强制刷新 |
##navigator对象 ##history对象
history对象方法 | 作用 |
---|---|
back() | 可以后退功能 |
forward() | 前进功能 |
go | 前进后退功能,参数如果是1前进,如果是-1后退 |
##元素偏移量offset系列
offset概述
// 1.可以得到元素的偏移 位置 返回的不带单位的数值 console.log(father.offsetTop); console.log(father.offsetLeft); // 它以带有定位的父亲为准 如果么有父亲或者父亲没有定位 则以 body 为准 console.log(son.offsetLeft); var w = document.querySelector('.w'); // 2.可以得到元素的大小 宽度和高度 是包含padding + border + width console.log(w.offsetWidth); console.log(w.offsetHeight); // 3. 返回带有定位的父亲 否则返回的是body console.log(son.offsetParent); // 返回带有定位的父亲 否则返回的是body console.log(son.parentNode); //
立即执行函数
//(function(){})() 或者 (function(){}()); (function(a,b){ console.log(a + b); })(1,2) //第二个小括号可以看做是调用函数
元素滚动scroll
scroll得到的是内容的实际大小 元素被卷去的头部是element.scrollTop,如果页面被卷去的头部则是 window.pageYOffset
三大系列总结
三大系列大小对比 | 作用 |
---|---|
element.offsetWidth | 返回自身包括padding、边框、内容的宽度、返回数值不带单位 |
element.clientWidth | 返回自身包括padding、内容区的宽度,不含边框,返回数值不带单位 |
element.scrollWidth | 返回自身实际宽度,不含边框,返回数值不带单位 |
mouseenter和mouseover的区别
mouseenter 鼠标事件
-
当鼠标移动到元素上就会触发mouseenter事件 +mouseover鼠标经过自身盒子会触发,经过子盒子还会触发。mouseenter只会经过自身盒子触发 +mouseenter鼠标离开mouselenve
##动画函数封装 注意:动画必须先加定位
动画原理
var div = document.querySelector('div'); var timer = setInterval(function() { if (div.offsetLeft >= 400) { //停止动画 clearInterval(timer); } div.style.left = div.offsetLeft + 1 + 'px'; }, 30);
动画效果简单封装
//动画中必须加定位 //obj目标对象 target目标位置 //给不同的元素指定不同的定时器 function animate(obj, target) { //当我们不断点击按钮,速度越来越快,开启太多计时器 //解决方案,让元素只有一个定时器执行 clearInterval(obj.timer); obj.timer = setInterval(function() { if (obj.offsetLeft >= target) { //停止动画 clearInterval(obj.timer); } obj.style.left = obj.offsetLeft + 1 + 'px'; }, 30); }
缓动动画
function animate(obj, target) { //当我们不断点击按钮,速度越来越快,开启太多计时器 //解决方案,让元素只有一个定时器执行 clearInterval(obj.timer); obj.timer = setInterval(function() { // var step = Math.ceil((target - obj.offsetLeft) / 10); var step = (target - obj.offsetLeft) / 10; step > 0 ? Math.ceil(step) : Math.floor(step); if (obj.offsetLeft == target) { //停止动画 clearInterval(obj.timer); } //把每次加1 这个步值改为一个慢慢变小的值 步长公式:(目标值 - 现在的位置)/10 obj.style.left = obj.offsetLeft + step + 'px'; }, 30); }