js进阶阶段总结

本文详细介绍了JavaScript的基础知识,包括变量声明、数据类型转换、三元运算以及循环结构。案例涵盖了九九乘法表、开关灯效果、动态创建列表和事件委托等应用场景。此外,还涉及了DOM操作、事件处理、jQuery库的使用,以及动画效果和表单交互。文章旨在帮助读者深入理解和应用JavaScript。
摘要由CSDN通过智能技术生成

js基础阶段总结和案例

var可以同时声明多个变量名

var str1,str2,str3;   // 同时声明多个变量名
str1 = "hello";
str2 = "Bonjour";
str3 = "hola";
// 一次性输出多个数据
console.log(str1, str2, str3);

数据类型转换

把其他转成数字: Number() 、 parseInt() 、 parseFloat()
把其他转成字符串:String() 、.toString()
把其他转成布尔: Boolean()

把其他类型转换为布尔

Boolean(数据);
只有以下几个是false,其他都是true
console.log(Boolean(0));
console.log(Boolean(''));
console.log(Boolean(null));
console.log(Boolean(undefined));
console.log(Boolean(false));
console.log(Boolean(NaN));

三元表达式

表达式1 ? 表达式2 : 表达式3
// 如果表达式1 成立, 那么就执行表达式2
// 如果表达式1 不成立, 那么就执行表达式3
//例如: 求二个数字中谁更大
var a = 10; var b = 20;
var max = a > b ? a : b;
console.log(max);

案例:九九乘法表

嵌套for循环

        var c = 0;
        for(var a=0;a<10;a++){
            for(var b=1;b<=a;b++){
                c = a*b
                document.write(a);
                document.write("*");
                document.write(b);
                document.write("=");
                document.write(c);
                document.write(" &nbsp;&nbsp;&nbsp; ")
            }
            document.write("<br>")
        }

案例:输入框密码

  1. 不断要求用户输入学生姓名,输入q结束.
  2. 要求用户输入用户名和密码,只要不是admin、888888就一直提示用户名或密码错误,请重新输入。
// 练习1 就是需要做无限循环 
do{
    var str = prompt("请输入用户名");
    if(str === "q"){
        break;// 一定要有出口,停止无限循环
    }
}while(true);

// 练习1 也可以用while循环
while(true){
    var str = prompt("请输入用户名");
    if(str === "q"){
        break;// 一定要有出口,停止无限循环
    }
}

// 练习1 用for循环解决
for(var i=1;true;){// 循环条件永远为true  不需要i++
    var str = prompt("请输入用户名");
    if(str === "q"){
        break
    }
}

// 练习2 解决方案
do {
    var username = prompt("请输入用户名");
    var password = prompt("请输入密码");

    if (username === "admin" && password === "123456") {
        alert("登录成功!");
        break;
    }

    alert("用户名或者密码错误,登录失败!");
} while (true);

// 练习2 用for循环解决
for (var i = 0; true; ) {
    var username = prompt("请输入用户名");
    var password = prompt("请输入密码");

    if (username === "admin" && password === "123456") {
        alert("登录成功!");
        break;
    }

    alert("用户名或者密码错误,登录失败!");
}

案例–机器人功能

        while(true){
            var base = prompt("请输入 \r\n 1、请输入1  打开计算机 \r\n 2、请输入2  打开歌曲推荐器  \r\n 3、请输入3   打开时间器   \r\n 4、输入q  退出机器人")
            if(base ==="1"){
                var num = prompt("请输入数学1,2,3,4 ,并用英文逗号,隔开");
                var p = num.split(",")
                var number = 0;
                for(var i =0;i<p.length;i++){
                    number += +p[i];
                }
                alert(number)
            }else if(base ==="2"){
                var long = ["光辉岁月","海阔天空","红色的高跟鞋","十年"]
               alert(long[(Math.floor(Math.random()*long.length))]);
            }else if(base ==="3"){
                var date = new Date();
                var year = date.getFullYear();
                var month = date.getMonth();
                var day = date.getDate();
                var h = date.getHours();
                var m = date.getMinutes();
                var s = date.getSeconds();

                month = month<10? "0"+month : month;
                day = day<10? "0"+day : day;
                h = h<10? "0"+h : h;
                m = m<10? "0"+m : m;
                s = s<10? "0"+s : s;

                alert(year+"年"+month+"月"+day+"日  "+h+":" +m+":"+s);


            }else if(base ==="q"){
                alert("再见!!!!")
                break;
            }else{
                alert("请按照要求输入")  
            }
       }

案例:求圆的面积和周长

        // 圆的面积
        function gets(r){
            return Math.floor( (3.14*r*r)*100)/100;
            
        }
        console.log(gets(5));

        // 圆的周长
        function getd(d){
            return Math.floor((3.14*2*d)*100)/100;
        }
        console.log(getd(2));

获取所有实参的对象:arguments

function fn(){
  console.log(arguments);
}
fn(1); // 输出 [1]
fn(1,2) // 输出 [1,2]
fn(1,2,3,4,5) // 输出 [1,2,3,4,5]

案例:求n个数字的和的问题

function getSum(){
  var sum = 0;
  for(var i = 0; i < arguments.length ; i++){
    sum += arguments[i];
  }
  return sum;
}

getSum(1,2,3);// 输出 6
getSum(1,2,3,4,5); // 输出15

非布尔值之间的逻辑运算

console.log(2 && 3); // 3
console.log(0 && 3); // 0
console.log(0 && null); // 0
// 如果是true,得到右边,如果左边是false,得到左边
// 两边都为false,返回第一个为false

console.log(2 || 3); // 2
console.log(0 || 3); // 3
console.log(0 || null); // 0
// 如果左边是true,得到左边,如果左边是false,得到右边
// 两边都为false,返回最后一个为false

短路运算在函数中的使用

  function getSum(a, b, c, d) {
    // 解决形参个数多于实参的问题 —— 参数的默认值

    // if(c === undefined){
    //   c = 0;
    // }
    // if(d === undefined){
    //   d = 0;
    // }

    c = c || 0;
    d = d || 0;
    return a + b + c + d;
  }
function fn(a,f){

  // 如果函数没有传递进来我们想要调用就会报错
  // 判断有没有传递进来,如果传递了,我们才调用
  // if(f !== undefined){
  //   f();
  // }

  f && f();
}

工厂函数创建对象

封装成函数

function createObj() {
	var obj = new Object(); 
    obj.name = '阿伟';
    obj.sayName = function(){
        console.log('你好,我叫阿伟');
    }
}

遍历对象

语法:

for(var key in obj){
    console.log(key);// 键名
    console.log(obj[key]); // 每个key对应的键值
}

获取数组的最大值

        getMax:function(){
            var max = arguments[0];
            for(var a =0;a<arguments.length;a++){
                if(max<arguments[a]){
                    max = arguments[a]
                }
            }
            return console.log(max)
        },

forEach 遍历数据的方法

// 作用: 遍历数组
arr.forEach(function(item,index){
  item 是数组里面的每个元素
  index 是数组的每个索引
})

js进阶阶段总结和案例

修改文本内容

修改元素的显示文本内容                 _butt.onclick = function(){
                                        // _box.innerText = "今天晴转多云"//修改文本内容

向一个元素中插入一段 HTML                       _box.innerHTML = "<h3>今天中雨到大雨</h3>"
                                    }

案例:随机切换窗口颜色

点击按钮切换窗口(document.body)的背景色(随机切换rgb颜色)

        var _butt = document.getElementsByTagName("button")[0];
        console.log(_butt);

        // 十六进制的换背景
        // _butt.onclick = function () {
        //     var arr = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"];
        //     var color = "#"
        //     for (var i = 0; i < 6; i++) {
        //         color += arr[Math.floor(Math.random() * 16)]
        //     }
        //     console.log(color);
        //     document.body.style.background = color;
        // }

        // rgb颜色
        _butt.onclick = function () {
            var color = "rgb("
            var arr = []
            for (var i = 0; i < 3; i++) {
                arr[i] = Math.floor(Math.random() * 256);
            }
            console.log(arr);
            color +=arr[0]+","+arr[1]+","+arr[2]+")"
            console.log(color);
            document.body.style.background = color;
        }

获取输入框的值

        _butt.onclick = function(){
            console.log(_inp.value);
            _inp.value = "";  //初始化操作
        }

其他事件类型

双击    		 butt.ondblclick = function(){
                    alert("双击")
                }
鼠标移入         getId("ch").onmouseover = function(){
                    console.log("鼠标移入");
                }
鼠标移出         getId("ch").onmouseout = function(){
                    console.log("鼠标移出");
                }
聚焦            getId("ch").onfocus = function(){
                    console.log("聚焦");
                }
失焦            getId("ch").onblur = function(){
                    console.log("失焦");
                }
值改变           getId("ch").onchange = function(){
                    console.log("值改变");
                }

禁止输入效果

        butt.onclick = function(){
            getId("inp").disabled = true; // 禁止输入
        }

点击选框选中效果

        butt.onclick = function(){
            getId("ch2").checked = true;

        }
        
        false

修改多个样式

style. 样式 = “ 值 ”

// 思路:将多个样式写成对象的形式作为参数,传递给一个函数
var obox = document.getElementById("box");
// 函数封装
function setCss(ele, css) {
    for (var key in css) {
        ele.style[key] = css[key];
    }
}
// 调用函数,传递参数
setCss(obox, {
    width: "300px",
    height: "300px",
    backgroundColor: "red"
})

js 修改css样式(增加/删除)

        var butt = document.getElementsByTagName("button")[0];
        function getId(ele){
            return document.getElementById(ele);
        }

        butt.onclick = function(){
            // getId("box").className = "dv new"
            getId("box").classList.add("new")//增加类名
            getId("box").classList.remove("dv")//删除类名
        }

为多个元素绑定事件(this)

var btn = document.getElementById("btn");//获取id为btn的元素
btn.onclick = function () {
   //根据标签名字获取标签
   var pObjs = document.getElementsByTagName("p");
   //无论获取的是一个标签,还是多个标签,最终都是在数组中存储的,这行代码的返回值就是一个数组
   console.log(pObjs);
   //循环遍历这个数组
   for(var i =0; i < pObjs.length; i++){
      //每个p标签,设置文字
      pObjs[i].innerText = "我们都是P标签";
   }
};

for循环为每个元素绑定事件

案例:多个元素绑定事件

        // 伪数组使用for循环遍历
        for (var i = 0;i<lis.length;i++){
            // for是同步,点击事件是异步
            lis[i].onclick = function(){
                // 事件处理程序中,this就是事件源
                console.log(this.innerText);
            }

排他思想案例

**排他思想案例:**点击当前按钮高亮显示,其他同级按钮取消高亮显示

for循环里面套for循环

var btn = document.getElementsByTagName("button");
for(var i=0;i<btn.length;i++){
    btn[i].onclick = function(){
        // 1.先处理所有元素,做初始化操作
        for(var j = 0;j<btn.length;j++){
            btn[j].style.background = "none";
        }
        // 2.再修改当前元素
        this.style.background = "#cfc";
    }
}

点击按钮修改input的类型和内容

var btnObj = document.getElementById("btn");
btnObj.onclick = function () {
    //修改按钮的value属性
    //btnObj.value = "我是按钮我被修改了";
     this.value = "我是按钮我被修改了";
     this.type = "text";
     this.id = "btn2";//审查元素看到id也是可以被修改的
}

开关思想

开关思想:定义一个变量, 这个变量决定了一个状态,事件触发的时候,根据这个变量的值,执行对应的操作,操作完还需要修改这个变量的值。

// 需要一个变量存储状态
var flag = true;
get_id("btn").onclick = function () {
    // console.log("点击事件触发了");
    // if(flag==true){
    if (flag) {
        // 把div的left值改成-200px
        my$("box").style.left = "-200px";
        // 需要把flag改成false,防止下一次点击这个flag还是true,如果flag还是true,就会一直走这里的代码
        flag = false
    } else {
        my$("box").style.left = "0px";
        // 防止下一次点击flag还是false,就还是会走这里的代码
        flag = true
    }
}

开关灯案例

  1. 当点击"关 灯"按钮时,将body背景颜色设置成黑色,同时将 “关 灯” 设置成 “开 灯”;
  2. 当点击"开 灯"按钮时,将body背景颜色设置成白色,同时将 “开 灯” 设置成 “关 灯”.
 var btn = document.getElementById("btn");
    btn.onclick = function () {
    // document.body可以获取body标签
 /* if (flag) {
        document.body.className = "cls"
        flag = false
    } else {
        document.body.className = ""
        flag = true
    } */
        
    // 其实只需要判断当前body的类名是不是cls
    // document.body.className = 条件 ? true : false
        //叫做 三元表达式 三目运算符
    document.body.className = document.body.className != "cls"?"cls":"";
}

开关灯案例

方法一:更改图片地址
		公共部分函数
        function getId(ele) {
            return document.getElementById(ele)
        };
        function getEla(la, th) {
            return getId(la).getElementsByTagName(th);
        };

        console.dir(getEla("bg", "img")[0].src);//打印对象属性

        

        var flag = true;
        getId("bg").onclick = function(){
        点击——判断用if
            if(flag){
                getEla("bg", "img")[0].src = "./开灯.jpg";
                flag = false;
            }else{
                getEla("bg", "img")[0].src = "./关灯.jpg";
                flag = true;
            }
        }

tab栏案例

var btns = document.getElementsByTagName("span");
var pages = document.getElementsByTagName("li");
for (var i = 0; i < btns.length; i++) {
    btns[i].index = i;
    btns[i].onmouseenter = function () {
        for (var j = 0; j < btns.length; j++) {
            btns[j].className = "";
            pages[j].className = "";
        }
        this.className = "current";
        pages[this.index].className = "current";
    };
}

全选反选功能

js实现

//获取全选的这个复选框
var ckAll = get_id("j_cbAll");
//获取文字显示span
var txt = get_id("txt");
//获取tbody中所有的小复选框
var cks = get_els("j_tb", "input");
//点击全选的这个复选框,获取他当前的状态,然后设置tbody中所有复选框的状态
ckAll.onclick = function () {
    console.log(this.checked);
    for (var i = 0; i < cks.length; i++) {
        cks[i].checked = this.checked;
    }
    //顺便修改文本显示
    txt.innerText = this.checked ? "全不选" : "全选";
};

//获取tbody中所有的复选框,分别注册点击事件
for (var i = 0; i < cks.length; i++) {
    /* cks[i].onclick = function () {
             var flag = true; //默认都被选中了
             //判断是否所有的复选框都选中
             for (var j = 0; j < cks.length; j++) {
                 if (!cks[j].checked) {
                     //没选中就进来了
                     flag = false;
                     break;
                 }
             }
             //全选的这个复选框的状态就是flag这个变量的值
             ckAll.checked = flag;
             //记得修改文本显示
             txt.innerText = flag?"全不选":"全选";
         };  */
    cks[i].onclick = fn;
}

// 反选功能
// 获取按钮
var btn = get_id("rev");
btn.onclick = function () {
    for (var i = 0; i < cks.length; i++) {
        cks[i].checked = !cks[i].checked
    }
    fn();
}

// 代码复用,函数封装
function fn() {
    var flag = true; //默认都被选中了
    //判断是否所有的复选框都选中
    for (var j = 0; j < cks.length; j++) {
        if (!cks[j].checked) {
            //没选中就进来了
            flag = false;
            break;
        }
    }
    //全选的这个复选框的状态就是flag这个变量的值
    ckAll.checked = flag;
    //记得修改文本显示
    txt.innerText = flag ? "全不选" : "全选";
}

jQuery实现


点击按钮设置div中p标签改变背景颜色

get_id("btn").onclick = function () {
    //先获取div
    var dvObj = get_id("dv");
    //获取里面所有的子节点
    var nodes = dvObj.childNodes;
    //循环遍历所有的子节点
    for (var i = 0; i < nodes.length; i++) {
        //判断这个子节点是不是p标签
        if (nodes[i].nodeType == 1 && nodes[i].nodeName == "P") {
            nodes[i].style.backgroundColor = "red";
        }
    }
};

自定义增加属性

    //获取li元素的集合
    var lis = getEls("uu","li")
    // console.log(lis);

    //遍历
    for(var i = 0;i<lis.length;i++){
        //新增属性
        lis[i].setAttribute("socur",(i+4)*10);
        //事件绑定
        lis[i].onclick = function(){

            //点击触发弹窗
            alert(this.getAttribute("socur"))
        }
    }
//设置自定义属性:
element.setAttribute("属性名","属性值");
//获取自定义属性:
element.getAttribute("属性名");
//移除标签行内属性
element.removeAttribute("属性名");

动态添加列表项

<input id="txt" type="text">
<button id="btn">添加</button>
<ul id="box"></ul>

get_id("btn").onclick = function(){
    var txt = get_id("txt").value;
    console.log(txt);
    get_id("box").innerHTML =  get_id("box").innerHTML + `<li> ${txt} </li>`
    get_id("txt").value = "";
}

案例:表单创建列表(非空校验:空和空格都排除)

        var butt = document.getElementsByTagName("button")[0];
        // console.log(butt);

        butt.onclick = function(){

            var txt = getId("inp").value;
            // console.log(txt);

            if(txt){//判断输入框是否为空
                //在文本内容中追加插入li
                getId("tet").innerHTML +="<li>"+txt+"</li>";
                //清空输入框
                getId("inp").value = ""

            }else(
                alert("输入框不能为空")
            )

        }

动态创建列表

<button id="btn">创建列表</button>
<div id="dv"></div>

 var names = ["杨过", "郭靖", "张无忌", "张三丰", "乔峰", "段飞", "丁棚"];
 get_id("btn").onclick = function () {
     // 将整个列表看成一个字符串,先创建开头的ul
     var str = "<ul>";
     // 根据数据遍历循环创建li
     for (var i = 0; i < names.length; i++) {
         str += `<li>${names[i]}</li>`;
     }
     str += "</ul>"
     console.log(str);
     get_id("dv").innerHTML = str;
 }

动态创建列表

<button id="btn">创建列表</button>
<div id="dv"></div>

var names = ["杨过", "郭靖", "张无忌", "张三丰", "乔峰", "段飞", "丁棚"];
get_id("btn").onclick = function () {
    // 先创建元素ul
    var box = document.createElement("ul");
    // 遍历循环数据,创建li
    for(var i=0;i<names.length;i++){
        var li = document.createElement("li");
        // 写入文本
        li.innerText = names[i];
        // 每一次遍历都将li追加进ul中
        box.appendChild(li);
    }
    console.log(box);
    // 盒子追加元素ul
    get_id("dv").appendChild(box);
}

案例:动态创建列表

var names = ["杨过", "郭靖", "张无忌", "张三丰", "乔峰", "段飞", "丁棚"];

        getId("btn").onclick = function(){
            if(!getId("uu").innerText){
                names.forEach(function(item){
                    getId("uu").innerHTML +="<li>"+ item +"</li>"
                })
            }
        }

动态创建表格

//创建表格
var otab = document.createElement("table");
// 直接将表格插入到body中
document.body.appendChild(otab);
get_id("btn").onclick = function () {
    var rowVal = Number(get_id("row").value);
    var colVal = Number(get_id("col").value);
    //创建tr 行
    for (var i = 0; i < rowVal; i++) {
        var otr = document.createElement("tr")
        otab.appendChild(otr);
        // 创建td 列
        for (var j = 0; j < colVal; j++) {
            var otd = document.createElement("td")
            otr.appendChild(otd);
            otd.innerText = `我是第${i+1}行${j+1}列`;
        }
    }
}

案例:动态创建表格(非空校验:去除空格和空字符、文字)

    var _tab = document.createElement("table")
    document.body.appendChild(_tab);

    getId("btn").onclick = function(){
        //获取输入内容的值(异步获取)
        var _row = +getId("row").value;//+就是转换成数字
        var _col = +getId("col").value;

//判断输入的值,输入框文本校验
//没内容————————""------------------false
// 非数字———————————NaN-----------------false
//0 ,0 ————————————0------------------false


        if(_row && _col){
            // 遍历
            for(var i = 0;i<_row;i++){
                var _tr = document.createElement("tr")
                _tab.appendChild(_tr);
                // 遍历
                for(var j=0;j<_col;j++){
                    var _td = document.createElement("td")
                    _tr.appendChild(_td);

                    _td.innerText = "第"+(i+1)+"行第"+(j+1)+"列";
                }
            }
        }else{
            alert("请输入正确的格式!!")
        }

    }

替换删除

// 最前插入新节点
btn.onclick = function () {
    var newli = document.createElement("li");
    newli.innerText = "皇叔败走投袁绍";
    uu.insertBefore(newli, uu.children[0])
}

var orep = document.querySelectorAll(".rep");
var odel = document.querySelectorAll(".del");

// console.log(orep);
// console.log(odel);

// 给每一条数据的替换和删除按钮绑定事件
for (var i = 0; i < orep.length; i++) {
    orep[i].onclick = function () {
        var newli = document.createElement("li");
        newli.innerText = "定三分隆中决策";
        uu.replaceChild(newli, this.parentElement)
    }
    odel[i].onclick = function () {
        uu.removeChild(this.parentElement)
    }
}

事件对象兼容处理

get_id("btn").onclick = function(e){
    var e=e || window.event // 兼容IE8
    console.log(e);
}

//e.pageX——表示鼠标距离,网页左上角的水平距离
//e.pageY——表示鼠标距离,网页左上角的垂直距离
//e.target——返回触发此事件的元素(事件的目标节点)

阻止事件冒泡


get_id("dv1").onclick = function (e) {
    console.log(e);
    // console.log(e.target);
}
get_id("dv2").onclick = function (e) {
    console.log(this.id);
}
get_id("dv3").onclick = function (e) {
    console.log(this.id);
    // var e=e||window.event;
    // e.cancelBubble=true;
    e.stopPropagation();
}

阻止事件默认行为


get_id("wolf").onclick = function (e) {
    console.log(this.id);
    var e = e || window.event;
    if (e.preventDefault) {
        e.preventDefault();
    } else {
        e.returnValue = false;
    }
}

事件委托

//事件冒泡的应用(事件委托)
get_id('ul').onclick = function (e) {
    //e.target:获取真正触发事件的那个元素
    //console.log(e.target);
    var target = e.target;
    // 只操作li元素
    if (target.nodeName == "LI") {
        target.style.backgroundColor = '#cfc';
    }
}

前后插入最新的节点(动态插入)

    getId("btn1").onclick = function () {
        var lis1 = document.createElement("li")
        lis1.innerHTML = "最前插入新节点 <button class='rep'>替换</button> <button class='del'>删除</button>"
        getId("uu").insertBefore(lis1, getId("uu").children[0])

    }
    getId("btn2").onclick = function () {
        var lis2 = document.createElement("li");
        lis2.innerHTML = "最后插入新节点 <button class='rep'>替换</button> <button class='del'>删除</button>"
        getId("uu").appendChild(lis2)

    }

动态插入节点(绑定新节点事件)

    getId("uu").onclick = function (e) {
        var e = e || window.event;
        var tag = e.target;
        console.log(tag);
        if (tag.className == "del") {
            getId("uu").removeChild(tag.parentElement)
        }else if(tag.className == "rep"){
            
            tag.parentElement.innerHTML = "插入替换新节点 <button class='rep'>替换</button> <button class='del'>删除</button>";
            getId("uu").replaceChild(newli, tag.parentElement)
        }
    };

事件绑定

<div id="dv">
    <button id="btn">按钮</button>
</div>
    
//对象.addEventListener("事件类型",事件处理函数,false);
//参数1:事件的类型---事件的名字,没有on
//参数2:事件处理函数---函数(命名函数,匿名函数)
//参数3:布尔类型,默认false-----指定事件是否在捕获(true )或冒泡(false)阶段执行
    
//为同一个元素绑定多个相同的事件
get_id("btn").addEventListener("click", function () {
    console.log("我是第一个点击事件");
}, false);
//为同一个元素绑定多个相同的事件
get_id("btn").addEventListener("click", function () {
    console.log("我是第二个点击事件");
}, false);
//为同一个元素绑定多个相同的事件
get_id("btn").addEventListener("click", function () {
    console.log("我是第三个点击事件");
}, false);
//验证第三个参数
 get_id("dv").addEventListener("click", function () {
     console.log("我是div的点击事件");
 }, true);

案例:多个元素绑定事件(通过父级绑定)

        getId("uu").onclick = function(e){
            var e = e || window.event;//IE8兼容
            //e.target  获取目标元素
            if(e.target.nodeName == "LI"){  //获取目标类名为  li的元素
                console.log(e.target);
                e.target.style.background = "red";
            }
        }

事件解绑

语法:

// 0级事件解绑:直接将dom.onclick = null;

// addEventListener对应的事件解绑(掌握)
对象.removeEventListener("事件类型",事件处理函数,false);
// attachEvent对应的事件解绑(了解)
对象.detachEvent("on事件类型",事件处理函数);

举例:

// get_id("btn1").addEventListener("click", function () {
//     console.log("第一个");
// }, false);
//  get_id("btn1").addEventListener("click", function () {
//     console.log("第二个");
// }, false);
// //点击第二个按钮把第一个按钮的第一个点击事件解绑
//  get_id("btn2").onclick = function () {
//      get_id("btn1").removeEventListener("click", function () {
//         console.log("第一个"); //这样就没解绑成功,因为是两个匿名函数,不是同一个函数
//     }, false)
// }

//解绑事件的时候,需要在绑定事件的时候,使用命名函数,否则解绑的不是一个函数
function f1() {
    console.log("第一个");
}
function f2() {
    console.log("第二个");
}
get_id("btn1").addEventListener("click", f1, false);
get_id("btn1").addEventListener("click", f2, false);
//点击第二个按钮把第一个按钮的第一个点击事件解绑
get_id("btn2").onclick = function () {
    get_id("btn1").removeEventListener("click", f1, false);
}

入口函数

window.onload = function () {
	//此时body还没渲染,btn是不存在的
	var btn = document.getElementById("btn");
    btn.onclick = function () {
         alert("哈哈");
 	}
}

BOM

window对象:是浏览器的顶级对象,全局对象。

  1. alert 等一系列弹框方法
  2. open方法:打开新窗口
  3. close方法:关闭当前窗口
  4. document对象:HTML 文档
  5. location对象:包含当前网页文档的URL信息
  6. history对象:包含浏览器窗口访问过的URL信息
  7. navigator对象:包含有关浏览器的信息,如名称,版本和系统等。
  8. 定时器

Location 对象

location.href  ——  获取完整URL

History 对象

- length属性——历史记录的长度(个数)。
- back() 方法——向后跳转,加载 history 列表中的前一个 URL。
- forward()方法——向前跳转,加载 history 列表中的下一个 URL。
- go()方法——加载 history 列表中的某个具体页面,参数 1 表示向前跳转,-1表示向后跳转。

前后跳转页面案例

//第一个页面
    console.log(window.history);
    var oBtn = document.getElementById('btn');
    oBtn.onclick = function () {
        if (history.length == 1) {
            location.href = "last.html"
        } else {
            history.forward(); // 向前跳转
            // history.go(1);
        }
    }
    
//第二个页面
    console.log(history);
    var oBtn = document.getElementById('btn');
    oBtn.onclick = function () {
        history.back();  // 向后跳转
        // history.go(-1);
    }

偏移量offset

var oBox = document.getElementsByTagName('div')[0];
console.log(oBox.offsetLeft); // 到文档左侧的距离
console.log(oBox.offsetTop); // 到文档顶部的距离
console.log(oBox.offsetWidth); // 获取盒子的实际占位宽度(border+contentWidth+padding)
console.log(oBox.offsetHeight); // 获取盒子的实际占位高度(border+contentHeight+padding)
console.log("-------------------------------------");
var spanTag = document.getElementsByTagName('span')[0];
console.log(spanTag.offsetLeft); // 到父盒子左侧的距离(前提是父盒子有定位,没定位则直接索引到body)
console.log(spanTag.offsetTop); // 到父盒子顶部的距离(前提是父盒子有定位,没定位则直接索引到body)
console.log(spanTag.offsetWidth); // 获取span的实际占位宽度(border+contentWidth+padding)
console.log(spanTag.offsetHeight); // 获取span的实际占位高度(border+contentHeight+padding)
console.log(spanTag.offsetParent); // 相对父级元素(默认指向body)

滚动scroll

var oBox = document.getElementById('box');
var oContent = document.getElementById('content');
var oBtn = document.getElementById("btn")
console.log(oContent.scrollWidth); // 内容盒子的可滚动宽度
console.log(oContent.scrollHeight); // 内容盒子的可滚动高度

console.log(oBox.scrollWidth); // 限定了宽高的父盒子中,其内容盒子可滚动的宽度
console.log(oBox.scrollHeight); // 限定了宽高的父盒子中,其内容盒子可滚动的高度

oBtn.onclick = function () {
    console.log("-------------------------");
    console.log(oBox.scrollTop); // 获取内容盒子相对于父盒子已经滚动了多少高度
    console.log(oBox.scrollLeft); // 获取内容盒子相对于父盒子已经滚动了多少宽度
}

客户区client

// 获取盒子的Y坐标
var boxTop = box.offsetTop;
console.log(boxTop);
// scroll 滚动事件
window.onscroll = function () {
    // 获取文档滚出的距离
    var winTop = document.documentElement.scrollTop;
    console.log(winTop);
    // 每当滚动的时候都需要获取超出窗口的范围  然后和盒子Y坐标做对比
    // 如果滚动距离大于等于盒子Y坐标,就设置成固定定位,否则去掉盒子定位
    if (winTop >= boxTop) {
        box.style.position = "fixed";
        box.style.top = 0;
    } else {
        box.style.position = "static";
    }
}

吸顶导航案例

需求: 窗口发生滚动的时候,盒子固定在顶部

        var header = getId("header");
        // 盒子本身到窗口顶部的距离
        var ot = header.offsetTop;
        console.log(ot);  // 275


        window.onscroll = function(){
            // 窗口发生滚动的时候执行这里的代码

            // 获取页面的scrollTop,  获取页面超出窗口的距离
            console.log(document.documentElement.scrollTop);  // 页面滚动的时候这个值越来越大
            // 把header变成固定定位
            // console.log("执行了window.onscroll");
            var st = document.documentElement.scrollTop;
            if(st>=ot){
               
                // 把header盒子变成固定定位
                header.style.position = "fixed";
                header.style.top = "0";
            }else{
                header.style.position = "static";
            }
        }

单次定时器

// 单次定时器,只能执行一次
setTimeout(function () { },time);
// - 参数1:function 必需。函数,过time时间之后执行的业务逻辑。
// - 参数2:time 可选。执行或调用 function 需要等待的时间,以毫秒ms计。默认为 0。1s=1000ms

// 清除setTimeout单次定时器
clearTimeout(定时器名称);
var timer = setTimeout(function () {
    console.log("单次定时器");
}, 2000);

//点击按钮清除定时器
var btn = document.getElementById("btn");
btn.onclick = function () {
    clearTimeout(timer);
    console.log("已经清除");
}

循环定时器

// 循环定时器,不停歇,每过一段时间time,执行一次。
setInterval(function () { },time);
// 参数同setTimeout

// 清除setInterval循环定时器
clearInterval(定时器名称);
var timer = setInterval(function () {
    alert("循环定时器");
},2000);

//点击按钮清除定时器
var btn = document.getElementById("btn");
btn.onclick = function () {
    clearInterval(timer);
}

盒子动画(上下前后移动)(js实现)

        var _box = document.getElementById("box");
        var _btn = document.getElementById("btn");
        var _box1 = document.getElementById("box1");

        console.log(_box, _btn);

        var timer = null
        var num = 0
        var flag = true;

        _btn.onclick = function () {
            clearInterval(timer)

            timer = setInterval(function () {

                if (flag) {
                    num += 2;
                    _box.style.left = num + "px";
                    _box.style.top = num + 30 + "px";
                    if (num > 500) {
                        flag = false;
                    } 
                } else {
                    num -= 2;
                    _box.style.left = num + "px";
                    _box.style.top = num + 30 + "px";
                    if (num < 0) {
                        flag = true;
                    }
                }

            }, 10)
        }

无缝轮播(js实现)

        var _oul = document.getElementById("oul")
        var num = 0;
        setInterval(function(){
            num-=5;
            if(num<-1200){
                num = 0;
            };
            _oul.style.left = num +"px";

        },30)

设置div的宽度(进度条)

 get_id("btn").onclick = function () {
     // 初始宽度
     var width = 200;
     // 开启定时器
     var timer = setInterval(function () {
         // 每次加10
         width += 10;
         // 设置临界值,最大只能是800
         if (width >= 800) {
             // 清除定时器
             clearInterval(timer);
         }
         // 实时设置div宽度
         get_id("dv").style.width = width + "px";
     }, 20);
 };

随机点名系统

//创造虚拟后台数据
var arrs = ["宋江", "卢俊义", "吴用", "公孙胜", "林冲", "花荣", "鲁智深", "武松", "李逵", "晁盖", "燕青", "潘金莲", "阎婆惜", "关胜", "秦明", "呼延灼", "陈达", "张青", "刘唐", "李俊", "张顺", "高俅", "孙二娘", "戴宗", "朱仝", "方腊", "阮小二", "李瓶儿", "庞春梅", "白胜", "吕方", "董平", "穆春", "宋清", "柴进", "施恩", "李忠", "周通", "杜兴", "时迁", "曹正", "宋万", "杨志", "镇关西", "西门庆"];

// 创建姓名列表
arrs.forEach(function (item, index) {
    // console.log(item,index);
    var nameNode = document.createElement("div");
    nameNode.innerText = item;
    nameNode.className = "name";
    get_id("box").appendChild(nameNode);
})

// 点名功能
var timer =null;
get_id("btn").onclick = function () {
    if (this.innerText === "点名") {
        // 开启定时器
        timer = setInterval(function () {
            // 清空所有颜色 排他
            for (var i = 0; i < arrs.length; i++) {
                get_id("box").children[i].style.background = "";
            }
            // 留下当前颜色
            var random = parseInt(Math.random() * arrs.length);
            get_id("box").children[random].style.background = "red";
        }, 10);
        this.innerText = "停止";
    } else {
        //清除计时器
        clearInterval(timer);
        this.innerText = "点名";
    }
}

获取验证码 案例

此时按钮不可点击,60s读完,按钮才恢复正常

js代码

        /*
        原生js
        
         btn.onclick=function(){
            this.disabled = true;
            var s = 5;
            var _this = this;
            var timer = setInterval(function(){
                // 定时器中的this指向window
                // console.log(_this);
                _this.innerText = --s +"秒后再点击";
            },1000)
            setTimeout(function(){
                // s秒后....
                clearInterval(timer);
                _this.innerText = "获取验证码";
                _this.disabled = false;
            },s*1000)
        } */

jQuery实现

        $("#btn").click(function () {
            $(this).prop("disabled",true);
            var s = 5;
            var timer = setInterval(function () {
                $("#btn").text(--s + "秒后再点击");
            }, 1000)
            setTimeout(function () {
                // s秒后....
                clearInterval(timer);
                $("#btn").text("获取验证码");
                $("#btn").prop("disabled",false);
            }, s * 1000)
        })

导航栏菜单(手风琴效果)案例

jQuery实现

        $("ul>li").hover(function(){
            // ol的移入显示移出隐藏
            // $(this).children("ol").toggle();
            $(this).children("ol").stop().slideToggle();
        })

文字随机闪烁案例

需求:点击按钮获取随机换文字颜色

        function getId(ele){
            return document.getElementById(ele);
        };

        var color = ["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"];
        var str = "#";
        var timer = null;
        var num = 0;

        getId("btn").onclick = function(){
            clearInterval(timer);
            if(this.innerText === "启动"){

                timer =  setInterval(function(){
                num = 0;
                str = "#";
                for(var i=0;i<6;i++){


                    num = parseInt(Math.random()*color.length);
                    str +=color[num];
                }
                getId("ht").style.color = str;
            },10);
            this.innerText = "停止"
            }else{
                clearInterval(timer);
                this.innerText = "启动";
            }

        }

jQuery实现

事件绑定

        // 可以绑定多个事件
        // 语法:
        // $("选择器").事件类型(function(){事件处理程序}
        // 没有封装的事件需要用on
        $('body').on('touchstart', function () {
            $('p').css({'background': '#f00'});
            console.log("用户手指触摸到屏幕...");
        });

显示、隐藏与切换

语法:

$(selector).show(time); // 显示, time表示动画时长,单位为毫秒,下同
$(selector).hide(time); // 隐藏
$(selector).toggle(time); // 切换
//注意:凡是函数都要加 括号,函数就是所谓的方法,方法就是函数!
 // eq(索引)就是获取元素列表对应索引的某个元素——是一个JQ对象
// 点击第1个按钮,让显示的元素隐藏
$('button:eq(0)').click(function(){
    // 参数 - 动画过渡时间(500)
    $('div').hide(500);
})

// 点击第2个按钮,让隐藏的元素显示
$('button:eq(1)').click(function(){
    $('div').show();
})

// 点击第3个按钮,切换元素的隐藏显示
$('button:eq(2)').click(function(){
    $('div').stop().toggle(300);//动画阻断
})

JQ中访问和修改文本

语法:

$(selector).html();	 // 获取与修改选择器中的html内容
$(selector).text();	 // 获取与修改选择器中的文本内容

$('div').text('我是div标签');
$('div').html('<p>我是p标签</p>');
        $("#box").click(function(){
            // html变化
            // $(this).html("<p>第一次变化</p>")

            // 文本修改
            // $(this).text("第二次变化")

            // 清空
            $("#box").text("")
        });

jQuery对象和DOM对象相互转换

不同对象之间是不能使用对方的方法的。也就是说JS的对象只能JS调用,如果JQ想要用的话,就必须进行对象转换。比如:this<------>$(this)

$("div").click(function(){
	$(this).html("文本内容")
})

JS转JQ对象

// 使用$()包裹起来就可以用转成成JQ对象
document.getElementsByTagName(element)    
==>   
$( document.getElementsByTagName(element) )

JQ转JS对象

// 方法一:
$(element).get(0)  ==> document.getElementsByTagName(element)
// 方法二:
$(element)[0]  ==> document.getElementsByTagName(element)

css样式修改

语法:

$(selector).css()  
第一种为单属性修改:
$(selector).css('key', 'value');    //只能修改一个属性和一个属性值

第二种为多属性修改:
$(selector).css({
  'key': 'value',
  'key': 'value'
   ....
})                      //可以多属性修改,理论上可以修改无限多个属性

标签属性的修改

prop:操作原生表单属性

$("#ch1").prop("checked",false);

自定义属性使用——attr

            // 修改a标签的属性
            // $("a").attr({
            //     href:"https://sirius.wolfcode.cn/#/",
            //     target:"_blank",
            // }).text("天狼星")

        // 链式编程
        $("a").attr("href","https://sirius.wolfcode.cn/#/").attr("target","_blank").text("天狼星");

jQuery常用选择器

基础选择器

基本选择器语法功能
ID选择器$(’#ID’)找到匹配指定ID的元素
元素(标签)选择器$(‘element’)找到指定的元素
class选择器$(’.class’)找到匹配指定class的元素
通配符选择器$(’*’)匹配所有元素
并集(组合)选择器$(‘sel,sel’)多个选择器匹配的元素合并
层级选择器语法功能
后代选择器$(‘parent child’)当前元素的所有后代元素
直接后代选择器$(‘parent>child’)当前元素所有的子元素
下一个兄弟$(‘prev+next’)当前元素的下一个元素
后面所有兄弟$(‘prev~siblings’)当前元素后面的所有兄弟元素

筛选选择器

基本筛选选择器语法
获取第一个元素$(‘ele:first’)
获取最后一个元素$(‘ele:last’)
获取指定索引的元素$(‘ele:eq(index)’) 方法eq(index)
获取所有元素除某个$(‘ele:not(selector)’)
获取索引为偶数的元素$(‘ele:even’)
获取索引为奇数的元素$(‘ele:odd’)
获取大于该索引元素$(‘ele:gt(index)’)
获取小于于该索引元素$(‘ele:lt(index)’)
获取所有标题类型元素$(‘ele:header’)

级别选择器

$(selector).parent() 表示选中所有匹配元素的唯一父元素。

案例:关闭悬浮广告

// 原生JS方法:
// 选中所有button
var oBtns = document.getElementsByTagName('button');
for(var i=0;i<oBtns.length;i++){
    oBtns[i].onclick = function(){
        // 找到父级,把父级display=none
        // console.log( this.parentNode );
        this.parentNode.style.display = "none";
    }
}

// JQ方法:
$('button').click(function(){
    // 选择这个按钮的父级 - 这个$(this)     父级.parent()
    $(this).parent().hide();
})

siblings方法

$(selector).siblings() 表示选中某个元素同级的元素,括号内有写元素,表示选中同级的某个元素,如果没有书写,则表示选中同级的所有元素!

案例:排他思想

// 原生JS方法
var btns = document.getElementsByTagName('button');
for(var i=0;i<btns.length;i++){
    btns[i].onclick = function(){
      for(var k=0;k<btns.length;k++){
          btns[k].style.background = "none";
      }
      this.style.background = "pink";
    }
}

// JQ方法:
$('button').click(function(){
    // siblings()兄弟节点,
    // 两个方法都是作用于$(this)的,可以使用链式编程
    $(this).css('background', 'skyblue').siblings('button').css('background', 'none');
})
        $("button").click(function(){
            $(this).css("background","#cfc").siblings().css("background","none");
        })

children方法

$(selector).children() 表示选中某个元素的子级元素,括号内有写元素,表示选中子级中的某个元素,如果没有书写,则表示选中子级的所有元素!

案例:《书城特效》

// 原生JS方法
var lis = document.getElementsByTagName('li');
for(var i=0;i<lis.length;i++){
    // 鼠标移入
    lis[i].onmouseenter = function(){
        // 让p标签隐藏
        this.children[0].style.display = "none";
        // 让img显示
        this.children[1].style.display = "block";
    }
    // 鼠标移出
    lis[i].onmouseleave = function(){
        // 让p标签显示
        this.children[0].style.display = "block";
        // 让img隐藏
        this.children[1].style.display = "none";
    }
}

// JQ 方法

// 初级解决方案
// mouseover 、 mouseout 是一对儿,机制相同。会冒泡
// mouseenter 、 mouseleave是一对儿,机制相同。不冒泡
$('li').mouseenter(function(){
  $(this).children('img').show().siblings().hide();
})
$('li').mouseleave(function(){
  $(this).children('p').show().siblings().hide();
})

// 中级解决方案
$('li').hover(function(){
  $(this).children('img').show().siblings().hide();
}, function(){
  $(this).children('p').show().siblings().hide();
})

// 高级解决方案
$('li').hover(function(){
  $(this).children().toggle();
})

案例:菜单栏下拉效果

        $("ul > li").hover(function(){
            $(this).children("ol").slideDown("slow");
        },function(){
            $(this).children("ol").slideUp("slow");
        })

动态设置class的方法

索引值方法

在JS中,一堆元素的排序是按照索引值来排列的,索引值是从0开始,并且用index来表示.

在JQ中,**index()**是一个方法(函数),所以必须加括号!用来获取当前元素在父级中的索引值。

语法:

$(selector).index();// 获取索引值方法
// 原生方法
var btns = document.getElementsByTagName("button");
for (var i = 0; i < btns.length; i++) {
    btns[i].setAttribute("myindex", i);
    btns[i].onclick = function () {
      	console.log(this.getAttribute("myindex"));
    };
}

// JQ index方法
$("button").click(function(){	
  var index = $(this).index();
  console.log(index);
})

addClass与removeClass方法

语法:

// 给某个元素添加类名,理论上,一个标签可以添加无数多个类名,用空格分开
$(selector).addClass(“className1  className2  className3”)

// 给某个元素移除类名
$(selector).removeClass(“className1  className2  className3”)

案例:Tab栏

// 原生方法
var btns = document.getElementsByTagName("span");
var pages = document.getElementsByTagName("li");
for (var i = 0; i < btns.length; i++) {
    btns[i].index = i;
    btns[i].onmouseenter = function () {
        for (var j = 0; j < btns.length; j++) {
            btns[j].className = "";
            pages[j].className = "";
        }
        this.className = "current";
        pages[this.index].className = "current";
    };
}

// JQ方法
$("span").hover(function () {
    var index = $(this).index();
    $(this).addClass("current").siblings().removeClass("current");
    $("li").eq(index).addClass("current").siblings().removeClass("current");
});

toggleClass

语法:

// 切换某个元素的类名(添加或删除)
$(selector).toggleClass(“className”)

案例:百度风云榜

$('span').click(function(){
  // 让当前列表切换收放
  $(this).toggleClass('open').siblings('ol').slideToggle();
  // 让其他列表收起
  $(this).parent().siblings().children('ol').slideUp().siblings('span').removeClass('open');
})

// 代码优化:
// 链式编程:在一个方法后调用另一个方法
// 原理:每一个方法都会去找最近的一个对象(事件源)
	// 本质上是每个函数末尾加了return this,将调用该函数的jquery对象返回
	// 同时由于只对 DOM 进行了一轮查找,性能方面更加出色。
$('span').click(function(){
  $(this).toggleClass('open')// "当前span"
    	 .siblings('ol')// 将事件源"当前span"变成了"当前ol"
          .slideToggle()// "当前ol"
          .parent()// 将"当前ol"变成了"当前父级li"
          .siblings()// 将"当前父级li"变成了"其他父级li"
          .children('ol')// 将"其他父级li"变成了"其他父级的ol"
          .slideUp()// "其他父级的ol"
          .siblings('span')// 将"其他父级的ol"变成了"其他父级的span"
          .removeClass('open');// "其他父级的span"
})

表单相关方法

获取input 或 textarea 的值

// ()内部写入文本可以实现修改功能
$('input').val()
$('textarea').val()

获取select下拉框的值

<select id="selectBrowser">
    <option value="1">pc</option>
    <option value="2">phone</option>
    <option value="3">pad</option>
</select>
<script>
    $("#selectBrowser").change(function(){
        console.log($(this).val());
    })
</script>

trim去除前后空格

表单输入时去除前后空格,我们可以用:

$.trim()
// 通常来说提交表单时,输入框的值是不允许为空的,并且包括空格,这样的数据是无意义的,此时需要做校验,提示用户重新输入
var val = $('input').val();
if( $.trim(val)=="" ){
  	alert('请重新输入');
}

增加子节点

// 在某个元素的子级中,往后面添加节点
$(element).append('子节点')
// 在某个元素的子级中,往前面添加节点
$(element).prepend('子节点')

增加同级节点

// 在element之前添加兄弟节点
$(element).before('兄弟节点') 
// 在element之后添加兄弟节点
$(element).after('兄弟节点') 
   //往前面添加节点
        $("#btn1").click(function(){
            $(".uu").prepend("<li>111111111111111</li>")
        });
        
   //往后面添加节点
        $("#btn2").click(function(){
            $(".uu").append("<li>111111111111111</li>")
        })
        
   //之前添加兄弟节点
        $("#btn3").click(function(){
            $(".po").before("<p>9999999999999999</p>")
        });
        
   //之后添加兄弟节点
        $("#btn4").click(function(){
            $(".po").after("<p>9999999999999999</p>")
        });

节点的删除

语法:

// 将element节点中的子级节点包括内容清空
$(element).empty();
// 删除element节点包括内容
$(element).remove();
$('button').eq(0).click(function(){
  $('ul').empty();  // 清空ul中的内容
})

$('button').eq(1).click(function(){
  $('ul').remove(); // 直接删除ul
})

节点的替换

语法:

// 用后者替代前者
$(element1).replaceWith(element2);
$('button').click(function(){
    // p替代li
    $('li').eq(1).replaceWith(`<p>这是个p标签</p>`);
})

事件委托

定义:

事件委托是利用事件冒泡,只指定一个事件处理程序来管理某一类型的所有事件。

给一个ul里面的几个li添加了事件但是如果动态又生成了li则刚生成的li不具备事件这时就需要用到委托。

语法:

// 事件和函数是必填的,子级选择器选填(不填就是普通事件绑定)
   $(selector).on(事件,children,function(e){...})
// 1ms之后再添加一下li元素
setTimeout(function () {
  	$('ul').append('<li>6</li>')
}, 1)
// 普通事件绑定(办不到)
// $('li').click(function(){
//     var index=$(this).index()+1
//     console.log(index);
// })
// 事件委托(重点)
$('ul').on('click', 'li', function () {
    var index = $(this).index() + 1
    // 此时this指向的是‘li’
    console.log(this, index);
})

// 事件解绑
$('ul').click(function(){
    console.log(111);
})
$("button").click(function(){
    $('ul').off('click', 'li')
})

// 另一种诡异写法(JQ项目很多这样的写法)
setTimeout(function () {
  	$('ul').append('<li onclick="getIndex(this)">6</li>')
}, 1)
function getIndex(myThis){
    var index=$(myThis).index()+1
    console.log(index);
}

键盘事件

$(selector).keydown(function(){...});// 键盘按下事件
$(selector).keyup(function(){...});// 键盘松开事件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值