JS学习笔记

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对象

  1. concat() 表示把几个数组合并成一个数组
  2. join() 设置分隔符连接数组元素为一个字符串
  3. pop() 移除数组最后一个元素
  4. shift() 移除数组中第一个元素
  5. slice(start,end) 返回数组中的一段
  6. splice() 可以用来删除,可以用来插入,也可以用来替换
  7. push() 往数组中新添加一个元素,返回最新长度
  8. sort() 对数组进行排序
  9. reverse() 反转数组的顺序
  10. toLocaleString() 把数组转

属性

  1. length 表示取得当前数组长度 (常用)
  2. constructor 引用数组对象的构造函数
  3. prototype 通过增加属性和方法扩展数组定义

2、Global对象

  1. escape() 对字符串编码

  2. eval() 把字符串解析为JavaScript代码并执行

  3. isNaN() 判断一个值是否是NaN

  4. parseInt() 解析一个字符串并返回一个整数

  5. parseFloat() 解析一个字符串并返回一个浮点数

  6. number() 把对象的值转换为数字

  7. string() 把对象的值转换为字符串

3、String对象

  1. charAt() 返回指定索引的位置的字符
  2. indexOf() 从前向后检索字符串,看是否含有指定字符串
  3. lastIndexOf() 从后向前检索字符串,看是否含有指定字符串
  4. concat() 连接两个或多个字符串
  5. match() 使用正则表达式模式对字符串执行查找,并将包含查找结果最为结果 返回
  6. replace() 替换一个与正则表达式匹配的子串
  7. search() 检索字符串中与正则表达式匹配的子串。如果没有找到匹配,则返回 -1。
  8. slice(start,end) 根据下表截取子串
  9. substring(start,end) 根据下表截取子串
  10. split() 根据指定分隔符将字符串分割成多个子串,并返回素组
  11. substr(start,length) 根据长度截取字符串 *
  12. toUpperCase() 返回一个字符串,该字符串中的所有字母都被转化为大写字母。
  13. toLowerCase() 返回一个字符串,该字符串中的所有字母都被转化为小写字母。

4、Math对象

  1. ceil() 向上取整。
  2. floor() 向下取整。
  3. round() 四舍五入。
  4. random() 取随机数。

5、Date对象

  1. getDate函数: 返回日期的“日”部分,值为1~31。
  2. getDay函数: 返回星期,值为0~6,0表示星期日。
  3. getHours函数: 返回日期的“小时”部分,值为0~23。
  4. getMinutes函数: 返回日期的“分钟”部分,值为0~59。
  5. getMonth函数: 返回日期的“月”部分,值为0~11。
  6. getSeconds函数: 返回日期的“秒”部分,值为0~59。
  7. getTime函数: 返回系统时间。
  8. getTimezoneOffset函数: 返回此地区的时差(当地时间与GMT格林威治标准时间的地区时差), 单位为分钟。
  9. getYear函数: 返回日期的“年”部分。返回值以1900年为基数,如1999年为99。
  10. parse函数: 返回从1970年1月1日零时整算起的毫秒数(当地时间)
  11. setDate函数: 设定日期的“日”部分,值为0~31。
  12. setHours函数: 设定日期的“小时”部分,值为0~23。
  13. setMinutes函数: 设定日期的“分钟”部分,值为0~59。
  14. setMonth函数: 设定日期的“月”部分,值为0~11。其中0表示1月,…,11表示12 月。
  15. setSeconds函数: 设定日期的“秒”部分,值为0~59。
  16. setTime函数: 设定时间。时间数值为1970年1月1日零时整算起的毫秒数。
  17. setYear函数: 设定日期的“年”部分。
  18. toGMTString函数: 转换日期成为字符串,为GMT格林威治标准时间。
  19. setLocaleString函数: 转换日期成为字符串,为当地时间。
  20. UTC函数: 返回从1970年1月1日零时整算起的毫秒数(GMT)。

三、DOM编程

js控制前端节点,与后端数据交互

在 HTML DOM (Document Object Model) 即文档对象模型中, 每个东西都是 节点 :

  • 文档本身就是一个文档对象
  • 所有 HTML 元素都是元素节点
  • 所有 HTML 属性都是属性节点
  • 元素内的文本是文本节点
  • 注释是注释节点,就不用
<div class='test1' id='a'>文本</div>
div整体是一个元素节点 
class=‘test1’ 是一个属性节点 
文本是个文本节点,注意中间没有东西空字符也是一个文本节点

所有的节点都有一个nodeType属性,可以判断节点类型,常用的就是以下

NodeTypeNamed Constant
1ELEMENT_NODE 元素节
2AATTRIBUTE_NODE 属性节点
3TEXT_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对象)的顺序触发。

就是说从大到小或是从小到大

img

先捕获后冒泡

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() 。

  1. 检索与正则表达式相匹配的子字符串,并返回子串的起始位置。

    /使用正则表达式搜索 "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 库。

  • +HTML 元素选取
  • HTML 元素操作
  • CSS 操作
  • HTML 事件函数
  • JavaScript 特效和动画
  • HTML DOM 遍历和修改
  • AJAX

兼容主流浏览器:支持 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的三个步骤:

  1. 引入jQuery文件
  2. 入口函数
  3. 功能实现

关于jQuery的入口函数:

//DOM文档加载步骤
(1) 解析HTML结构。
(2) 加载外部脚本和样式表文件。
(3) 解析并执行脚本代码。(按文档代码顺序加载解析)
(4) 构造HTML DOM模型,由抽象语法树构造成的DOM树。//$().ready
(5) 加载图片等外部文件。
(6) 页面加载完毕。
//第一种写法
$(document).ready(function() {
	
});
//第二种写法
$(function() {
    
});
//$符号也可以直接换成jQuery
  1. JavaScript的入口函数要等到页面中所有资源(包括图片、文件)加载完成才开始执行。onload 事件
  2. js中如果有多个入口函数,最后的会覆盖前面的
  3. jQuery的入口函数只会等待文档树加载完成就开始执行,并不会等待图片、文件的加载。
  4. 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(形参){
         
       });

区别

  1. GET请求会将参数跟在URL后进行传递,而POST请求则是作为HTTP消息的实体内容发送给WEB服务器。当然在Ajax请求中,这种区别对用户是不可见的。

  2. GET方式对传输的数据大小有限制,通常不能大于2KB,而POST方式传递的数据量要比GET方式大得多,理论上不受限制。

  3. GET方式请求的数据会被浏览器缓存起来,因此其他人就可以从浏览器的历史记录中读取到这些数据,例如账号和密码等。在某种情况下,GET方式会带来严重的安全问题。而POST方式相对来说就可以避免这些问题。

  4. GET方式和POST方式传递的数据在服务器端的获取也不相同。

$.getJSON
     语法:
       $.getJSON("请求地址","请求参数",function(形参){
         
       });

​ 注:getJSON方式要求返回的数据格式满足json格式(json字符串)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值