javascript-基础知识汇总

面向对象

链接: 面向对象我的另外一篇文章链接

正则对象

链接:正则对象我的另外一篇文章链接

数组操作

链接: 数组操作链接看我另一篇文章.

时间操作

链接: 时间操作链接看我另一篇文章

DOM and BOM

链接: DOM and BOM我的另外一篇文章链接

函数

链接: 函数我的另外一篇文章链接

Json 操作

Json用法: var json = {name:“zhangsan”,age:21} 键值对

    获取方法: alert(json.name)    结果是 zhangsan

        数组获取方法json.arr[]  以下标方式

推荐写法: var json = {“name”:“zhangsan”,“age”:21} 最好都加引号

改值的两种方法: json.name="jia" 或者 json["name"]="jia"

注意:json能包数组反而数组也能包json。

   数组获取里面json的方法是: arr[0].name   下标加json值名,就能访问数组里面的json。

JSONP : JSON with padding

1.script标签

2.用script标签加载资源是没有跨域问题的

在资源加载进来之前定义好一个函数,这个函数接收一个参数(数据),函数里面利用这个参数做一些事情
    
然后需要的时候通过script标签加载对应远程文件资源,当远程的文件资源被加载进来的时候,就会去执行

我们前面定义好的函数,并且把数据当作这个函数的参数传入进去。

for in 遍历json

用法:for(var attr in json){alert(attr);} 找到json里面每一个键名

    alert(json[attr])  找到json里面的每一个键的值

如果遍历数组,用法:

   for(var attr in json){

       for(var i=0;i<json[attr].length;i++){

    alert(json[attr][i])
    };
};

字符串操作

charAt(); 查找字符串的位置

用法:var str =“王者荣耀”

alert(str.charAt(0));     结果:王

charCodeAt(); 根据字符查找编码。

0-9的编码段 :48-57

a-z的编码段 :97-122

A-Z的编码段 :65-90

用法:var str =“0123”
alert(str.charCodeAt(0)); 结果:48


fromCharCode(); 根据编码查找字符

用法:
alert(String.fromCharCode(48)); 结果:0


indexOf();从左往右

lastIndexOf();从右往左 查找字符串的位置

用法:

alert(str.indexOf('m',5);

参数详解 ,第一个参是查找字符串的字符名 ,第二个参数是指定从第几位开始查找。

如字符串内没有查找的对应字符,返回-1。


字符串比较
字符串比较是比较的编码值,只比较第一个字符。


substring(); 截取字符, 共两个参数 ,第一个参数是下标开始,第二个参数是下标结 束。

不给参数, 默认是从0开始到最后。 参数是负数转换为0 , 参数位置交换如第一参

数小于第二个参数,两个参数会交换位置。

split();把字符串转化成数组 与上个相比,它不交换位置。 如果参数是负数会从字符串后面往前面数。

用法:
    str.split(0,5);下标从第零个开始,第五个结束。  

转换类:
toUpperCse(); 将字母转换大写

toLowerCase();  将字母转换为小写

字符串分隔:

split(); 分隔字符串 , 分隔后成为了数组。

 用法:
    str.split(); 参数是,分隔字符串从哪开始分隔,填分隔符的开始字符。

如果不给参数,默认是整个字符串

如果参数是“”,空字符串,默认会每个都分隔一次。

第二个参数是限制分隔的个数。    

扩展join

join(), 把数组内每一项连接成一个字符串,没给参数会默认连接数组中括号内所有内容。

  参数可设置连接字符串时的连接符。

作用域

作用域

作用:操作

域:区域,范围,空间

浏览器解析js代码的步骤:

1.定义:

     找 var 和 function

2.执行:    

    函数名()        

    表达式 :能改变其值的,就是表达式

        例: alert(),= + - * / ! ++ -- number ()...

案例:

根据以上步骤解析,

    第一步,找 var 和 function
        
        a
        
        // function a(a){a= 4;alert(a);};   第一步解析完后的a    
    
        // 1        执行后a第一次的值

        // 2        执行后a第二次的值
        
    第二步,执行表达式

        弹function a(a){a= 4;alert(a);};
        
        //a = 1
            
        弹出 1

        //a = 2        这是a的最后值

        弹出 2

        报错 ...
    

根据解析得出的最后结果:

    第一次弹    function a(a){a= 4;alert(a);};

    第二次弹    1

    第三次弹    2

    最后报错,停止了往下解析

JS执行上下文

执行环境(Execution Context, EC)
当我们的代码执行时,会进入到不同的执行上下文,即不同的环境。在不同的环境中,有着不同的 scope(作用域),代码所能访问到的资源也就不同。 在 JS 中,执行环境有如下三种情况:
全局环境
代码默认运行的环境,代码执行时会首先进入全局环境。它是最外围的一个执行环境,根据 ECMAScript 实现所在的宿主环境的不同,表示全局环境的对象也不一样。在 web 浏览器中,全局环境就是 window 对象。全局变量和函数都是作为全局对象 window 的变量和方法来创建的。
函数环境
函数被调用执行时,所创建的执行环境。
eval
使用 eval 会进入一个新的执行环境,它的变量对象为全局变量对象或调用者的变量对象。由于 eval 的毒瘤属性,一般不推荐使用,可忽略。
某个执行环境中的所有代码执行完毕后,该环境被销毁,保存在环境中的变量和函数也随之销毁。这些变量和函数保存在一个叫做变量对象的对象(variableObject)中,关于变量对象将在变量对象与作用域链一文作详细探讨。
执行环境的生命周期
执行环境的生命周期大概分为两个阶段,即创建阶段和执行阶段:

  1. 创建阶段
    创建作用域链(变量对象+父级执行环境的变量对象)
    创建变量对象(包括局部变量、函数以及函数参数)
    确定 this 的指向
    由此,一个执行环境可以由包含作用域链、变量对象和 this 指针的对象组成:
    executionContextObj = {
    scopeChain: {},
    variableObject: {},
    this: {}
    }
  2. 代码执行阶段
    指定变量的值和函数的引用
    解释并执行代码
    执行环境栈(Execution Context Stack, ECS)
    浏览器中的解释器被实现为单线程,同一时间只能处理一个任务,JS 程序中多个执行环境会以栈的方式来处理,这个栈叫做执行栈。栈底永远都是全局环境(窗口关闭时弹出),栈顶就是当前正在执行的环境。前述三种情况都会创建执行环境,执行环境创建时会被压入栈顶,成为一个运行(活动)的环境,位于栈顶的环境执行完毕后就从栈顶弹出,并将环境控制权交给调用者(之前的栈),而调用者继续执行(或激活其他环境),直到它的执行环境结束。ECMAScript 程序中的执行流正是由这个方便的机制控制着。
    来看下面的例子:
var firstName = 'snow';

function getName() {
var lastName = 'John';

function fullName() {
var name = lastName + firstName;
return name;
}
var name = fullName();
return name;
}

getName();

其执行栈变化过程如下:
首先,将全局环境压入栈,开始执行代码,
直到遇到getName(),准备调用函数,创建函数 getName 的执行环境,将其压入栈顶并开始执行函数
直到遇到fullName(),准备调用函数,创建函数 fullName 的执行环境,将其压入栈顶并开始执行函数
在这里插入图片描述

函数 fullName 执行时没有再生成执行环境,执行完毕后则从栈顶弹出
在这里插入图片描述

fullName 执行栈弹出后,控制权回到了 getName 的执行栈,继续执行代码,执行完毕,从栈顶弹出
最后回到了全局环境,窗口关闭后弹出
在这里插入图片描述

结论
单线程,同步执行,只有栈顶的环境处于执行中,其余环境需要等待。
执行 JS 程序,首先进入全局环境,全局环境只有一个并在关闭窗口时弹出。
函数调用时会创建新的执行环境,包括调用自己。

响应式布局

<!--不同接口的申明,宽度= 设备宽度 device-width 页面显示的倍数,initial-scale=1 用户是否自动 user-scalable=no 为了在手机上正常显示-->

<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">

<link rel="stylesheet" href="css/style.css"><!--公共样式-->

<link rel="stylesheet" media="screen and (min-width:980px)" href="css/pc.css"><!--大于980px的时候-->

<link rel="stylesheet" media="screen and (max-width:980px) and (min-width:780px)" href="css/flat.css"><!--平板的时候-->

<link rel="stylesheet" media="screen and (max-width:780px)" href="css/mobile.css"><!--小于780px的时候-->

文档宽高,窗口事件

可视区的尺寸

    clientWidth 可视区宽度

    clientHeight 可视区高


滚动条滚动距离

    document.documentElement.scrollTop

    document.body.scrollTop

内容高

    scrollHeight 内容高

    scrollWidth  内容宽


文档宽高

    document.documentElement.offsetHeight
    document.documentElement.offsetWidth


事件

    onscroll  当滚动条滚动时触发

    onresize  当窗口大小发生改变时触发

鼠标光标代码cursor

default 默认光标(通常是一个箭头)

auto 默认。浏览器设置的光标。

crosshair 十字线。

pointer 一只手

move 移动。

e-resize 矩形框的边缘可被向右(东)移动。

ne-resize 矩形框的边缘可被向上及向右移动(北/东)。

nw-resize 矩形框的边缘可被向上及向左移动(北/西)。

n-resize 矩形框的边缘可被向上(北)移动。

se-resize 矩形框的边缘可被向下及向右移动(南/东)。

sw-resize 矩形框的边缘可被向下及向左移动(南/西)。

s-resize 矩形框的边缘可被向下移动(南)。

w-resize 矩形框的边缘可被向左移动(西)

text 指示文本。

wait 通常是一只表或沙漏

help 通常是一个问号或一个气球

事件冒泡机制

事件冒泡 :当一个元素接收到事件的时候,会把他接收的所有事件传播给他的父级,直到顶层window。

阻止冒泡 : 当前要阻止冒泡的事件函数中调用

ie :      event.cancelBubble = true

标准:  ev.stopPropagation()

事件的绑定与捕获

第一种事件绑定形式的取消 : 通过赋值取消,给改事件赋值null

第二种事件绑定形式的取消

ie : obj.detachEvent(事件名称,事件函数)

标准:obj.removeEventListener(事件名称,事件函数,是否捕获)

第二种绑定事件

给一个对象的同一个事件绑定多个不同的函数

给一个元素绑定事件函数的第二种形式

兼容:

ie: object.attachEvent(事件名字,事件函数)

    1.没有捕获

    2.事件名称有on

    3.事件函数执行顺序:标准ie,正序    非标准ie,倒序
    
    4.this指向window

    解决this指向

    call:函数下的一个方法,call方法的第一个参数可以改变函数执行过程中的内部this的指向,

          call方法第二个参数开始就是原来函数的参数列表

标准:object.addEventListener(事件名称,事件函数,是否捕获)

    1.有捕获

    2.事件名称没有on

    3.事件执行顺序是正序

    4.this指向事件触发的对象

是否捕获:默认是false  false:冒泡   true:捕获

addEventListener绑定事件需要通过event下面的preventDefault();阻止

return false 阻止的是 obj.on事件名称=fn 所触发的默认行为

事件-碰撞运动流程步骤解析:

定义X轴速度变量 = 速度系数

定义Y轴速度变量 = 速度系数

关闭定时器

创建一个定时器

Y轴速度变量加等于累加系数;

定义变量left方向属性变化值等于当前left属性值加X轴速度变量

定义变量top方向属性变化值等于当前的top属性值加Y轴速度变量

判断,如果变量top方向大于或者等于页面可视区高减元素高

    Y轴速度*=-0.8

    X轴速度*=0.8

    变量top重新赋值等于页面可视区高减元素高


    如果,变量top方向是小于或者等于0

         Y轴速度*=-1

        X轴速度*=0.8

        top变量赋值等于0


判断,如果变量left方向大于或者等于页面可视区宽度减元素宽度

    X轴速度*=-0.8

    变量left重新赋值等于页面可视区宽度减元素宽度


    如果变量left小于等于0

        X轴速度*=-0.8

        变量left赋值0


判断,如果绝对值X轴速度小于1

    X轴速度等于0

判断,如果绝对值Y轴速度小于1

    Y轴速度等于0

判断,如果X轴速度等于0并且Y轴速度等于0并且变量top等于页面可视区高减元素高

    关闭定时器

否则

    元素设置属性让left等于变量left

    元素设置属性让top等于变量top

键盘事件

onkeydown : 当键盘按键按下的时候触发事件

onkeyup : 当键盘按键抬起的时候触发事件

onkeypress 当键盘字符建按下时触发事件

event.keyCode : 数字类型 键盘按键的值 键值

ctrlKey ,shiftKey,altKey 功能键,布尔值

当一个事件发生的时候,如果ctrlkey||shiftkey||altKey是按下的状态,就返回true,否则返回false。

事件-获取鼠标位置

3D动画设置

transfrom-style:presevrve-3d;
设置到父元素上面

perspective:800px;
父级元素设置

倒影属性

-webkit-box-reflect:below 10px;

below 下倒影

left 左倒影

right 右倒影

-webkit-linear-gradient(top,rgba(0,0,0,0.5))%40,ragb(0,0,0,0.5);倒影遮盖透明

禁止拖拽代码

οndragstart=“return false”

contenteditable=“true” div变编辑框

onselectstart=‘return false’ 禁止选择文本内容

.attr(‘属性名’,‘属性值’) 加标签属性

.mousedown 鼠标按下事件

.mousemove 鼠标移动事件

.mouseup 鼠标抬起事件

.bind 绑定事件

.unbind 解除绑定事件

.append 添加

.clientX 获取鼠标x轴位置

.clientY 获取鼠标Y轴位置

创建元素与删除元素

document.createElement(标签名称) 创建元素

父级.removeChild(要删除的元素) 删除元素

父级.appendChild(要添加的元素) 向元素后面追加子元素

父级.insertBefore(新被插入的元素)在指定元素前面插入一个新元素

兼容问题

   在ie下如果第二个参数的节点不存在,会报错。
   
   在其他标准浏览器下如果第二个参数的节点不存在,则会以appendChild的形式进行添加。

父级.replaceChild(新节点,被替换节点) 替换子节点

appendChild,insertBefore,replaceChild都可以操作动态创建出来的节点,也可以操作已有节点

cloneNode(true) 克隆节点

表格的操作

操作属性

获取方式(获取到的是集合):

      tBodies 获取tbody

      tHead   获取thead

      tFoot   获取tfoot

           rows    获取tr

      cells   获取td



格式:

body

    table

        thead  /thead

        tbody  /tbody

        tfoot  /tfoot

    table

body

表格合并边框属性:border-collapse:collapse;

表单

表单 name属性控制表单,进行操作

onchange : 当值发生改变的时候触发事件

text : 当光标离开元素的时候再去判断值是否发生了变化,如果发生了变化则触发onchange事件

radio : 当选中的时候触发onchange事件

checkbox : 选择或者反选的时候触发onchange事件

select : 切换时触发onchange事件

submit
onsubmit 事件 当提交表单时触发

标签提交在form上放置一个action=‘提交的路径’

submit(); js方法提交表单

return false ; 可阻止提交表单

reset
onreset 事件 当提交表单重置时触发

return confirm(‘你确定要重置吗’); 当点击重置按钮后,

让用户选择是否真的要重置表单内容,确定返回是true ,取消返回false

onfocus : 获取焦点的时候触发该事件

onblur : 失去焦点的时候触发该事件

.focus() : 手动获得焦点

.blur() : 手动失去焦点

.select() : 选中文本

form表单提交数据

php 语法

get方式查询,

post方式修改,删除,添加

<?php

    header('content-type:trxt/html;charset=utf-8'); 声明编码

    $con = mysql_connect('localhost','root'); //连接数据库

    mysql_select_db(数据库名);指定数据库

    //新建一个数据库,创建一个表,字段Id唯一标识,字段名称username

    mysql_query('set names utf8');// 声明数据库编码
    
    $username = $_REQUEST['username'];//获取客户端输入框value值;$_REQUEST自动调制get与post

    $sql = "select(查询) *(所有) from 表 where 字段 = '值'";

    $query = mysql_query($sql); //执行查询代码,与js选择元素类似

    
    mysql_num_rows($query)// 如果用户在注册表中,找到了就返回一个长度1,否则0;    

    if($query && mysql_num_rows($query)){
        
        echo "<script>alert('已经有人注册过了')</script>"; //输出js的弹窗
        
        echo "<script>history.back()</script>";//返回前一页
    }else{
    
        $sql = "insert into 表(字段) values(值)";//检测如果该username在数据库不存在,就向数据库内添加该username
            
        $query = mysql_query($sql);//执行添加代码

        if($query){
            
            echo "<script>alert('添加成功')</script>";
            
            echo "<script>window.location = 'index.html'</script>";//返回页面
        };
    };
?>

闭包

callee

caller 返回该函数被调用函数的函数

fn.call(document,1,2)

fn.apply(document,[1,2])第二个参数就是fn中的arguments

call 更改this的指引

apply 和call基本一致,不同的是参数的传递上

Math.max() 找数组内最大的值

var arr = [0,2,5,6,9,10,22,50]

Math.max.apply(null,arr);找出数组内最大的值

闭包:函数嵌套函数,内部函数可以引用外部函数的参数和变量

垃圾回收机制:

闭包下的变量和参数是不会被回收的,而是一直存在内存当中。

而普通局部变量和参数是会使用完以后被垃圾回收机制回收回去,不会存留在内存当中。

好处:
1,变量长期驻扎在内存当中

2,避免全局变量的污染

3,私有成员的存在

用法:

1,模块化代码

2,在循环中直接找到对应元素而不需要去添加索引

模块化用法:
var c = (function(){
var a=1;
function aaa(){a++;alert(a);};
function bbb(){a++;alert(a);};
return {aaa:aaa,bbb:bbb};
})();
c.aaa(); 2
c.bbb(); 3

防止内存泄露:

IE下会引发内存泄露

var odiv = document.getElementById(‘div’);

odiv.οnclick=function(){
alert(odiv.id); 这样直接使用外部获取到的元素或者数组就会存在内存泄露
}

解决方法:

1 , window.unload=function(){
odiv.οnclick=nill;
};

2, 设置一个全局变量等于odiv.id,然后直接给这个变量为空;

EV对象

onfocus   当元素获取焦点的时候触发事件

onblur    当元素失去焦点的时候触发事件


    方法:  object.focus();给指定元素设置焦点

        object.blur(); 取消指定元素的焦点

        object.select(); 选中指定元素里面的文本内容



EV对象

event    当事件发生的时候,和当前这个对象发生的这个事件有关的一些详细的信息都会被临时保存到一个指定的地方

     注意:事件对象必须在一个事件调用的函数里面使用才有内容

兼容

    ie/chrome  : event是一个内置全局对象

    标准下 :事件对象是通过事件函数的第一个参数传入
    
    如果一个函数是被事件调用的,那么这个函数定义的第一个参数就是事件对象

兼容解决方法:

     定义一个变量  var ev = ev||event;


clientX   当一个事件发生时,鼠标到页面可视区的X轴距离

clientY      当一个事件发生时,鼠标到页面可视区的Y轴距离


ev.type    获取事件类型

ev.target || ev.srcElement    获取事件的目标元素

ev.preventDefault()  || ev.returnValue=false   阻止事件的默认行为

ev.stopPropagation() || ev.cancelBubble=true   阻止事件冒泡

ev.keyCode  : 数字类型,键盘按键的相应键值。



onmousemove   当鼠标在一个元素上面移动时触发  

  触发的频率不是像素的,而是间隔时间,在一个指定时间,如果鼠标的位置和上一次的位置发生变化,那么就会触发一次

oncontextmenu   鼠标右键事件,关闭浏览器默认右键菜单需在html上加个return false,然后到fn下面重新打开,return true。



ondragstart="return false"    禁止选中文本内容

contenteditable="true"  div变编辑框

cookie

cookie : 存储数据,当用户访问了某个网站(网页)的时候,就可以通过cookie来向访问者电脑上存储数据

    1.不同的浏览器存放的cookie位置不一样,也是不能通用的

    2.cookie的存储是以域名的形式进行区分的

    3.cookie的数据可以设置名字的

    4.一个域名下存放的cookie的个数是有限的,不同浏览器存放的个数不一样

    5.每个cookie存放的内容大小也是有限制的,不同的浏览器存放大小不一样

    当通过document.cookie来获取当前网站下的cookie的时候,得到的是字符串形式的值,他包含了当前网站下所有
    的cookie。他会把所有的cookie通过一个分号+空格的形式串联起来

    如果想长时间存放一个cookie,需要在设置这个cookie的时候同时给他设置一个过期的时间。

    cookie默认是临时存储的,当浏览器关闭进程的时候,自动销毁

语法 :

var date = new Date()

date.setDate(date.getDate()+5);设置过期时间

时间对象转字符串语法date.toGMTString();


document.cookie = '名字=值';

document.cookie=‘名字=值;expires=’+字符串格式的时间;  


特殊字符编码

内容最好编码存放,encodeURI

        encodeURI(‘你好’)

读取编码  decodeURI

        decodeURI(‘你好’)

js 面试题地址

-----------------Q&&A----------------------

服务状态码websocket
== http请求的状态码?==
200 - 请求成功
301 - 资源(网页等)被永久转移到其它URL
301:Moved Permanently — 永久重定向。
302:Found — 暂时重定向。
304:请求缓存数据
403:Forbideen — 服务器理解请求客户端的请求,但是拒绝执行此请求。跨域
404 - 请求的资源(网页等)不存在
500 - 内部服务器错误

== 跨域请求?==
1.web sockets
web sockets是一种浏览器的API,它的目标是在一个单独的持久连接上提供全双工、双向通信。(同源策略对web sockets不适用)

web sockets原理:在JS创建了web socket之后,会有一个HTTP请求发送到浏览器以发起连接。取得服务器响应后,建立的连接会使用HTTP升级从HTTP协议交换为web sockt协议。

只有在支持web socket协议的服务器上才能正常工作。
var socket = new WebSockt(‘ws://www.baidu.com’);//http->ws; https->wss
socket.send(‘hello WebSockt’);
socket.onmessage = function(event){
var data = event.data;

有使用过websocket没?怎么进行发送消息?怎么进行断连,重连?
websocket
WebSocket 实例
WebSocket 协议本质上是一个基于 TCP 的协议。
为了建立一个 WebSocket 连接,客户端浏览器首先要向服务器发起一个 HTTP 请求,这个请求和通常的 HTTP 请求不同,包含了一些附加头信息,其中附加头信息"Upgrade: WebSocket"表明这是一个申请协议升级的 HTTP 请求,服务器端解析这些附加的头信息然后产生应答信息返回给客户端,客户端和服务器端的 WebSocket 连接就建立起来了,双方就可以通过这个连接通道自由的传递信息,并且这个连接会持续存在直到客户端或者服务器端的某一方主动的关闭连接。

WebSocket可在一个单独的持久连接上提供全双工、双向通信。
WebSocket使用自定义协议,未加密的连接时ws://;加密的链接是wss://。
var webSocket=new WebSocket(“ws://”);
webSocket.send(message);
webSocket.onmessage=function(event){
var data=event.data;
… …
}
注意:
必须给WebSocket构造函数传入绝对URL;
WebSocket可以打开任何站点的连接,是否会与某个域中的页面通信,完全取决于服务器;
WebSocket只能发送纯文本数据,对于复杂的数据结构,在发送之前必须进行序列化JSON.stringify(message))。
优点:
在客户端和服务器之间发送非常少的数据,减少字节开销。
== 讲一下你对get和post请求在缓存方面的区别的理解:==
post/get的请求区别,具体不再赘述。 补充补充一个get和post在缓存方面的区别: · get请求类似于查找的过程,用户获取数据,可以不用每次都与数据库连接,所以可以使用缓存。 · post不同,post做的一般是修改和删除的工作,所以必须与数据库交互,所以不能使用缓存。因此get请求适合于请求缓存。
== 为什么利用多个域名来存储网站资源会更有效?==
CDN 缓存更方便
突破浏览器并发限制
节约 cookie 带宽
节约主域名的连接数,优化页面响应速度
防止不必要的安全问题

1.项目中的角色,遇到那些问题,怎么解决的,负责那些业务?

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值