JavaScript(完整)
本文件已定稿,最后修改时间 20240613 1:41
1、什么是JavaScript
“弱类型”的脚本语言
基于”原型”的脚本语言
2、JavaScript的构成
ECMAScript:核心语法、基本对象
DOM:文档对象模型
BOM:浏览器对象模型
3、JavaScript的输出语句
document.write()
在文档中打印内容 ,要用引号包起来
console.log()
在控制台打印内容
4、如何延迟加载js:defer
<script type="text/javascript" defer src='路径'></script> |
defer:js脚本可以延迟到文档完全被解析和显示之后执行
5、如何异步加载js:async
<script type="text/javascript" async src='路径'></script> |
async:立即执行脚本,但不妨碍页面其他的操作
简单粗暴:谁加载完了谁执行
6、js中的变量
命名规则:
- 首位:字母、下划线、$
- 严格区分大小写
- 采用驼峰命名(第二个单词开始之后每一个单词首字母开头大写)
- 声明变量:
var
注释:
公共的js文件
/**
*文件用途说明
*作者姓名、联系方式
*制作日期
**/大的模块注释方法
//====================
// 代码用途
//====================
7、规范
- 单引号优先(如果不是引号嵌套,不要用双引号)
- 变量命名:
- str、num、bol、obj、fun、arr:作用域不大的情况
- 循环 i、j、k
一、数据类型
基本数据类型
string
:字符串,基本上加入引号的都是字符串类型number
:数值boolean
:布尔undefined
:未定义,表示缺少值,应该有一个值,但是还没有赋值null
:表示没有对象,即该处不应该有值,特殊的object区别
null
表示无对象,把他转化成数值是0underfined
表示”缺少值”,把他转换数值是NaN引用数据类型【array、function】
object
二、数据类型的转换
其他类型转【字符串类型】
数据.toString()
String(数据)
其他类型转【数值类型】
Number(数据)
parseInt(数据)
=> 整数parseInt(数据)
=> 小数字符串不是纯数字的都是NaN
NaN【数值类型】:属性,代表非数字值得特殊值
其他类型转【布尔类型】
Boolean(数据)
数值:0—false、NaN—false、其他值—true、
字符串:非空字符串—true、空字符串—false
null—false、underfined—false
三、变量的存储机制和原理
内存生命周期(三个周期)
- 分配器:分配所需内存
- 使用期:读、写
- 释放期:不需要时将其释放
JavaScript内存的生命周期
- 内存分配:分配所需要的暂时使用的内存大小
- 内存使用:读、写内存
- 内存回收:对于不需要使用的内存将其释放
栈内存、堆内存
- 栈内存:
- 基本类型(string、number、boolean、undefined、null)
- 按值访问
- 存储大小固定
- 系统会自动分配内存空间
- 空间小,运行效率高
- 先进后出
- 堆内存:
- 引用类型(object)
- 按引用访问
- 存储大小不固定
- 由代码进行指定分配
- 孔金阿达、运行效率相对较低
- 无需存储(根据引用直接获取)
- 栈内存:
四、数据类型隐式转换
- 布尔和数字或者纯布尔相加(+),布尔会自动转换成数值类型
- 字符串和任何类型(+),其他类型都会转换成字符串
五、函数
区别:
函数表达式:函数只能在声明之后调用,因为这种方式的函数,是在函数运行的阶段赋值给变量的
函数声明:函数可以在声明函数的作用域任意范围内调用,因为这种方式,是在函数解析阶段赋值给函数名
- 函数如果没有调用,则不会保存在内存中
- 当函数调用完毕,其中函数的代码就会被系统内存回收
函数的参数
function fun(形参1,形参2,形参3...){
}
fun(实参1,实参2,实参3...)arguments对象
作用:就是操作实参
arguments.length
就是实参的个数【长度】匿名函数【没有名字的函数】
匿名函数立即执行
(function(){
})匿名函数的自我执行
(function(形参1,形参2...){
})(实参1,实参2...)
六、Js执行环境
什么是执行环境
执行环境又被称为:执行上下文
执行环境定义了变量或者函数有权或无权访问其他数据,决定了各自的行为
执行分类(3大类)
- 全局执行环境
- 是最外围的执行环境、在页面中,全局执行环境就是window对象
- 当一打开页面,会自动生成window对象,那么全局的变量或者函数都属于window对象的内容。那么window就是全局的。
- 回收机制:
- 某个执行环境中的所有代码执行完毕,保存在执行环境中的变量或者函数都会进行销毁(回收)
- 但是全局执行环境是到关闭浏览器或者当前页面才会被回收
- 函数的执行环境
- 当某个函数被调用时,首先会创建一个执行环境以及作用域链,然后使用arguments和其他参数来初始化这个执行环境
- 全局执行环境
执行环境的生命周期
创建阶段
- 生成变量对象
- 建立作用域链
- 确定this指向
执行阶段
- 变量赋值
- 函数调用
- 执行其他代码
销毁阶段
// 第一次页面加载创建全局执行环境
// 先到创建阶段---->扫描全局的变量以及函数
// 扫描结果是num = undefined
// 执行阶段再运行赋值
console.log(num)
var num = 10;
七、BOM
浏览器对象模型
围绕 ”浏览器“ 的一些操作
BOM可以:
- 获取到浏览器的型号(手机型号)
- url操作
- 屏幕的大小尺寸
location对象:操作浏览器当前的url
href:本身是可以获取到当前的url、设置对应跳转的url
localtion.href = 'url'
是在本页面进行的跳转,不是新窗口打开window.open(url,'_blank')
可以在新窗口打开<script>
btn.onclick = function(){
location.href = 'http:///www.xuexiluxian.cn';
}
</script><body>
<input type="text" id='userName'/>
<input type="password" id='userPwd'/>
<input type="button" value='登录' id='login'/>
</body>
<script>
login.onclick = function(){
var uName = userName.value;
var uPwd = userPwd.value;
if(uName=='admin' && uPws=='admin'){
location.href='home.html';
// window.open(url,'_blank');
}else{
alert('用户名或密码不正确');
}
}
</script>search:设置或者获取,从问号(?),开始的url
解码
decodeURIComponent
中文字体乱码,需要解码<script>
document.title = decodeURIComponent(location.search);
</script>hash:设置或者获取,从井号(#),开始的url
history:操作浏览器窗口访问过的url
back:返回上一页
// home.html
<body>
<ul>
<li id='js'>js</li>
</ul>
</body>
<script>
js.onclick = function(){
loaction.href = 'list.html';
}
</script>// list.html
<body>
<div id='oReturn'> < </div>
</body>
<script>
oReturn.onclick = function(){
history.back();
}
</script>forward:前进下一页
go:前往指定的页面
go(-1)
:返回上一页 backgo(1)
:前进下一页 forwardgo(0)
:刷新
navigator:包含有关浏览器的信息
userAgent:用户代理头的值、用的什么浏览器
platform:返回运行浏览器的操作系统
screen:客户端屏幕信息
- width:返回显示的屏幕宽度
- height:返回屏幕的高度
八、定时器
setInterval:间歇调用,”后”,将定时任务处理的函数添加到执行队列到队尾
语法格式:
setInterval(执行匿名函数,毫秒数)
setTimeout:超时调用,”后”,将定时任务处理的函数添加到执行队列到队尾
语法格式:
setTimeout(执行匿名函数,毫秒数)
清除定时器
clearInterval
——-setInterval
clearTimeout
———setTimeout
语法格式:
clearInterval(清楚哪一个定时器)
clearTimeout(清楚哪一个定时器)
九、js的单线程
同一时间只能做一件时间,这也就意味着所有的任务需要排队,前一个任务执行结束了,才可以继续执行下一个任务
js语言为什么是单线程
取决于用在什么地方、用户体验
事件队列(定时器、ajax…):先进先出
先执行主线程,再执行事件队列
获取id:document.getElementById('id值')
获取集合元素:document.getElementsByTagName('元素名称')
十、数组
什么是数组
使用单独的变量名来存储”一系列”的值
数组可以
存储一系列(大量)的值
使用数组
如何创建数组
构造函数形式:
new Array('字符串',数值,布尔)
、如果只有一个参数,这个参数就是数组的长度【只限数值】字面量:
['字符串',数值,布尔]
数组是一个对象、存储在堆内存中
- 数组属性:长度length
十一、数组方法
concat()
:合并数组,最后返回一个新的数组数组.方法名称(参数)
var arr = ['a','b','c'];
var brr = ['1','2','3'];
arr.concat(brr);reverse()
:反转数组的顺序,会改变原来的数组join('分隔符')
:将数组转换成字符串将数组的元素组成一个字符串,用参数分隔符进行分割,默认以逗号分隔
push()
:将参数添加到原数组的末尾,并且返回数组的长度unshift()
:将参数添加到原数组开头,并且返回数组的长度pop()
:数组末尾移除最后一项,返回移除的项shift()
:删除原数组第一项,返回移除的项slice(开始位置,结束位置)
:截取,返回新数组一个参数(正数):从当前下标(包括下标)开始往后截取
两个参数(正数):从开始位置(包括开始位置)到结束位置(不包括结束位置)
sort()
:按升序排列数组项sort(function(a,b){
return a-b; // 从小到大
return b-a; // 从大到小
})indexOf(参数)
:查找,查找参数在数组中是否存在如果存在返回下标
如果不存在返回-1
splice()
:可以实现删除、插入、替换操作删除:2个参数,(1,2)从下标1开始,删除2个
替换:3个参数,(0,1,4)从下标0开始,长度为1的数组元素替换成4
插入:3个参数,(1,0,5)表示下标为1处添加一项5
十二、循环遍历数组
forEach
语法格式:
数组.forEach(function(item,index){
// item:数组每一项
// index:数组的下标
})缺点:不可以使用break和return
map
:里面支持return,并且返回新的数组var arr = ['a','b','c'];
/*
var brr = [];
for(var i=0;i<arr.length;i++){
brr.push(arr[i]+'0');
}
console.log(brr);
*/
var brr = arr.map(function(item,index){
return item+'0';
})
console.log(brr);filter
:过滤,并且返回新的数组var arr = [18,19,20,22,25,33,26];
/*
var brr = [];
for(var i=0;i<arr.length;i++){
if(arr[i]>20){
brr.push(arr[i]);
}
}
console.log(brr);
*/
var brr = arr.filter(function(item,index){
return item>20;
})
console.log(brr);every
:所有为true,返回truesome
:只要有一项为true,返回true
十三、字符串
区别
- 字面量形式存储在栈内存,构造函数形式存储在堆内存
typeof
字面量返回 stringtypeof
构造函数返回 object
- 为什么字面量的string、boolean、number也有属性和方法
- string、boolean、number:原始的资料类型
- new String、new Number、new Boolean:包装对象
- 原始的资料类型向包装对象借用
字符串方法
charAt(数值)
:返回指定”位置”的字符var str = 'abcdef';
console.log(str[1]);
console.log(str.chatAt(1));indexOf(字符)
:查找,有返回下标,没有返回-1replace(把什么,替换成什么)
:替换、只替换一处,并不是全部替换全部替换:
str.replace(/字符/g,'替换的内容');
trim()
:去除前后空格toLowerCase()
:把字符转换成小写toUpperCase()
:把字符转换成大写split()
:把字符串转换成数组join()
:把数组转换成字符串
字符串截取
slice(start,end)
substring(start,end)
负数转换成0substr(start,length)
:start为开始位置,length为长度
上传文件判断后缀名
btn.onclick = function(){ |
手机号中4位隐藏
<body> |
var tel = document.getElementById('tel'); |
十四、Math(数学)对象
取最大
Math.max()
取最小值
Math.min()
四舍五入
Math.round()
返回数的绝对值
Math.abs()
返回数的平方根
Mmath.sqrt()`
向下取整
Math.floor()
向上取整
Math.ceil()
返回随机数
Math.random()
随机的公式:
- 不包含最大值,包含最小值
Math.floor(Math.random() * (max - min))+min
- 包含最大值,包含最小值
Math.floor(Math.random() * (max - min + 1))+min
- 不包含最大值,包含最小值
随机验证码
<div> |
// 点击验证码可以切换 |
十五、日期对象【new Date()】
日期对象的方法
对象.getFullYear()
年对象.getMonth()
月对象.getDate()
日对象.getHours()
时对象.getMinutes()
分对象.getSeconds()
秒var date = new Date();
date.getSeconds();
时间戳
从1970年1月1日至今的时间(毫秒)
对象.getTime()
京东秒杀
<div> |
var hour = document.getElementById('hour'); |
十六、DOM
document object model:文档对象模型
获取文档节点【元素】的方法
获取id:
document.getElementById('main')
获取标签名:
document.getElementsByTagName('li')
获取到的是集合元素获取class名:
document.getElementsByClassName('class')
获取到的是集合元素通过选择器来获取一个节点:
document.querySelector()
通过选择器来获取所有节点:
document.querySelectorAll()
<div id='main' class='container'>
我是main
</div>console.log(document.querySelectorAll('#main')[0]);
console.log(document.querySelectorAll('.container');
节点属性
innerHTML
、innerText
:给节点添加内容innerText
解析不了html标签nodeName
:返回节点名称、用来做判断使用、返回大写字母firstElementChild
:获取到第一个子元素节点lastElememtChild
:获取到最后一个子元素节点parentNode
:获取到父节点
节点方法(操作节点属性的方法)
- 获取:
节点对象.getAttribute('属性名称')
:返回对应属性名称的值 - 设置:
节点对象.setAttribute('属性名称',‘对应的值)
- 删除:
节点.removeAttribute('属性名称')
- 获取:
创建节点
document.createElement('节点名称')
添加节点
追加
父节点.appendChild(子节点)
前置
父节点.insertBefore(添加的子节点,添加到谁前面)
var add = document.getElementById('add');
var uls = document.getElementById('uls');
add.onclick = function(){
// 创建li节点
var newLi = document.createElement('li');
var liLen = document.getElementByTagName('li').length;
newLi.innerText = liLen;
// 添加节点->追加
uls.appendChild(newLi);
// 添加节点->前置
uls.insertBefore(newLi,document.getElementsByTagName('li')[0]);
}
删除节点
父节点.removeChild(子节点)
<div>
<ul>
<li>
1111
<a href="javascript:;">删除</a>
</li>
<li>
2222
<a href="javascript:;">删除</a>
</li>
<li>
3333
<a href="javascript:;">删除</a>
</li>
<li>
4444
<a href="javascript:;">删除</a>
</li>
<li>
5555
<a href="javascript:;">删除</a>
</li>
</ul>
</div>var uls = document.getElementById('uls');
var oA = document.getElementsByTagName('a');
var oAlen = oA.length
for(var i = 0;i<oAlen;i++){
oA[i].onclick = function(){
uls.removeChild(this.parentNode);
}
}获取样式表中的样式
语法格式:
getComputedStyle(节点,null).样式名称
获取元素的大小和偏移位置
- 大小:
- 计算width+padding+border、没有px单位,返回的是数值类型
节点对象.offsetWidth
节点对象.offsetHeight
- 计算width+padding、没有px单位,返回的是数值类型
节点对象.clientWidth
节点对象.clientHeight
- 计算width+padding+border、没有px单位,返回的是数值类型
- 偏移值:
节点对象.offsetLeft
(从左到右)节点对象.offsetTop
(从上到下)- 如果节点没有定位的情况下:相对整个文档偏移
- 如果节点有定位的情况下:相对于父节点偏移
- 大小:
滚动距离
节点对象.scrollLeft
节点对象.scrollTop
回到顶部
<head>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
.is-fx{
position: fixed;
bottom;0px;
top: 50px;
width: 150px;
height: 150px;
background: red;
text-align: center;
line-height: 150px;
}
</style>
</head>
<body style='height: 5000px;'>
<div id='isFx' class='is-fx'>
回到顶部
</div>
</body>
<script>
var isFx = document.getElementById('isFx');
isFx.onclick = function(){
document.documentElement.scrollTop = 0;
}
</script>
十七、事件
- 什么是事件:事件指可以被JavaScript检测到的行为
- 事情的起因
- 都有哪些事件
- 即鼠标点击、页面或图像载入、鼠标悬浮于页面的某个热点之上、在表单中选取输入框、确认表单、键盘按键等操作。
- 事件在什么时候执行
- 事件通常与函数配合使用,当事件发生时函数才会执行
事件流
事件执行的顺序
- 历史原因:早期的IE事件传播方向为由上至下,即从document逐级向下传播到目标元素;而Netscape公司则是朝相反的方向传播,也就是从目标元素开始向上逐级传播最终至window后来ECMAScript在DOM2中对事件流进行了进一步规范,基本上就是两者的结合。
- 当事件发生时,最先得到通知的是window,然后是document,由上至下逐级依次而入,直到真正触发事件的那个元素(目标元素)为止,这个过程就是捕获。
- 接下来,事件会从目标元素开始起泡,由下至上逐级依次传播,直到window对象为止,这个过程就是冒泡,所以捕获比冒泡先执行。
- 事件流分为两种:事件捕获、事件冒泡
- 事件捕获:是从window开始向下传播,一直目标节点
- 事件冒泡:是从目标节点开始向上传播,一直到window
- 历史原因:早期的IE事件传播方向为由上至下,即从document逐级向下传播到目标元素;而Netscape公司则是朝相反的方向传播,也就是从目标元素开始向上逐级传播最终至window后来ECMAScript在DOM2中对事件流进行了进一步规范,基本上就是两者的结合。
鼠标类事件
onclick
单击事件ondblclick
双击事件oncontextmenu
右击事件、要return false
屏蔽右击
document.oncontextmenu = function(){
return false;
}onmousedown
鼠标按下、在拖拽的时候会用到onmouseup
鼠标释放、在拖拽的时候会用到onmouseover
鼠标经过onmouseout
鼠标离开onmousemove
鼠标悬浮、放大镜效果
键盘类事件
onkeydown
键盘按下onkeyup
键盘按下通过keyCode获得键值
e.keyCode
txt.onkeydown = function(e){
if(e.keyCode == 13){
var lis = document.createElement('li');
lis.innerHTML = txt.value;
uls.appendChild(lis);
txt.value = '';
}
}
其他类事件
onload
加载完毕后立即执行的操作window.onload
网页加载完毕后onfocus
获取焦点onblur
失去焦点onscroll
滚动条事件onchange
内容改变时触发
事件处理程序-添加
HTML事件处理程序 :把事件直接写在节点上
<div onclick='alert(1)'>
我是一个div
</div><div onclick='fNum(20,5)'>
我是一个div
</div>
<script>
function fNum(num1,num2){
alert(num1 + num2);
}
</script>缺点:代码耦合
DOM 0级事件处理程序:
main.onclick = function(){}
缺点:同样元素的同样事件会被覆盖
DOM 2级事件处理程序:
dom对象.addEventListener(事件名称,函数,false|true)
注:事件名称:不需要加入on
false:冒泡
true:捕获
事件处理程序-删除
DOM 0级删除事件
dom对象.事件名称 = null
DOM 2级删除事件
dom对象.remove EventListener(事件名称,函数,false|true)
注:要使用一个内存的
function fn(){
alert('2级')
}
main.addEventListener('click',fn,false)
main.removeEventListener('click',fn,false)
事件对象-事件委托
事件对象:e
mian.onclick = function(e){
console.log(e);
}事件对象的属性
事件对象.target
:目标,返回对应的dom对象clientX
: 当前鼠标的位置距离浏览器左侧的距离clientY
: 当前鼠标的位置距离浏览器顶部的距离
事件委托
优点:性能好、即使后添加的内容也有效
// 无事件委托
var lis = document.getElementById('lis');
var liLen = lis.length;
for(var i=0;i<liLen;i++){
lis[i].onclick = function(){
this.style.background = 'red';
}
}
var btn = document.getElementById('btn');
btn.onclick = function(){
var newLi = document.createElement('li');
newLi.innerHTML = '后添加的';
uls.appendChild(newLi);
}// 有事件委托
var btn = document.getElementById('btn');
var uls = document.getElementById('uls');
btn.onclick = function(){
var newLi = document.createElement('li');
newLi.innerHTML = '后添加的';
uls.appendChild(newLi);
}
uls.onclick = function(e){
if(e.target.nodeName == 'LI'){
e.target.style.background = 'red'
}
}
阻止冒泡-阻止默认行为
阻止事件冒泡
事件对象.stopPropagation()
阻止默认行为
事件对象.preventDefault()
案例:拖拽
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.drag {
position: absolute;
width: 100px;
height: 100px;
background: pink;
border-radius: 20px;
cursor: pointer;
}
</style>
</head>
<body>
<div id="drag" class="drag"></div>
</body>
<script>
// 三个事件
// 鼠标按下:onmousedown
// 鼠标移动:onmouseover|onmousemove
// 鼠标方式:onmouseup
var drag = document.getElementById('drag');
drag.onmousedown = function (e) {
// 按下时候鼠标位置距离浏览器左侧的距离 - 盒子左侧距离浏览器的位置
var x = e.clientX - drag.offsetLeft;
// 按下时候鼠标位置距离浏览器顶部的距离 - 盒子顶部距离浏览器的位置
var y = e.clientY - drag.offsetTop;
document.onmousemove = function (e) {
// 鼠标距离浏览器左侧的距离值
var l = e.clientX - x;
// 鼠标距离浏览器顶部的距离值
var t = e.clientY - y;
if (l < 0) {
l = 0;
}else if (l > document.documentElement.clientWidth - drag.offsetWidth) {
l = document.documentElement.clientWidth - drag.offsetWidth
}
if (t < 0) {
t = 0;
}else if (t > document.documentElement.clientHeight - drag.offsetHeight) {
t = document.documentElement.clientHeight - drag.offsetHeight
}
drag.style.left = l + 'px';
drag.style.top = t + 'px';
}
}
drag.onmouseup = function () {
document.onmousemove = null;
}
</script>
</html>案例:放大镜
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>放大镜</title>
<style>
* {
margin: 0;
padding: 0;
}
.u-l {
float: left;
}
.mian {
margin: 150px;
}
.s-img {
position: relative;
width: 400px;
height: 400px;
}
.s-img img {
width: 100%;
height: 100%;
}
.s-img span {
display: none;
position: absolute;
left: 0;
top: 0;
width: 200px;
height: 200px;
background: #fff;
opacity: 0.5;
}
.p-img {
position: relative;
display: none;
margin-left: 30px;
width: 400px;
height: 400px;
overflow: hidden;
}
.p-img img {
position: absolute;
left: 0;
top: 0;
}
</style>
</head>
<body>
<div class="main" id="main">
<!-- 小图 -->
<div class="s-img u-l" id="sImg">
<img src="images/400.jpg" alt="">
<span class="lens" id="lens"></span>
</div>
<!-- 大图 -->
<div class="p-img u-l" id="pImg">
<img src="images/800.jpg" alt="" id="picImg">
</div>
</div>
</body>
<script>
// 小盒子
var sImg = document.getElementById('sImg');
// 阴影
var lens = document.getElementById('lens');
// 大盒子
var pImg = document.getElementById('pImg');
// main节点
var main = document.getElementById('main');
// 大图片
var picImg = document.getElementById('picImg');
// 给小盒子加入鼠标移入事件,让阴影和大盒子显示
sImg.onmouseover = function () {
lens.style.display = 'block';
pImg.style.display = 'block';
}
sImg.onmousemove = function (e) {
// 当前鼠标的位置 - 盒子距离浏览器左侧的偏移 - 阴影宽度的一半
var x = e.clientX - main.offsetLeft - lens.offsetWidth / 2;
var y = e.clientY - main.offsetTop - lens.offsetHeight / 2;
if (x < 0) {
x = 0;
} else if (x > sImg.offsetWidth - lens.offsetWidth) {
x = sImg.offsetWidth - lens.offsetWidth
}
if (y < 0) {
y = 0;
} else if (y > sImg.offsetHeight - lens.offsetHeight) {
y = sImg.offsetHeight - lens.offsetHeight
}
// 阴影位置
lens.style.left = x + 'px';
lens.style.top = y + 'px';
// 大图片位置
picImg.style.left = -x * 2 + 'px';
picImg.style.top = -y * 2 + 'px';
}
sImg.onmouseout = function () {
lens.style.display = 'none';
pImg.style.display = 'none';
}
</script>
</html>
十八、正则表达式
什么是正则表达式
规则表达式
正则的使用
定义
字面量://
构造函数:
new RegExp()
区别
new RegEep()
放入变量
正则的方法
test()
:检测一个内容是否与正则匹配如果匹配返回true
如果不匹配返回false
exec()
:检测一个内容是否与正则匹配如果匹配返回数组
如果不匹配返回null
元字符
元字符 含义 [] 匹配中括号内的任意一个字符、验证手机号 [abc]
[^] 除了中括号内任意字符、 [^abc]
[0-9] 匹配数字0-9范围的 [a-z] [A-Z] [a-zA-Z] \d 匹配数字[0-9] \D 匹配非数字 \w 匹配数字、字母、下划线 [a-zA-Z0-9_]
\W 匹配非数字、字母、下划线 \s 匹配空格 \S 匹配非空格 \b 匹配边界 \B 匹配非边界 . 匹配除了换行符以外的任意字符 转义(\)
/\./
失去原有功能选择符
|:或
修饰符
修饰符 含义 i 不区分大小写 /[a-z]/i
=/[a-zA-Z]/
g 全文匹配 m(不常用) var reg = /菜B|大爷/g;
if(reg.test(val)){
val = val.replace(reg,'*');
}字符串方法可以配合正则去用
replace
match:类似于exec、查找返回对应的值【值是数组】、没有找到返回null、支持全局
限定符
^ 开始
$ 结束
验证手机号的时候:11位数字
// 以数字1开头
var reg1 = /^1/;
// 以数字1开始,以数字结束
// 数字1后面必须是一位的数字
var str1 = /^1\d$/;重复
符号 含义 {n} 重复n次 {n,} 重复最少n次、最多不限 {n,m} 重复最少n次、最多m次 * 重复最少0次、最多不限 + 重复最好1次、最多不限 ? 重复最好0次、最多1次 贪婪模式
var reg1 = /\d{3,6}/g;
var str1 = '123456789';
console.log(str1.replace(reg1,'*'));
// ******789非贪婪模式(懒惰模式)
var reg1 = /\d{3,6}?/g;
var str1 = '123456789';
console.log(str1.replace(reg1,'*'));
// ***456789分组
() 把部分内容组合在一起
字符类:来获取分组
$1 第一个分组
$2 第二个分组
$3 第三个分组
…
前瞻 和 后顾
js正则没有后顾
正向前瞻:(?=):匹配符合的
// 看一看 \d(数字)后面的是不是字母,是字母匹配到
var reg1 = /\d(?=[a-z])/g;
var str1 = '1a2b*%3cdddd5';
console.log(str1.replace(reg1,'*'));
// *a*b*%*cdddd5/(?=.*\d)/
开始字符后必须是数字负向前瞻:(?!):匹配不符合的
// 看一看 \d不是字母,可以匹配到
var reg1 = /\d(?![a-z])/g;
var str1 = '1a2b*%3cdddd5';
console.log(str1.replace(reg1,'*'));
// 1a2b*%3cdddd*
案例:验证表单
|
案例:验证表单+验证码
|
案例:手机号钝点
|
十九、作用域
作用域
作用的区域或者作用的范围
全局作用域,全局就是window
在全局作用域下写的变量:没有区别,都属于window对象的属性
var str1 = '123’;
window.str2 = '123';
str3 = '123';在局部作用写变量
// 声明局部变量
var str1 = '123’;
// 声明全局变量
window.str2 = '123';
// 声明全局变量
str3 = '123';作用域链
从内部向外链:从当前作用域开始找,如果找不到向外作用域找,当找到返回,
悬挂变量声明(变量提升)
解释:js提升所有的变量声明,将他们移到其作用域的开头
顺序、优先级
变量 > 函数 > 参数 > 变量提升
function c() {
var b = 1;
function a() {
console.log(b); // undefined
var b = 2;
console.log(b); // 2
}
a();
console.log(b); // 1
}
二十、严格模式:use strict
使用方式
针对于整个文件【全局】
文件开头(第一行)写入
use strict
<script>
'use strict'
</script>针对单个函数【局部】
函数内开头(第一行)写入
use strict
function fun(){
'use strict'
}
作用
变量声明问题:var | window、如果写法是:str = 123; 就报错
禁止this关键字指向全局对象
重名问题,函数不能有重名的参数
arguments对象不能赋值
二十二、递归函数:自己调用自己
注:一定要有结束条件,如果没有结束条件就变成死循环
数组扁平化
[‘a’,’b’,’c’,[‘d’,’e’,[‘f’,’q’]]]
把多维数组变成一维
function fun(arr) {
// 弄一个空数组
var result = [];
for (var i = 0;i < arr.length;i++) {
if (typeof arr[i] == 'object') {
// ['d','e']
// ['a','b','c'].合并(['d','e'])
result = result.concat(fun(arr[i]));
}else {
result.push(arr[i]);
}
}
}
console.log(fun(['a','b','c',['d','e']]));斐波那契算法
有一对兔子,从生出的第三个月起每个月会生一对兔子,小兔子长到第三个月后每个月也会生一对兔子,假如兔子不死,那么第N个月有多少对兔子?
分析:1 1 2 3 5 13 21 …
function fun(n) {
if (n <= 0) {
return 0;
}
if (n <= 2) {
return 1;
}
// 第n个月兔子的总对数 = 第n-1个月的总数+第n-2个月的总数
return fun(n-1) + fun(n-2);
}走楼梯
一共10级楼梯,每次可以走一步或者可以走二步,求一共多少种走法
function fun(n) {
if (n == 1) {
return 0;
}else if (n == 2) {
return 2;
}else if(n > 2){
return fun(n-1) + fun(n-2);
}
}
二十三、闭包
块级作用域
只有var没有块级作用域,let和const有块级作用域
作用域和作用域链
当函数声明的时候,函数会通过内部属性,scope来记录创建范围
闭包
什么是闭包
闭包是一个函数加上到创建函数的作用域的连接,闭包就是“关闭”了函数的自由变量
简单理解:
有两个函数,作用域是连接关系【scope】,变量不自由,会停留在内存中,不会销毁
function fun(n) {
return function(m) {
n += m;
return n;
}
}
var f = fun(5);
f(1)
闭包可以做什么?无意间共享环境
var lis = document.getElementsByTagName('li');
for (var i = 0;i < lis.length;i++) {
lis[i].onclick = function() {
console.log(i);
}
}
// 此处打印会是3 3 3,而期望打印0 1 2 ,因为在打印变量i时内部没有i他会向外找i当找到i时已经执行完了var lis = document.getElementsByTagName('li');
for (var i = 0;i < lis.length;i++) {
(function() {
var idx = i;
lis[i].onclick = function() {
console.log(idx);
}
})
}
// 自执行函数
二十三、undefined和null区别-instanceof
回顾数据类型
原始数据类型(基本数据类型)
字符串、数值、布尔、undefined、null
引用数据类型
对象:object
基本和引用的区别:每个对象都有唯一的标识,并且(严格地)等于自身。
var arr1 = [1,2,3];
var arr2 = [1,2,3];
console.log(str1 === str2);
// false
区别
undefined:未定义
null:没有对象
先设计的null,后设计的undefined
JavaScript的最初版本是这样区分的:null是一个表示 ”无“ 的对象(空对象指针),转为数值时为0;undefined是一个表示 ”无“ 的原始值,转为数值时为NaN。
注意null的问题:typeof null 返回 ‘object’ 是一个无法修复的错误
检测类型
typeof
:检测基本类型instanceof
:检测引用类型、对象、返回布尔类型// 语法格式
检测的数据类型 instanceof 所属构造函数名称
二十四、对象
字面量形式
var obj = {}
// 获取对象的属性对应的值
var obj = {
userName:'张三',
age:18,
}
console.log(obj.userName);构造函数形式
注:构造函数的首字母要大写
function Fun() {
this.userName = '张三',
this.run = function() {
return 123;
}
}
var obj = new Fun();
console.log(obj.userName);
console.log(obj.run());Object.create()
创建一个新的对象,使用现有的对象来提供创建的对象的原型
var obj = Object.create(Object.prototype);
console.log(obj);设置属性
var obj = {
age:18,
5:'你好',
};
obj.userName = '张三';检测对象是否有该属性
in:
属性名称 in 对象
'userName' in obj;
// 返回布尔值hasOwnProperty:
对象.hasOwnProperty
判断对象自身是否有某个属性
obj.hasOwnProperty('sex');
区别
in 可以检测对象自身属性也可以检测原型的属性、hasOwnProperty无法检测原型
删除属性
delete 对象.属性
注:对象即使没有这个属性,也不会报错,是返回undefined
get-set
get:读
set:写
var obj = {
name:'张三',
get changeName() {
return this.name;
},
set changeName(val) {
this.name = val;
},
}
obj.changeName = '李四';
console.log(obj.changeName); // 张三 // 李四序列化对象
对象 转化成 字符串:
JSON.stringify()
字符串 转化成 对象:
JSON.parse()
遍历对象
for...in
key:就是属性名【键名】
obj[key]:就是值【键值】
var obj = {
a:1,
b:2,
c:3,
fun:function() {
retuen 111
},
};
for(var key in obj) {
console.log(key); // a b c fun
console.log(obj[key]); // 1 2 3 function(){return 111}
}Object.keys()、Object.values()
var obj = {
a:1,
b:2,
c:3,
fun:function() {
retuen 111
},
};
console.log( Object.keys(obj) );
console.log( Object.values(obj) );
// 返回数组
合并对象
Object.assign(target,obj1,obj2...)
target:合并对象,复制目标对象
var obj1 = {
a:1,
}
var obj2 = {
b:2,
}
Object.assign( obj1,obj2 );
console.log( obj1 ); // { a:1, b:2 }
var o = Object.assign( {},obj1,obj2 );
console.log( o ); // { a:1, b:2 }
this指向
this 指的是函数运行时所在的 “环境”
原理:js语言设计 this,是跟内存的数据结构有关系,函数可以在不同的环境运行执行,所以就需要一种机制,能够在函数体内获取当前函数的运行环境。
this 的设计目的就是在函数体内,指向函数当前的运行环境。
补充:引擎会将函数单独保存在内存中
var x = 1;
var obj = {
x:2,
run:function() {
// 要是想让this指向函数,添加下面的代码
// var that = this;
return function() {
return this.x; // 这里的this 代表window了,值为1
// return that.x;
};
},
}
console.log( obj.run()() )
// 等同于
var f = obj.run();
console.log( f() );改变this指向–call、apply、bind
是所有函数都具有的方法
函数也是对象,函数具有方法
call(参数1,参数2,参数3...)
参数1:调用函数时,内部this的具有值
剩余的参数(参数2,参数3…)就是函数的参数
var x = 1;
var obj = {
x:2,
run:function(val) {
return this.x + val;
},
};
console.log( obj.run('你好') );
var f = obj.run;
console.log( f.call(obj,'大家好') );apply(参数1,[参数值1,参数值2,参数值3])
参数1:调用函数时,内部this的具有值
参数2:是一个数组,其中数组每一个值代表了函数的参数
console.log( f.apply(obj,['大家好']) );
console.log( Math.max(...[3,6,8,99,55]) ); // 99
console.log( Math.max.apply(null,[3,6,8,99,55]) ); // 99bind(参数1,参数2,参数3...)
参数1:调用函数时,内部this的具有值
剩余的参数(参数2,参数3…)就是函数的参数
注:bind会返回一个函数,所以要加一个()
console.bind( f.call(obj,'大家好')() );
二十五、对象模式
工厂模式
// 这是一个厂子
function fun() {
// 这是人
var o = new Object();
o.name = '张三';
// 最终要返回一个对象
return o;
}
var obj = fun();
console.log(obj);// 这是一个厂子
function fun(cName) {
// 这是人
var o = new Object();
o.name = cName;
// 最终要返回一个对象
return o;
}
var obj1 = fun('张三');
var obj2 = fun('李四');
console.log( obj1,obj2 );构造函数
就是普通函数、只不过首字母要大写,函数内可以有 this,这个 this 指向 new 出来的对象
function fun() {
// 普通函数
}
function Fun() {
// 构造函数
}// 构造函数
function Fun() {
}
var obj = new Fun(); // 实例化
console.log( obj );原型模式(prototype)
- 函数拥有prototype属性|对象
- 共享的属性和方法放在prototype中,不共享的放在构造函数中
- new 缺点:无法共享属性和方法
function Fun() {
// 不共享
this.run = function() {
return 111;
}
}
// 共享
// Fun.prototype.person = function() {
// return 222;
// }
Fun.prototype = {
person:function() {
retuen 222;
}
}
var obj1 = new Fun();
var obj2 = new Fun();
console.log( obj1.run === obj2.run ); // false
console.log( obj1.person === obj2.oerson ); // true函数与对象的原型关系
函数有:
prototype
对象有:
__proto__
function Fun() {
this.name = '张三';
}
var obj = new Fun();
// Fun 是一个函数
// obj 是一个对象
console.log( obj.name );new 具体做了什么事
创建一个对象
new Object()
原型赋值【指向共同一个原型对象】
对象.__proto__ = Fun.prototype
改变this指向
浅拷贝和深拷贝
什么叫拷贝
复制
var a = 10;
var b = a;
console.log( a,b ); // 10 10
a = 200;
console.log( a,b ); // 200 10// 引用类型,引用传递
var o = {a:1};
var m = o;
console.log( o.a,m.a ); // 1 1
o.a = '你好';
console.log( o.a,m.a ); // 你好 你好浅拷贝
只复制一层对象,当对象的属性是引用类型时,实质上复制的其引用,当引用指向的值发生变化的时候,原对象的属性也会跟着变化。
var obj = {
a:1,
b:{
a:'你好'
}
}
function fun(obj) {
var m = {};
for(var k in obj) {
m[k] = obj[k]
}
return m;
}
var createObj = fun(obj);
console.log( createObj.b ); // {a:"你好"}
console.log( createObj.b.a ); // 你好
console.log( obj.b.a ); // 你好
createObj.b.a = '222'
console.log( createObj.b.a ); // 222
console.log( obj.b.a ); // 222Object.assign()
var o = {
a:1,
b:{
a:'你好'
}
}
var m = Object.assign({},o); // {a:1, b:{a:'你好'}} {a:1, b:{a:'你好'}}
m.b.a = '不好';
console.log( 0,m ) // {a:1, b:{a:'不好'}} {a:1, b:{a:'不好'}}深拷贝
在拷贝的时候,创建新的对象,并把原对象所有的属性都深拷贝到新对象,原属性如果是对象,也会重新创建新的对象并拷贝到新对象属性中,这样旧对象和新对象就是互相独立的,互不影响。、
JOSN.parse() + JOSN.stringify
var o = {
a:1,
b:{
a:'你好'
}
}
var m = JOSN.parse(JOSN.stringify(o));
console.log( o,m ); // {a:1, b:{a:'你好'}} {a:1, b:{a:'你好'}}
m.b.a = '不好';
console.log( o,m ); // {a:1, b:{a:'你好'}} {a:1, b:{a:'不好'}}递归
var o = {
a:1,
b:{
a:'你好'
}
}
function fun(obj) {
var m = {};
if(typeof obj == 'object') {
for(var k in obj) {
if(obj.hasOwnProperty(k)) {
if(typeof obj[k] == 'object') {
m[k] = fun(obj[k]);
} else {
m[k] = obj[k];
}
}
}
}
return m;
}
var createObj = fun(obj);
console.log( createObj.b ); // {a:1, b:{a:'你好'}}
console.log( obj.b ); // {a:1, b:{a:'你好'}}
createObj.b.a = '不好';
console.log( createObj.b ); // {a:1, b:{a:'不好'}}
console.log( obj.b ); // {a:1, b:{a:'你好'}}
二十六、原型链–继承
每一个对象那个都有原型(__ proto __),这个原型还有属于自己的原型,最终形成了原型链。原型链最顶端是null。
为什么设计原型:继承、让对象的属性和方法实现共享
函数:prototype
对象:__ proto __
如果要查找对象的属性或者方法,我们先要去对象中查找,
如果没有查找到,要去对象的原型中查找
如果还没有查找到,要去当前对象的原型的原型中查找
以此类推……直到找不到,返回undefined
继承
儿子 继承 父亲
Child.prototype = new Parent();
function Parent() {
this.name = '张三';
}
function Child() {
this.age = 18;
}
// 把父对象给子原型、实现了原型继承
Child.prototype = new Parent();
var obj = new Child();
console.log( obj.name );function Hero() {
this.name = 'nihao';
this.sayMe = function() {
alert('this is nihao');
}
}
Hero.prototype.name = 'hellow';
Hero.prototype.sayMe = function() {
alert('this is hellow');
}
var hero = new Hero();
console.log( hero.name ); // nihao
console.log( hero.sayMe ); // function() {alert('this is nihao');}function Foo() {
getName = function(){
alert(1);
}
return this;
}
Foo.getName = function() {
alert(2);
}
Foo.prototype.getName = function() {
alert(3);
}
var getName = function() {
alert(4);
}
function getName() {
alert(5);
}
Foo.getName(); // 2
getName(); // 4
Foo().getName(); // 1
getName(); // 1
new Foo().getName(); // 1借用构造函数
字面量的字符串,new String()
var str1 = '123' // string
var str2 = new String() // 对象
str1 借用了new String的属性和方法每次生成一个对象,对象本身的属性和方法不共享
改变this指向:call、apply、bind
function Parent() {
this,name = '张三';
this.arr = [1,2,3];
}
function Child() {
// 让Parent的this指向于对象
Parent.call(this);
this.age = 20;
}
// obj1.arr[0] = '你好' obj1会被修改,obj2不会
var obj1 = new Child();
var obj2 = new Child();
console.log( obj1.name,obj2.name );组合继承
还有很多继承方式:寄生继承
原型:
- 共享属性和方法
- 无法向父构造函数传递参数
借用构造函数:
- 可以向父构造函数传递参数
- 不可以共享
组合继承:
- 既可以传递参数,也可以实现该有的共享性
function Parent(cName) {
this.name = cName;
}
Parent.prototype.run = function() {
}
function Child(cName) {
this.age = 20;
// 借用构造函数
Parent.call(this,cName);
}
// 原型
Child.prototype = new Parent();
Child obj1 = new Child('111');
Child obj2 = new Child('222');
console.log( obj1.name,obj2.name );
console.log( obj1.run === obj2.run );
二十七、前端性能优化
一个网站打开速度多少合适
PC:4s内 移动端:3s内
浏览器的渲染过程
视觉变化【js操作】–> style –> layout【布局】 –> point【绘制】 –> composite【合并】
当在浏览器输入一个url,按回车会经历什么步骤
- 通过浏览器的解释器,把文本【代码】,解析成html
- dom树
- css树
- 然后进行合并,并且渲染
- 通过浏览器的解释器,把文本【代码】,解析成html
layout 布局 –> 造成回流【css改变动画】
增加/删除元素
移动/改变大小元素:offsetLeft、scrollTop、style.width
修改浏览器大小和字体大小
js优化需要注意
原型链
二十八、debugger和try
ReferenceError:非法或者不能识别的引用数值
SyntaxError:发生语法解析错误
TypeError:操作类型错误
try … catch:让错误代码不影响后续代码进行
二十九、jQuery
jQuery使用
jQuery中的选择器
基本选择器
#id
$('#id名称')
.class
$('.class名称')
element
$('div')
*
几乎不用selector1,selector2,selectorN
$('div,span,p...')
:first
选择到第一个:not(:selector)
去除所有与给定选择器匹配的元素:even
匹配到所有索引变量偶数的元素,从0开始计数:odd
匹配到所有索引变量奇数的元素,从0开始计数:eq(index)
匹配一个给定的索引的元素,从0开始计数:gt(index)
匹配所有大于给定索引值的元素,从0开始计数:last
选择到最后一个:lt(index)
匹配所有小于给定索引值的元素,从0开始计数
层级选择器
ancestor descendant
在给定的祖先元素下匹配所有的后代元素parent > child
在给定的父元素下匹配所有的子元素prev + next
匹配兄弟的下一个,下一个兄弟prev ~ siblings
匹配下所有【平级关系】兄弟
内容选择器
:contains(text)
含有这个文本的节点,模糊搜索<ul>
<li>1123你好23232</li>
<li>11不好2</li>
<li>aff我有100万好不好dfdfd</li>
<li>aff23232d</li>
<li>aff23232d</li>
<li>kfjdf</li>
<li></li>
</ul>
<script type = "text/javascript" src = 'js/jquery.js'></script>
$(function(){
$('ul li:contains(好)').css('background','pink');
}):empty
选取到不含子元素的元素$('ul li:empty').css('background','pink');
:has(selector)
选取到只有一个子元素:parent
选取到含有某一个元素的元素
可见性选择器
:hidden
匹配所有不可见元素,或者type为hidden的元素:visible
匹配所有可见的元素
一般在判断的时候使用可见性选择器
<ul>
<li>苹果</liOPPO>
<li>OPPO</li>
<li>VIVO</li>
<li>小米</li>
<li>索尼</li>
<li id="more">更多</li>
</ul>$(function(){
// 选择到所有的Li,大于索引2的隐藏掉,并且排除掉最后一个
var lis = $('ul li:gt(2):not(:last)').css('display','none');
$('#more').click(function(){
// 如果是显示 的就隐藏掉,否则就显示
if (lis.is(":visible")) {
lis.css('display','none');
$('#more').text('收起');
} else {
lis.css('display','block');
$('#more').text('更多');
}
})
})
对象之间的转换
jquery对象转换为dom对象
$('#main')[0]
||$('#main').get(0 )
dom对象转换为jquery对象
var mian = document.getElementById('main')
$(main)
这里是转换
节点查找的方法
子节点
children()
查找的是子节点find()
查找所有指定后代元素父节点
parent()
查找到父节点parents('元素')
查找到指定的祖先元素兄弟节点
next()
下一个兄弟,不包括自己nextAll()
下所有兄弟,不包括自己prev()
上一个兄弟,不包括自己prevAll()
上所有兄弟,不包括自己siblings()
上下所有兄弟,不 包括自己$('#lis').nextAll().css('background','blue);
CSS类
addClass()
添加class$('#main').addClass('o');
removeClass()
删除class如果不加参数,删除所有class的值
如果加参数,删除指定class的值
$('#main').addClass('o').removeClass();
toggleClass()
做切换的,如果存在(不存在)就删除(添加)一个类
过滤方法
eq()
first()
last()
eq、first、last方法和选择器的功能是一模一样的
filter
筛选出与指定表达式匹配的元素集合is
根据选择器、DOM元素或jQuery对象来检测匹配元素集合,如果其中至少有一个元素符合这个给定的表达式就返回trueslice
字符串或者数组的slice完全一样插入节点
内部插入
append(content|fn)
与appendChild类似// 添加到内部的最后
$('#main').append('<h1>这是h1</h1>')appendTo(content)
prepend(content|fn)
// 添加到内部的前面
$('#main').prepend('<h1>这是h1</h1>')prependTo(content)
语法:
- append、prepend =====》
父元素.方法名称(子元素)
- appendTo、prependTo ====》
子元素.方法名称(父元素)
- append、prepend =====》
外部插入
after(content|fn)
平级插入,插入在当前的下面before(content|fn)
平级插入,插入在当前的上面insertAfter(content)
insertBefore(content)
语法:
- after、before =====》
当前元素.方法名称(插入语元素)
- appendTo、prependTo =====》
子元素.方法名称(父元素)
- after、before =====》
删除节点和属性
删除节点
js原生中用
removeChild
删除节点jquery中使用
remove()
来删除节点$('#uls a').click(function(){
$(this).parent().remove();
})属性
attr
获取匹配的元素集合中的第一个元素的属性的值 或 设置每一个匹配元素的一个或多个属性
js原生中设置属性或者获得属性的值用
setAttribute
、getAttribute
方法jquery用
attr()
来获取或者设置属性、1个参数是获取属性的值,2个参数是设置属性prop
获取匹配的元素集合第一个元素的属性(property)值或设置每一个匹配元素的一个或多个属性
文本值
html()
js原生中的innerHTML
text()
js原生中的innerText
val()
js原生中value
获取:
选择器.方法名称
赋值:
选择器.方法名称(赋值的内容)
尺寸
height([val|fn])
width([val|fn])
- 只是单纯的返回width和height
innerHeight()
innerWidth()
- width + padding
outerHeight([soptions])
outerWidth([options])
width + padding + border
如果参数为true,则:width + padding + border + margin
位置
offset().left
当前元素距离浏览器左侧的偏移量offset().top
当前元素距离浏览器顶部的偏移量scrollTop
scrollLeft
事件
// js原生的事件
var main = document.getElementById('main');
main.onmouseover = function() {
alert(1);
}// jquery事件的写法区别
$('#main').mouseover(function(){
alert(1);
})事件绑定
bind(type,[data],fn)
// 无法执行
$('#txt').input(function() {
alert(1);
})
// 可以执行
$('#txt').bind('input',function() {
alert(1);
})事件委托
$(父元素).on('事件名称','子元素',函数)
事件对象
eve.pageX
类似于js原生的e.clientX
eve.pageY
类似于js原生的e.clientY
鼠标距离浏览器左侧【顶部】的距离
event.preventDefault()
阻止默认行为event.stopPropagation()
阻止冒泡
循环遍历
方式一:
$(选择器).each(function(index,item){})
方式二:
$.each(要遍历的对象,function(index,item){ // 循环体 })
区别:
当遍历一个jquery对象的时候可以用方式一
当遍历一个对象或者数组的时候,可以用方式二、
jQuery自带动画
基本动画
show()
hide()
可以加入参数,就是动画完成的毫秒数
滑动动画
slideDown([s],[e],[fn])
slideUp([s,[e],[fn]])
淡入淡出
fadeIn()
fadeOut()
注意stop可以清空队列
$(this).find('ul').stop().slideUp();
自定义动画
animate(要改变的样式,毫秒数,回调函数)
animate({
margin:'10px',
padding:'10px',
color:'#000'
...
},500,function() {
alert(1);
})
<div id='main'class='main'> 111 </div>
$(function() {
$("#main").aminate({
'padding':'100px',
'margin':'20px'
},500,function() {
alert(1);
})
})无缝滚动
jQuery插件写法
插件:让代码更具有复用性
插件机制的方法
$.fn.extend(object)
扩展 jQuery元素集来提供新的方法(通常用来制作插件)
$('ul li').扩展一个方法()
、局部插件
$.extend(object)
扩展jQuery对象本身、$扩展方法、全局插件如何写jquery插件
先引入jQuery再引入插件
<script type="text/javascript" src='juqery-1.11.min.js'></script>
<script type="text/javascript" src='jquery.nav.js'></script>插件的命名规范
jquert.插件名称.js
插件内部写法
开始是匿名函数自执行
// 全局
(function() {
$.extend({
'nav':function(){
alert(1);
return this;
}
})
})();<script>
$(function(){
// 使用插件
$.nav();
})
</script>// 局部
(function() {
$.fn.extend({
'nav':function(){
$(this).find('li').click(function(){
$(this).hide();
})
return this;
}
})
})();<script>
$(function(){
// 使用插件
$('ul').eq(2).nav();
})
</script>
三十、json格式
什么是json
存入数据的格式,轻量级交换数据的一种格式
// 普通对象格式
var obj = {
userName:'张三',
age:18,
arr:['a','b','c'],
'margin-left':'20px'
}
console.log(obj['margin-left']);json数据存放
json中不能有单引号
json中的key必须要加入双引号
json中是数据,不能写函数
// 完美的json格式
{
"userName":"张三",
"age":20,
"arr":["a","b","c"],
"o":{
"a":10
}
}
三十一、ajax
什么是ajax
一种创建”快速” “动态”的网页技术
原生js操作ajax
http请求方式
GET
:用户获取数据,get是在url上传递数据,存储量较少,安全性较低POST
:用户上传数据,post容量几乎是无限的异步操作
同步
异步
操作ajax
创建ajax对象
new XMLHttpRequest()
var xhr = new XMLHttpRequest()
连接服务器
ajax对象.open(请求方式[get|post],请求的url,异步|同步)
异步:true
同步:false
xhr.open('GET','data.json',true)
发送请求
ajax对象.send(给后端的数据,如果没有数据就写null)
xhr.send(null)
接收返回值
ajax对象.onreadystatechange
:事件、当请求被发送到服务器时,我们需要执行基于响应的操作ajax对象.readyState
:请求的状态码- 0(未初始化)open还没有调用
- 1(载入)已经调用send,正在发送请求
- 2(载入完成)send完成了,已经收到全部响应了
- 3(解析)正在解析内容
- 4(完成)响应内容解析完成,可以在客户端用了
ajax对象.status
:返回请求结果码- 200成功
- 404未找到
- 500服务器错误
返回内容:
ajax对象.reponseText
// 创建ajax对象
var xhr = new XMLHttpRequest();
// 连接服务
xhr.open('POST','http://39.101.217.150:8075/banner/list',true);
// 发送请求
xhr.send(null);
// 接收返回值
xhr.onreadystatechange = function() {
if(xhr.status == 200 && xhr.readyState == 4) {
var data = JSON.parse(xhr.responseText);
console.log(data);
}
}
三十二、jQuery操作ajax
$.ajax(url,[settings])
$.ajax({
// url:请求的路径
url:'http://39.101.217.150:8075/banner/list',
// 默认为true异步请求,false同步请求
async:
// 发送信息至服务器时内容编码类型
contentType:
// 前端给后端的数据
data:
// 预期服务器返回的数据类型
dataType:
// 请求方式 默认:get
type:"POST"
// 请求成功后的回调函数
success:function(data) {
console.log(data);
}
})跨域
前端:jsonp
后端:cors