js
一、相关语法
函数
//定义函数1
var a = function(b){
.....
}
//定义函数2
function a(b){
.....
}
//function定义的函数,既能直接调用,也可以像类一样使用new关键字来生成。(直接new函数名用一个变量来接收,这个变量就相当于一个对象了)也就是函数既可以当做普通函数,也能当做构造函数。
function User(name)
{ this.name = name;
}
var user = new User('lu');
console.log(user.name)
函数可以被当作参数传递
var f1 = function(){
console.log('我是f1的方法')
}
var f2 = function(a){
a()
}
f2(f1)
对象
-
var dog =object();
-
var dog = new Object();
-
var dog={}
//建立对象以后可直接赋属性和方法
dog.color = 'red'
dog.eat = fuction(){
console.log('我在吃!')
}
dog.eat();
//也可以这样
var dog = {name: 'tidy',color: 'red'}
var a = {name: 'lu',eat : function(){console.log('我是方法')}} //可以调用a.eat()或打印a.name
if
如果条件是一个值
- 0
- null
- undefined
- false
- ‘’
上面5个都是false,其他都是true (空对象和数组也是true)
遍历对象属性
注意:获取对象属性的时候可以用. 也可以用[key]
var options = { name: 'zhangsan', age: 10 }
console.log(options['name'])//说明我们对象取值除了点还有这种方式
console.log(options.name)
for(var key in options)
{
console.log(key) //正确
console.log(options[key]) //正确
console.log(options.key) //错误取值
}
//用点的时候 点后面是对象的真实属性名称,
//用中括号的时候 中括号里面是变量或者字符串
衍生类数组
var a={
0: '12',
1: '34',
2: '56',
length : '3'
}
for(var i=0;i<a.length;i++){
console.log(a[i])
}
function里面有两个内置对象
1.arguments 不管写没写参数,外面传了这个对象都能接收到哦
function b(){
console.log(arguments)
}
b(1,2,3,4,5)
浏览器结果如下
//Arguments(5) [1, 2, 3, 4, 5, callee: ƒ, Symbol(Symbol.iterator): ƒ]
0: 1
1: 2
2: 3
3: 4
4: 5
callee: ƒ b()
length: 5
Symbol(Symbol.iterator): ƒ values()
[[Prototype]]: Object
2.this 始终指向这个函数创造的对象
二、常见内置对象
1、Array对象
- concat() 表示把几个数组合并成一个数组
- join() 设置分隔符连接数组元素为一个字符串
- pop() 移除数组最后一个元素
- shift() 移除数组中第一个元素
- slice(start,end) 返回数组中的一段
- splice() 可以用来删除,可以用来插入,也可以用来替换
- push() 往数组中新添加一个元素,返回最新长度
- sort() 对数组进行排序
- reverse() 反转数组的顺序
- toLocaleString() 把数组转
属性
- length 表示取得当前数组长度 (常用)
- constructor 引用数组对象的构造函数
- prototype 通过增加属性和方法扩展数组定义
2、Global对象
-
escape() 对字符串编码
-
eval() 把字符串解析为JavaScript代码并执行
-
isNaN() 判断一个值是否是NaN
-
parseInt() 解析一个字符串并返回一个整数
-
parseFloat() 解析一个字符串并返回一个浮点数
-
number() 把对象的值转换为数字
-
string() 把对象的值转换为字符串
3、String对象
- charAt() 返回指定索引的位置的字符
- indexOf() 从前向后检索字符串,看是否含有指定字符串
- lastIndexOf() 从后向前检索字符串,看是否含有指定字符串
- concat() 连接两个或多个字符串
- match() 使用正则表达式模式对字符串执行查找,并将包含查找结果最为结果 返回
- replace() 替换一个与正则表达式匹配的子串
- search() 检索字符串中与正则表达式匹配的子串。如果没有找到匹配,则返回 -1。
- slice(start,end) 根据下表截取子串
- substring(start,end) 根据下表截取子串
- split() 根据指定分隔符将字符串分割成多个子串,并返回素组
- substr(start,length) 根据长度截取字符串 *
- toUpperCase() 返回一个字符串,该字符串中的所有字母都被转化为大写字母。
- toLowerCase() 返回一个字符串,该字符串中的所有字母都被转化为小写字母。
4、Math对象
- ceil() 向上取整。
- floor() 向下取整。
- round() 四舍五入。
- random() 取随机数。
5、Date对象
- getDate函数: 返回日期的“日”部分,值为1~31。
- getDay函数: 返回星期,值为0~6,0表示星期日。
- getHours函数: 返回日期的“小时”部分,值为0~23。
- getMinutes函数: 返回日期的“分钟”部分,值为0~59。
- getMonth函数: 返回日期的“月”部分,值为0~11。
- getSeconds函数: 返回日期的“秒”部分,值为0~59。
- getTime函数: 返回系统时间。
- getTimezoneOffset函数: 返回此地区的时差(当地时间与GMT格林威治标准时间的地区时差), 单位为分钟。
- getYear函数: 返回日期的“年”部分。返回值以1900年为基数,如1999年为99。
- parse函数: 返回从1970年1月1日零时整算起的毫秒数(当地时间)
- setDate函数: 设定日期的“日”部分,值为0~31。
- setHours函数: 设定日期的“小时”部分,值为0~23。
- setMinutes函数: 设定日期的“分钟”部分,值为0~59。
- setMonth函数: 设定日期的“月”部分,值为0~11。其中0表示1月,…,11表示12 月。
- setSeconds函数: 设定日期的“秒”部分,值为0~59。
- setTime函数: 设定时间。时间数值为1970年1月1日零时整算起的毫秒数。
- setYear函数: 设定日期的“年”部分。
- toGMTString函数: 转换日期成为字符串,为GMT格林威治标准时间。
- setLocaleString函数: 转换日期成为字符串,为当地时间。
- UTC函数: 返回从1970年1月1日零时整算起的毫秒数(GMT)。
三、DOM编程
js控制前端节点,与后端数据交互
在 HTML DOM (Document Object Model) 即文档对象模型中, 每个东西都是 节点 :
- 文档本身就是一个文档对象
- 所有 HTML 元素都是元素节点
- 所有 HTML 属性都是属性节点
- 元素内的文本是文本节点
- 注释是注释节点,就不用
<div class='test1' id='a'>文本</div>
div整体是一个元素节点
class=‘test1’ 是一个属性节点
文本是个文本节点,注意中间没有东西空字符也是一个文本节点
所有的节点都有一个nodeType属性,可以判断节点类型,常用的就是以下
NodeType | Named Constant |
---|---|
1 | ELEMENT_NODE 元素节 |
2 | AATTRIBUTE_NODE 属性节点 |
3 | TEXT_NODE 文本节点 |
DOM操作其实就是对节点的增删查改
1、元素节点
获取元素节点的方法
//根据id获取一个元素节点
var div1 = document.getElementById("div1")
//根据标签名获取一堆节点的集合
var li1 = document.getElementsByTagName("li");
//根据class获取一堆元素节点
var div2 = document.getElementsByClassName("content");
//使用css选择器选择第一个匹配的元素节点
var d1 = document.querySelector(".content")
//根据css选择器选择一批能够被匹配到的所有的元素
var d1 = document.querySelectorAll(".content")
修改节点内容
//不渲染html标签,标签会当做文本打印出来
mydiv.innerText = "jiasoushi"
//会将html标签渲染出来
mydiv.innerHTML = "</h1>123</h1>
删除一个元素节点
//直接把自己干掉
var mydiv = document.getElementById("div1")
mydiv.remove();
//清除内容
mydiv.innerText = “”;
//删除某个子元素节点
//1、找到这个字元素节点
var myul = document.getElementsByTagName('ul')[0];
//2、调用方法干掉,注意这个方法参数一定要是个元素节点
mydiv.removeChild(myul)
var div1 = document.getElementById("div1")
undefined
var child = document.getElementsByTagName("ul")[0]
undefined
child
•…•
• div1.removeChild(child)
新建一个元素节点
//创建一个div标签,内存中
var mydiv = document.createElement("div");
//添加进几个属性
mydiv.setAttribute("name","mydiv");
mydiv.setAttribute("class","test");
//获取到我的
div var div1 = document.getElementById("div1");
//将内存中新建的div实实在在的加入到我的div中
div1.append(mydiv)
获取所有的子节点
//children属性能获取所有的子元素节点, 不包括文本节点
var a=mydiv.children //a是一个元素的集合
a[i]//可以获取其中一个元素
//children属性能获取所有的子元素节点, 包括文本节点
mydiv.childNodes
NodeList(3) [text, ul, text]
//子节点也是元素节点,一样可以有子节点
mydiv.children[0].children
2、属性节点
使用元素节点方法进行增删查改
var mydiv = document.getElementById("div1")
//获取这个属性的值
mydiv.getAttribute("name")
//修改,同时可以添加一个属性的值
mydiv.setAttribute("name","cccc")
//删除一个属性
mydiv.removeAttribute("name")
使用属性节点对象对属性本身进行操作
//获取所有的属性节点的集合,是个可以当成数组
mydiv.attributes
//通过下标拿到第二个属性
mydiv.attributes[1]
//拿到属性的name
var attrName = mydiv.attributes[1].name
//拿到属性的值
var attrValue = mydiv.attributes[1].value
//修改这个属性的值
mydiv.attributes[1].value = "aaa"
常用属性操作
比如id、class、style
var div1 = document.getElementById("div1");
//获取id的值
div1.id
//给元素标签的id赋值
div1.id = "div2"
//获取class属性
div1.className
//为class属性赋值
div1.className = 'content'
div1.className "content"
//直接修改行内样式
div1.style = 'background: black'
四、BOM编程
BOM是浏览器对象模型
BOM提供了独立于内容,而与浏览器窗口进行交互的对象
BOM的核心对象window
BOM由一系列相关对象构成
1.回调函数
js函数定义很灵活,定义了参数传什么都行,其实是传什么就当做什么来用
eg.
var callback = function(fun){
console.log(fun)
}
callback(1)
callback("123")
callback( {name:'zhangnan'} )
callback( [1,2,3] )
如果这个参数是传的一个方法,就需要在方法里面找个地方调用一下
eg.
var test = function(fun){
console.log("before")
fun(); //我们这里要运行fun函数,这里已经代表是一个函数,所以在外面我们写test(1)之类的会在这报错
console.log("after")
}
var callback = function(){
console.log(".......")
}
test(callback)
=========================================================
也可以直接传个方法体进去
test(function(){
console.log(".......")
})
=========================================================
其实运行一个函数可以直接调用方法体
(function(){
console.log(123)
})()
一些深入
阻塞式回调和延迟式回调。两者的区别在于:阻塞式回调里,回调函数的调用一定发生在起始函数返回之前;而延迟式(异步)回调里,回调函数的调用有可能是在起始函数返回之后。
setTimeout(fn,time){
.................. //就称作中间函数
fn()
}
//参数fn就是回调函数
//中间函数的调用者叫做起始函数
//给中间函数传入什么样的回调函数,是在起始函数里决定的
js任务队列
setTimeout("alert('回调函数')", 10000 )
alert("阻塞")
//先弹出“阻塞”,立马按下确定后大约5秒后弹出“回调函数”
//或者弹出“阻塞”后,等待5秒,按下确定后立马弹出“回调函数”
JavaScript语言的一大特点就是单线程
虽然我们知道多线程可以充分利用cpu,提高程序运行效率高。其实JavaScript的单线程,与它的用途有关。
作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?(联想一下android开发的那个handle机制)
为了利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,但是子线程完全受主线程控制,且不得操作DOM。这个新标准并没有改变JavaScript单线程的本质。
单线程,顾名思义只有一条队伍,任务都是在排队等待使用CPU执行的。大多时候CPU处于空闲状态,例如IO设备(输入输出设备)很慢(比如Ajax操作从网络读取数据,操作页面DOM),不得不等着结果出来,再往下执行。
JavaScript语言的设计者意识到,这时主线程完全可以不管IO设备,挂起处于等待中的任务,先运行排在后面的任务。等到IO设备返回了结果,再回过头,把挂起的任务继续执行下去。
于是,所有任务可以分成两种:
①同步任务(synchronous)
在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;
②异步任务(asynchronous)
不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。
● setTimeout() 设置的异步延迟事件
● DOM 操作相关如布局和绘制事件
● 网络 I/O 如 AJAX 请求事件;
● 用户操作事件,如鼠标点击、键盘敲击。
具体来说,异步执行的运行机制如下。
(同步执行也是如此,因为它可以被视为没有异步任务的异步执行。)
————————————————————————————————————————————
(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕(主线程空了),系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。
除了放置异步任务的事件,“任务队列"还可以放置定时事件,即指定某些代码在多少时间之后执行。这叫做"定时器”(timer)功能,也就是定时执行的代码。
定时器功能主要由setTimeout()和setInterval()这两个函数来完成,它们的内部运行机制完全一样
如果将setTimeout()的第二个参数设为0,就表示当前代码执行完(执行栈清空)以后,立即执行(0毫秒间隔)指定的回调函数
setTimeout(function(){console.log(1);}, 0);
console.log(2);
上面代码的执行结果总是2,1,因为只有在执行完第二行以后,系统才会去执行"任务队列"中的回调函数。
需要注意的是,setTimeout()只是将事件插入了"任务队列",必须等到当前代码(执行栈)执行完,主线程才会去执行它指定的回调函数。要是当前代码耗时很长,有可能要等很久,所以并没有办法保证,回调函数一定会在setTimeout()指定的时间执行。
1.setTimeout
//一次性定时器,会在多少毫秒后执行这个函数
//里边的是匿名函数,也叫回调函数(就是等过了两秒后回过头来再调用这个函数)
//返回值是个定时器,这个方法是在未来去执行某个函数
var timer = setTimeout( function(){
console.log(123)
},2000 )
//如果时间未到,不想让他执行了,就需要取消这个定时器
clearTimeout(timer)
2.setInterval
//周期性定时器,会每隔多少毫秒后执行这个函数
//里边的是匿名函数,也叫回调函数(就是等过了两秒后回过头来再调用这个函数)
//返回值是个定时器,这个方法是在未来去执行某个函数
var timer = setInterval( function(){
console.log(123) },2000 )
//如果时间未到,或者中途不想让他执行了,就需要取消这个定时器
clearInterval(timer)
3.浏览器还有一个自己的数据库
//localStorage只要不人为删除,会浏览器被删除数据会一直在
//增加或修改一个
window.localStorage.setItem("name","lucy")
//获取
window.localStorage.getItem("name")
//删除一个
window.localStorage.removeItem("name")
//清空
window.localStorage.clear()
==================================================
//sessionStorage网页被关闭就没有了
//增加或修改一个
window.sessionStorage.setItem("name","lucy")
//获取
window.sessionStorage.getItem("name")
//删除一个
window.sessionStorage.removeItem("name")
//清空
window.sessionStorage.clear()
4、弹窗
alert()
//弹出确认框
confirm("你确定吗?")
//弹出信息框
prompt("填写你的手机号!")
5.history
//回退
history.go(-1)
//向前
history.go(1)
//回退
history.back()
//向前
window.history.forward()
注意事项
在BOM中,调用的方法或属性其实是属于window对象
最外层定义一个方法或变量是赋给window对象
我们平时都没写window.啥
写一些全局变量尽量避开name,因为window里有name属性,你定义的把别人覆盖了
五、事件
一般给元素节点绑定一个事件
1.定义事件
- addEventListener
var div1 = document.getElementById("div1");
div1.addEventListener('click',function(){
console.log("click");
})
- onclick
var div1 = document.getElementById("div1");
div1.onclick = function(){
console.log("click")
}
- 标签内使用
<div class="content aaa" onclick="test(123)" id="div1" name="bbb"></div>
<script type="text/javascript">
function test(){
console.log("test");
}
</script>
2.清除事件
(1)方式一
div1.onclick = null
或
div1.onclick = false
(2).方式二
这里必须把回调函数定义在外边,不能使用匿名回调
var callback = function(){
console.log("click")
}
var div1 = document.getElementById("div1");
//添加一个事件
div1.addEventListener('click',callback)
//移除一个事件
div1.removeEventListener('click',callback)
3.事件分类
- 鼠标事件
(常用)
onclick:点击某个对象时触发
ondblclick:双击某个对象时触发
onmouseover:鼠标移入某个元素时触发
onmouseout:鼠标移出某个元素时触发
(知道,不用)
onmouseenter:鼠标进入某个元素时触发
onmouseleave:鼠标离开某个元素时触发
onmousedown:鼠标按下时触发
onmouseup:鼠标抬起时触发
onmousemove:鼠标被移动时触发
onwheel:鼠标滚轮滚动时触发
oncontextmenu:点击鼠标右键时触发
- 键盘事件
onkeydown:键盘的键按下时触发
onkeyup:键盘的键放开时触发
onkeypress:按下或按住键盘键时触发
- 表单事件
常用
onfocus:元素获得焦点时触发
onblur:元素失去焦点时触发
onchange:元素内容改变时触发
oninput:元素获取用户输入时触发
- 文档、浏览器对象事件
onload:元素加载完时触发
其他基本不用吧
六、事件冒泡和捕获
1、事件捕获
捕获型事件(event capturing):事件从最不精确的对象(document 对象)开始触发,然后到最精确(也可
以在窗口级别捕获事件,不过必须由开发人员特别指定)
2、事件冒泡
冒泡型事件:事件按照从最特定的事件目标到最不特定的事件目标(document对象)的顺序触发。
就是说从大到小或是从小到大
先捕获后冒泡
addEventListener的第三个参数如果是false表示在冒泡阶段处理回调函数,如果是true表示在捕获阶段 处理回调函数。
ul.addEventListener('click',function(event){
console.log('ul')
event.stopPropagation(); //阻止事件冒泡
},true)
七、相关语法深入
1.arguments
方法默认传入的形参
方法会将调用时传入的所有参数封装成一个类数组。 js对传参要求的非常灵活,基本上就是想怎么传就怎么传。
就是说我没写形参列表有个arguments会替我接收
function test(){
for( let i = 0 ; i < arguments.length ; i++ ){
console.log(arguments[i])
}
}
test(1,'2342',34,456,678,789,null);
//结果如下
VM1546:3 1
VM1546:3 2342
VM1546:3 34
VM1546:3 456
VM1546:3 678
VM1546:3 789
VM1546:3 null
2.this
this总是指向调用这个方法的实例对象
eg.
let dog = {
name: 'teddy',
say: function (a,b) {
var that = this;
console.log(a,b)
setTimeout(function(){
console.log('my name is ' + that.name)
}, 1000);
}
}
dog.say();
// 这里say方法调用时的this指向调用say的dog对象,
// 而setTimeout方法调用时是由window对象负责调用,
// 所以setTimeoue的this指向window。
// 如果要在setTimeout内使用dog对象需要在外边进行保存
this指向的改变
使用call、apply、bind可以改变this的指向
1、第一个参数都是新的this对象
2、从第二个参数开始,需要传递say方法的实参,
3、call是以多个参数的方式传递,而apply是以数组形式传递
4、bind不能直接执行方法,而是返回一个方法,需要另行执行
//我认为类似于构造方法,重新new,导致this指向的改变
dog.say.call({name: '刘奇'},12,23)
dog.say.apply({name: '刘奇'},[23,45])
var fn = dog.say.bind({name: '刘奇'})
fn()
3.作用域
全局作用域只有一个,每个函数又都有作用域(环境)。
- 编译器运行时会将变量定义在所在作用域
- 使用变量时会从当前作用域开始向上查找变量,找到window终止,这告诉我们别轻易定义全局变量
- 函数每次调用都会创建一个新作用域
- 函数被执行后其环境变量将从内存中删除。
外界访问不到函数内部定义的变量,
子函数使用时父级环境将被保留(相当于那种我再次去访问一个方法,里面的相关变量还存有上一次的值)
eg.
function hd() {
let n = 1;
return function() {
let b = 1;
return function() {
console.log(++n);
console.log(++b);
};
};
}
let a = hd()();
a(); //2,2
a(); //3,3
另一方面
for (let i = 0; i < 10; i++) {
setTimeout(() => {
console.log(i);
}, 500);
}
//这个能打印0-10
//如果把let改为var会打印10次10
//let有块级作用域,var不存在
// for循环中使用 let/const 会在每一次迭代中重新生成不同的变量
4.闭包使用(待补充)
闭包指子函数可以访问外部作用域变量的函数特性,即使在子函数作用域外也可以访问。如果没有闭包 那么在处理事件绑定,异步请求时都会变得困难。
eg.
//闭包,函数里面返回函数,内部可能会包持对外部变量的引用
function fn() {
var nums = 10;
return function() {
return nums
}
}
var add = fn()
console.log(fn()()) //一个括号返回一函数再加一个就是里面函数结果
//闭包函数实现一个加法器,
function count() {
var num = 0;
return function() {
return num++
}
}
var adder = count()
console.log(adder())
console.log(adder())
console.log(adder())
adder = null //释放掉,可能造成内存溢出,由于一直存在
可能出现的问题:内存泄露
闭包特性中上级作用域会为函数保存数据,从而造成的如下所示的内存泄漏问题
八、原型
每个对象都有一个原型 prototype 对象,通过函数创建的对象也将拥有这个原型对象。原型是一个指向 对象的指针。
//函数有一个prototype属性,当函数作为构造函数时,new出来的对象的 __proto__ 指向prototype
function User(name,age) {
this.name = name;
this.age = age;
}
//函数有一个prototype属性,当函数作为构造函数时,new出来的对象的 __proto__ 指向prototype
//我们可以写一些抽取出来共性的方法或属性在里面,当调用时也能找到
User.prototype.gander = '男'
User.prototype.eat = function () {
console.log('吃饭')
}
let user1 = new User('张三',12)
let user2 = new User('李四',13)
九、正则表达式
正则表达式是由一个字符序列形成的搜索模式,搜索模式可用于文本搜索和文本替换以及文本检测。
JS正则表达式的创建有两种方式: new RegExp() 和 直接字面量。
var re=new RegExp ();
//RegExp 是JS中的类,同Array类似。然而这个创建方法没有指定表达式内容
re=new RegExp ("a");
//最简单的正则表达式,将匹配字母a
re=new RegExp ("a","i");
//重载的构造函数,其第二个参数指定将不区分大小写也可以 g :全文查找;
===================================
var re=/a/i;
//其作用同:re=new RegExp ("a","i"),而且更常用。
相关方法
在 JavaScript 中,RegExp 对象是一个预定义了属性和方法的正则表达式对象。
test() 方法
test() 方法用于检测一个字符串是否匹配某个模式,如果字符串中含有匹配的文本,则返回
true ,否则返回 false 。
//以下实例用于搜索字符串中的字符 "e":
var patt = /e/;
patt.test("The best things in life are free!");
字符串中含有 "e",所以该实例输出为:
true
============================
以上两行代码可以合并为一行:
/e/.test("The best things in life are free!")
exec() 方法
exec() 方法用于检索字符串中的正则表达式的匹配。
该函数返回一个数组,其中存放匹配的结果。如果未找到匹配,则返回值为 null 。
以下实例用于搜索字符串中的字母 e :
/e/.exec("The best things in life are free!");
字符串中含有 "e",所以该实例输出为:
e
字符串对象中与正则表达式有关的方法
正则表达式通常用于两个字符串方法 : search() 和 replace() 。
-
检索与正则表达式相匹配的子字符串,并返回子串的起始位置。
/使用正则表达式搜索 "Runoob" 字符串,且不区分大小写: var str = "Visit Runoob!"; var n = str.search(/Runoob/i); //输出结果为: 6
2.用于检索字符串中指定的子字符串。
search 方法可使用字符串作为参数。字符串参数会转换为正则表达式:
//检索字符串中 "Runoob" 的子串:
var str = "Visit Runoob!";
var n = str.search("Runoob");
replace() 方法
replace() 方法将接收字符串作为参数:
var str="Visit W3CSchool!";
var n=str.replace("W3CSchool","Runoob");
console.log(n);
//结果Visit Runoob!
console.log(str);
//结果Visit W3CSchool!
jQuery
jQuery 是一个 JavaScript 库。
兼容主流浏览器:支持 IE 6.0+、Chrome、Firefox 3.6+、Safari 5.0+、Opera等。
具有的特有链式语法和短小清晰的多功能接口。
具有高效灵活的 CSS 选择器,并且可对 CSS 选择器进行扩展。
拥有便捷的插件扩展机制和丰富的插件。
一、下载使用相关
1.共有两个版本的 jQuery 可供下载:一份是精简过的(min),另一份是未压缩的(供调试或阅读)。
这两个版本都可从 jQuery.com 下载。
不想下载可以从 Google 或 Microsoft 加载 CDN jQuery 核心文件。
也可以用 BootCDN
BootCDN 是 猫云 联合 Bootstrap 中文网 共同支持并维护的前端开源项目免费 CDN 服务
https://www.bootcdn.cn/
中文文档
https://jquery.cuishifeng.cn/
2.使用jQuery的三个步骤:
- 引入jQuery文件
- 入口函数
- 功能实现
关于jQuery的入口函数:
//DOM文档加载步骤
(1) 解析HTML结构。
(2) 加载外部脚本和样式表文件。
(3) 解析并执行脚本代码。(按文档代码顺序加载解析)
(4) 构造HTML DOM模型,由抽象语法树构造成的DOM树。//$().ready
(5) 加载图片等外部文件。
(6) 页面加载完毕。
//第一种写法
$(document).ready(function() {
});
//第二种写法
$(function() {
});
//$符号也可以直接换成jQuery
- JavaScript的入口函数要等到页面中所有资源(包括图片、文件)加载完成才开始执行。onload 事件
- js中如果有多个入口函数,最后的会覆盖前面的
- jQuery的入口函数只会等待文档树加载完成就开始执行,并不会等待图片、文件的加载。
- jQuery中如果有多个入口函数,会顺序执行
页面效果实现类的js应该放在body之前,动作,交互,事件驱动,需要访问dom属性的js可以放在body之后
jq对象和dom对象
- DOM对象:使用JavaScript中的方法获取页面中的元素返回的对象就是dom对象。
- jQuery对象:jquery对象就是使用jquery的方法获取页面中的元素返回的对象就是jQuery对象。
- jQuery对象其实就是DOM对象的包装集,包装了DOM对象的集合(伪数组)。
- DOM对象与jQuery对象的方法不能混用。
转化
var obj = $(domObj); *// $(document).ready(function(){});就是典型的DOM对象转jQuery对象*
var li = $("li")[i]; *//jQuery包装集是一个集合,通过索引器访问其中第一个元素。通过索引器返回的不再是jQuery包装集,而是一个DOM对象。
二、jquery选择器
jQuery 元素选择器和属性选择器允许通过标签名、属性名或内容对 HTML 元素进行选择。
-
jQuery选择器有很多,基本兼容了CSS1到CSS3所有的选择器,并且jQuery还添加了很多扩展性的选择器。
-
jQuery选择器虽然很j多,但是选择器之间可以相互替代,就是说获取一个元素,你会有很多种方法获取到。
所以我们平时真正能用到的只是少数的最常用的选择器。
1.jQuery 元素选择器
名称 | 用法 | 描述 |
---|---|---|
ID选择器 | $(“#id”); | 获取指定ID的元素 |
类选择器 | $(“.class”); | 获取同一类class的元素 |
标签选择器 | $(“div”); | 获取同一类标签的所有元素 |
并集选择器 | $(“div,p,li”); | 使用逗号分隔,只要符合条件之一就可 |
交集选择器 | $(“div.redClass”); | 获取class为redClass的div元素 |
2.层级选择器
名称 | 用法 | 描述 |
---|---|---|
子代选择器 | $(“ul>li”); | 使用>号,获取儿子层级的元素,注意,并不会获取孙子层级的元素 |
后代选择器 | $(“ul li”); | 使用空格,代表后代选择器,获取ul下的所有li元素,包括孙子等 |
总结:跟css的选择器用法一模一样。
3.过滤选择器
名称 | 用法 | 描述 |
---|---|---|
:eq(index) | $(“li:eq(2)”).css(“color”, “red”); | 获取到的li元素中,选择索引号为2的元素,索引号index从0开始 |
:odd | $(“li:odd”).css(“color”, “red”); | 获取到的li元素中,选择索引号为奇数的元素 |
:even | $(“li:even”).css(“color”, “red”); | 获取到的li元素中,选择索引号为偶数的元素 |
总结:这类选择器都带冒号
名称 | 用法 | 描述 |
---|---|---|
children(selector) | $(“ul”).children(“li”) | 相当于$(“ul>li”),子类选择器 |
find(selector) | $(“ul”).find(“li”); | 相当于$(“ul li”),后代选择器 |
siblings(selector) | $(“#first”).siblings(“li”); | 查找兄弟节点,不包括自己本身。 |
parent() | $(“#first”).parent(); | 查找父亲 |
eq(index) | $(“li”).eq(2); | 相当于$(“li:eq(2)”),index从0开始 |
next() | $(“li”).next() | 找下一个兄弟 |
prev() | $(“li”).prev() | 找上一次兄弟 |
筛选选择器的功能与过滤选择器有点类似,但是用法不一样,筛选选择器主要是方法。
jQuery 属性选择器
jQuery 使用 XPath 表达式来选择带有给定属性的元素。
$("[href]") //选取所有带有 href 属性的元素。
$("[href='#']") //选取所有带有 href 值等于 "#" 的元素。
$("[href!='#']") //选取所有带有 href 值不等于 "#" 的元素。
$("[href$='.jpg']") //选取所有 href 值以 ".jpg" 结尾的元素。
注意:
第一:多用ID选择器。即使不存在 ID 选择器,也可以从父级元素中添加一个 ID 选择器,这样就会缩短节点访问的路程。
第二:少直接使用 class 选择器。可以使用复合选择器,例如,使用 tag.class 代替 .class。文档的标签是有限的,但是类可以拓展标签的语义,那么在大部分情况下,使用同一个类的标签也是相同的。当然,对于不必要的复合表达式就应该进行简化,例如 #id2#id1 或者tag#id1 表达式,不如直接使用 #id1即可。
第三:多用父子关系,少用嵌套关系。例如,使用parent>child 代替 parent child。因为 “>” 是 child 选择器,只从子节点中匹配,不递归。 而 ”“表示为后代选择器,递归匹配所有子节点及子节点的子节点,即后代节点。
第四:缓存 jQuery 对象。如果选出结果不发生变化,则不妨缓存 jQuery 对象,这样就可以提高系统性能,养成缓存 jQuery 对象的习惯可以让你在不经意间就能够完成主要的性能优化。
详细性能测速:https://blog.csdn.net/zyb2010yaonuli/article/details/84531821
jQuery 操作元素属性
<head>
<meta charset="utf-8">
<title>操作元素的属性</title>
</head>
<body>
<!--
操作元素的属性
属性的分类:
固有属性:元素本身就有的属性(id、name、class、style)
返回值是boolean的属性:checked、selected、disabled
自定义属性:用户自己定义的属性
attr()和prop()的区别:
1. 如果是固有属性,attr()和prop()方法均可操作
2. 如果是自定义属性,attr()可操作,prop()不可操作
3. 如果是返回值是boolean类型的属性
若设置了属性,attr()返回具体的值,prop()返回true;
若未设置属性,attr()返回undefined,prop()返回false;
1. 获取属性
attr("属性名")
prop("属性名")
2. 设置属性
attr("属性名","属性值")
prop("属性名","属性值")
3. 移除属性
removeAttr("属性名");
总结:
如果属性的类型是boolean(checked、selected、disabled),则使用prop()方法;否则使用attr()方法。
-->
<input type="checkbox" name="ch" checked="checked" id="aa" abc="aabbcc"/> aa
<input type="checkbox" name="ch" id="bb" /> bb
</body>
<script src="js/jquery-3.4.1.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
/* 获取属性 */
// 固有属性
var name = $("#aa").attr("name");
console.log(name);
var name2 = $("#aa").prop("name");
console.log(name2);
// 返回值是boolean的属性(元素设置了属性)
var ck1 = $("#aa").attr("checked"); // checked
var ck2 = $("#aa").prop("checked"); // true
console.log(ck1);
console.log(ck2);
// 返回值是boolean的属性(元素未设置属性)
var ck3 = $("#bb").attr("checked"); // undefined
var ck4 = $("#bb").prop("checked"); // false
console.log(ck3);
console.log(ck4);
// 自定义属性
var abc1 = $("#aa").attr("abc"); // aabbcc
var abc2 = $("#aa").prop("abc"); // undefined
console.log(abc1);
console.log(abc2);
/* 设置属性 */
// 固有属性
$("#aa").attr("value","1");
$("#bb").prop("value","2");
/*.设置多个属性*/
$('#aa').attr({
'name':'tom',
'age':'18'
});
// 返回值是boolean的属性
$("#bb").attr("checked","checked");
$("#bb").prop("checked",false);
// 自定义属性
$("#aa").attr("uname","admin");
$("#aa").prop("uage",18);
/* 移除属性 */
$("#aa").removeAttr("checked")
</script>
jQuery 操作元素样式
/*操作元素的样式
attr("class") 获取元素的样式名
attr("class","样式名") 设置元素的样式 (设置样式,原本的样式会被覆盖)
addClass("样式名") 添加样式 (在原来的样式基础上添加样式,原本的样式会保留,如果出现相同样式,则以样式中后定义的为准)
css() 添加具体的样式(添加行内样式)
css("具体样式名","样式值"); 设置单个样式
css({"具体样式名":"样式值","具体样式名":"样式值"}); 设置多个样式
removeClass("样式名") 移除样式
*/
eg.
jQuery CSS 选择器可用于改变 HTML 元素的 CSS 属性。
$("p").css("background-color","red");
/*2.设置多个样式*/
$('p').css({
'color':'green',
'font-size':'20px'
});
jQuery 操作元素内容
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>操作元素的内容</title>
</head>
<body>
<h3><span>html()和text()方法设置元素内容</span></h3>
<div id="html"></div>
<div id="html2"></div>
<div id="text">北京</div>
<div id="text2"><h2>北京</h2></div>
<input type="text" name="uname" id="op" value="oop" />
</body>
<!--
操作元素的内容
html() 获取元素的内容,包含html标签(非表单元素)
html("内容") 设置元素的内容,包含html标签(非表单元素)
text() 获取元素的纯文本内容,不识别HTML标签(非表单元素)
text("内容") 设置元素的纯文本内容,不识别HTML标签(非表单元素)
val() 获取元素的值(表单元素)
val("值") 设置元素的值(表单元素)
表单元素:
文本框text、密码框password、单选框radio、复选框checkbox、隐藏域hidden、文本域textarea、下拉框select
非表单元素:
div、span、h1~h6、table、tr、td、li、p等
-->
<script src="js/jquery-3.4.1.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
// html("内容") 设置元素的内容,包含html标签(非表单元素)
$("#html").html("<h2>上海</h2>");
$("#html2").html("上海");
// html() 获取元素的内容,包含html标签(非表单元素)
var html = $("#html").html();
var html2 = $("#html2").html();
console.log(html);
console.log(html2);
// text("内容") 设置元素的纯文本内容,不识别HTML标签(非表单元素)
//$("#text").text("北京");
//$("#text2").text("<h2>北京</h2>");
// text() 获取元素的纯文本内容,不识别HTML标签(非表单元素)
var txt = $("#text").text();
var txt2 = $("#text2").text();
console.log(txt);
console.log(txt2);
// val() 获取元素的值(表单元素)
var val = $("#op").val();
console.log(val);
// val("值") 设置元素的值(表单元素)
$("#op").val("今天天气不错");
</script>
</html>
三、动画
1.基本动画
/*注意:动画的本质是改变容器的大小和透明度*/
/*注意:如果不传参数是看不到动画*/
/*注意:可传入特殊的字符 fast normal slow*/
/*注意:可传入数字 单位毫秒*/
/*1.展示动画*/
$('li').show();
/*2.隐藏动画*/
$('li').hide();
/*3.切换展示和隐藏*/
$('li').toggle();
2.滑入滑出
/*注意:动画的本质是改变容器的高度*/
/*1.滑入动画*/
$('li').slideDown();
/*2.滑出动画*/
$('li').slideUp();
/*3.切换滑入滑出*/
$('li').slideToggle();
3.淡入淡出
/*注意:动画的本质是改变容器的透明度*/
/*1.淡入动画*/
$('li').fadeIn();
/*2.淡出动画*/
$('li').fadeOut();
/*3.切换淡入淡出*/
$('li').fadeToggle();
$('li').fadeTo('speed','opacity');
4.自定义动画
/*
* 自定义动画
* 参数1:需要做动画的属性
* 参数2:需要执行动画的总时长
* 参数3:执行动画的时候的速度
* 参数4:执行动画完成之后的回调函数
* */
$('#box1').animate({left:800},5000);
$('#box2').animate({left:800},5000,'linear');
$('#box3').animate({left:800},5000,'swing',function () {
console.log('动画执行完成');
});
四、DOM操作
1.创建节点
/*创建节点*/
var $a = $('<a href="http://www.baidu.com" target="_blank">百度1</a>');
2.克隆节点
/*如果想克隆事件 false true克隆事件*/
var $cloneP = $('p').clone(true);
3.添加&移动节点
/*
1.前追加子元素
指定元素.prepend(内容) 在指定元素内部的最前面追加内容,内容可以是字符串、html元素或jquery对象。
$(内容).prependTo(指定元素); 把内容追加到指定元素内部的最前面,内容可以是字符串、html元素或jquery对象。
2.后追加子元素
指定元素.append(内容) 在指定元素内部的最后面追加内容,内容可以是字符串、html元素或jquery对象。
$(内容).appendTo(指定元素); 把内容追加到指定元素内部的最后面,内容可以是字符串、html元素或jquery对象。
3.前追加同级元素
before() 在指定元素的前面追加内容
4.后追加同级元素
after() 在指定元素的后面追加内容*/
/*追加自身的最后面 传对象和html格式代码*/
$('#box').append('<a href="http://www.baidu.com" target="_blank"><b>百度3</b></a>');
$('#box').append($a);
/*追加到目标元素最后面 传目标元素的选择器或者对象*/
$('<a href="http://www.baidu.com" target="_blank"><b>百度3</b></a>').appendTo($('#box'));
$('a').appendTo('#box');
//其他方法大同小异
...........
3.删除节点&清空节点
/*1.清空box里面的元素*/
/* 清理门户 */
$('#box').empty();
/*2.删除某个元素*/
/* 自杀 */
$('#box').remove();
4.遍历元素
/*each()
jQuery的隐式迭代会对所有的DOM对象设置相同的值,但是如果我们需要给每一个对象设置不同的值的时候,就需要自己进行迭代了。
$(selector).each(function(index,element)) :遍历元素
参数 function 为遍历时的回调函数,
index 为遍历元素的序列号,从 0 开始。
element是当前的元素,此时是dom元素。
*/
$(".green").each(function(index,element){
console.log(index);
console.log(element);
console.log(this);
console.log($(this));
})
五、jQuery特殊属性操作
1.width方法与height方法
//带参数表示设置高度
$('img').height(200);
//不带参数获取高度
$('img').height();
//获取可视区宽度
$(window).width();
//获取可视区高度
$(window).height();
2.scrollTop与scrollLeft
//设置或者获取垂直滚动条的位置
//获取页面被卷曲的高度
$(window).scrollTop();
//获取页面被卷曲的宽度
$(window).scrollLeft();
3.offset方法与position方法
offset方法获取元素距离document的位置,position方法获取的是元素距离有定位的父元素的位置。
所谓绝对便宜位置offset就是获取指定元素距离浏览器窗口左上角的偏移距离
//获取元素距离document的位置,返回值为对象:{left:100, top:100}
$(selector).offset();
//获取相对于其最近的有定位的父元素的位置。
$(selector).position();
六、jQuery事件
1.事件绑定
简单事件绑定>>bind事件绑定>>delegate事件绑定>>on事件绑定
- 简单事件注册
click(handler) //单击事件
mouseenter(handler) //鼠标进入事件
mouseleave(handler) //鼠标离开事件
缺点:不能同时注册多个事件
- bind方式注册事件
//第一个参数:事件类型
//第二个参数:事件处理程序
$("p").bind("click mouseenter", function(){
//事件响应方法
});
缺点:不支持动态事件绑定
- delegate注册委托事件
// 第一个参数:selector,要绑定事件的元素
// 第二个参数:事件类型
// 第三个参数:事件处理函数
$(".parentBox").delegate("p", "click", function(){
//为 .parentBox下面的所有的p标签绑定事件
});
缺点:只能注册委托事件,因此注册时间需要记得方法太多了
- on注册事件
// 第一个参数:events,绑定事件的名称可以是由空格分隔的多个事件(标准事件或者自定义事件)
// 第二个参数:selector, 执行事件的后代元素(可选),如果没有后代元素,那么事件将有自己执行。
// 第三个参数:data,传递给处理函数的数据,事件触发的时候通过event.data来使用(不常使用)
// 第四个参数:handler,事件处理函数
$(selector).on(events,[selector],[data],handler);
on和bind的具体区别
-
bind只能给符合条件的元素本身添加事件
-
on可以将子元素的事件委托给父元素进行处理,而且可以给动态添加的元素加上绑定事件
也就是对于新添加的元素如果是on绑定,符合条件的新元素也会绑定事件,
如果是bind则不影响新元素
eg.
<ul>
<li>第一个子元素</li>
<li>第二个子元素</li>
<li>第三个子元素</li>
</ul>
<script>
//为上面li标签添加事件
//用bind
$('ul li').bind('click', function () {
console.log($(this).text());
});
//用on
$('ul').on('click','li', function () {
console.log($(this).text());
});
/*
第一用on绑定实际上是委托给了父级ul,也就是只给 一个元素绑定了事件
第二个是用选择器选择了ul下的所有li元素 依次绑定了事件
假如有很多很多子元素区别就很大了, bind会严重影响性能!
*/
//如果追加一个元素
$('ul').append('<li>第四个子元素<li>');
如果是on绑定则这个li也会有点击事件
如果是bind则没有
</script>
2.事件解绑
// 解绑匹配元素的所有事件
$(selector).off();
// 解绑匹配元素的所有click事件
$(selector).off("click");
3.触发事件
$(selector).click(); //触发 click事件
$(selector).trigger("click");
jQuery事件对象
jQuery事件对象其实就是js事件对象的一个封装,处理了兼容性。
//screenX和screenY 对应屏幕最左上角的值
//clientX和clientY 距离页面左上角的位置(忽视滚动条)
//pageX和pageY 距离页面最顶部的左上角的位置(会计算滚动条的距离)
//event.keyCode 按下的键盘代码
//event.data 存储绑定事件时J传递的附加数据
//event.stopPropagation() 阻止事件冒泡行为
//event.preventDefault() 阻止浏览器默认行为
//return false:既能阻止事件冒泡,又能阻止浏览器默认行为。
jQuery补充知识点
链式编程
通常情况下,只有设置操作才能把链式编程延续下去。因为获取操作的时候,会返回获取到的相应的值,无法返回 jQuery对象。
/*end()函数用于返回最近一次"破坏性"操作之前的jQuery对象。
当前jQuery对象可能是通过调用之前的jQuery对象的特定方法创建的,使用该函数可以返回之前的jQuery对象。
*/
end(); // 筛选选择器会改变jQuery对象的DOM对象,想要回复到上一次的状态,并且返回匹配元素/
<ul class="first">
<li class="foo">list item 1</li>
<li class="bar">list item 2</li>
</ul>
<script>
$('.first').find('.foo').css('background-color', 'red')
.end().find('.bar').css('background-color', 'green');
</script>
多库共存
jQuery使用作 为 标 示 符 , 但 是 如 果 与 其 他 框 架 中 的 作为标示符,但是如果与其他框架中的作为标示符,但是如果与其他框架中的冲突时,jQuery可以释放$符的控制权.
var c = $.noConflict();//释放$的控制权,并且把$的能力给了c
七、jQuery AJAX
异步无刷新操作(无需等待服务器返回结果; 无刷新结合我们的dom操作)
1.$.ajax
jquery调用ajax方法
格式:$.ajax({})
参数:
- type:类型,“POST"或者"GET”,默认是"GET"。get有缓存
- url:发送请求的地址。
- async:是否异步,默认是true表示异步
- data:是一个对象,连同请求发送到服务器的数据
- dataType:预期服务器返回的数据类型。如果不指定,jQuery将自动根据HTTP包含的MIME信息来智能判断。
- contentType:设置请求头
- success:是一个方法,请求成功后的回调函数。传入返回后的数据,以及包含成功代码的字符串。
- error:是一个方法、请求失败时调用此函数。传入XMLHttpRequest对象。
$("button").on("click",function(){
$.ajax({
type:"GET",
dataType:"json",//如果写了json,会将txt自动封装为json对象,如果没写,但请求的是json文件也会自动封装为json对象
url:"data.txt",
success:function(data){
console.log(data)
},
error:function(data){
alert('失败')
}
})
})
2.$.get/ $.post/ $.getJSON
其结构为:
$.get/post(url [, data] [, callback] [, type])
-
url:请求的HTML页的URL地址
-
data(可选):发送至服务器的key/value数据会未为QueryString附加到请求URL中
-
callback(可选):载入成功时回调函数(即当Response的返回状态为success才调用)自动将请求结果和状态传递给该方法
-
type(可选):服务器端返回内容的格式,包括xml,html,script,json,text
eg.
$.get();
语法:
$.get("请求地址","请求参数",function(形参){
});
$.post();
语法:
$.post("请求地址","请求参数",function(形参){
});
区别
-
GET请求会将参数跟在URL后进行传递,而POST请求则是作为HTTP消息的实体内容发送给WEB服务器。当然在Ajax请求中,这种区别对用户是不可见的。
-
GET方式对传输的数据大小有限制,通常不能大于2KB,而POST方式传递的数据量要比GET方式大得多,理论上不受限制。
-
GET方式请求的数据会被浏览器缓存起来,因此其他人就可以从浏览器的历史记录中读取到这些数据,例如账号和密码等。在某种情况下,GET方式会带来严重的安全问题。而POST方式相对来说就可以避免这些问题。
-
GET方式和POST方式传递的数据在服务器端的获取也不相同。
$.getJSON
语法:
$.getJSON("请求地址","请求参数",function(形参){
});
注:getJSON方式要求返回的数据格式满足json格式(json字符串)