js第一篇(基础)

    科技2025-08-22  16

    JavaScript:依赖HTML的脚本语言(网景公司的Netscape)

    script标签:三种写法(行内,内联,外联)

    外联后script里面不需要写代码

    script可以和style一样放在页面任意位置

    初期建议放在/body和/html之间

    注释:

    // /**/

    输出语句:

    加载至文档流:document.write();用户提示:alert();删除前的进一步提示:confirm();输入框:prompt();调试,控制台输出:console.log();

    js语法要求:

    单双引号尽量保持一种 分号可加可不加,要加都加,要不加都不加

    变量:

    本质就是存数据的容器—放在内存中

    显示声明:var a = 5;

    隐式声明:b = 5;

    var a= b=c = 5;相当于 var a = 5;b = 5;c = 5;

    一次性定义多个变量:var a = 3,b,c,d;

    规则:

    变量名不能数字开头,字母数字下划线美元符号组成关键字不能作为变量名。

    变量类型:

    number:

    var a = 10;

    String:

    若干个 任意字符 引号号包含起来

    boolean

    true,false

    undefined未定义类型

    var a ;.//undefined

    object对象类型

    三种表现形式:

    数组:

    var arr =[1,2,3]

    json对象
    null关键字

    小数问题解决方案

    js进行小数计算会精度损失

    var a = 0.2,b = 0.1; var c = a + b ; console.log(c);//0.30000000000000004

    解决方案:

    方法一:乘以10除以10

    var a = 0.2; var b = 0.1; var c = (a*10 + b *10) / 10; console.log(c);

    方法二:强直保留小数点后几位 console.log(c.toFixed(3));

    NaN(not a number)

    var a = 10; var b = 'abc'; var c =a -b;//NaN console.log(c);//Number

    特点:

    跟任何数据饭都不相等,包括自己 isNaN():检测一个数字是不是数字//true不是一个数字,false是数字 100a时显示true

    字符串类型

    单引号和双引号不可以嵌套他们自身

    原因:引号虽然是字符,但是有特殊含义

    解决:单嵌套双或相反;转义字符

    注意:字符串拼接可以用加号

    js可以输出标签的,doucment.write("


    ");

    输出字符串长度:str.length

    字符串也可以+=

    运算符

    赋值运算:

    = ,+=,-=,… 作用;将右边的值赋给左边的变量

    数字运算符

    +                -                 *                /                %

    字符串拼接:加号两边都是数字才运算

    比较运算符

    >       <等等

    其中 ==是比较值的, ===是先比较类型,再比较值

    因为 == 和!=是会自动进行数据类型转换的,转成数字再比较

    强制类型转换

    转为number:

    Number():字符串纯数字才可以转为数字型,不然NaN

    布尔true为1,false为0

    undefined转数字是NaN

    null转数字是0

    parseInt();字符串前面的整数获取到

    parseFloat()字符串前面的小数获取到

    转boolean

    Boolean(要转换的数据);

    会转为false的情况;

    NaN,0,’’,undefined,null

    转字符串:

    String():就是加个引号 数据.toString(); 直接加上"";

    自动类型转换

    字符串拼接时,一边为字符串,另一边转为字符串

    比较运算时,左右有一个是数字,另一个也会被转为数字比较

    当进行除了加法以外的数学运算,会将量两边转为数字再运算

    逻辑运算

    && 与 ||或 !非 通常连接两个表达式

    控制台黑色数字为字符串类型,蓝色数字为数字类型

    三元运算符

    1 ? 2 :3; 1是正确的执行2,否则执行3 常用于双分支的替代 也可以将整个表达式赋值或者输出

    进行数字加法运算的时候一定要检测是不是数字类型

    逻辑分支

    单分支:

    if(条件){满足条件执行} 小括号内自动转换为boolean型

    双分支

    if(条件){当条件满足执行}else{不满足时执行}

    多分支

    if (条件) { 代码块 } else if ( 条件 ) { 代码块 } else if ( 条件) { 代码 块 }…else { 代码块 }(最后这个可写可不写)

    单个多分支是多选一,多个单分支是多选多

    分支语句可以简写

    switch多路判断:

    类似于多分支,只能判断一个变量跟某些值是否全等

    var num =1; switch(num){//switch小括号里面的值只能是变量 case 1:num ===1;(重点) 执行语句; break... default: 执行语句;break}

    break是可以省略的,称为case穿透

    当num=2: case 2: console.log(“hello”)//这里省略break case 3:console.log(“hello”);break;//这个就不判断了 当num=3case 3:跳过了case 2;但是倒过来写会执行case 2

    注意:

    switch的运行效率是高于分支的,因为直接到达符合条件的地方,不需要从上往下判断当判断是否相等时更加精确

    分支语句的细节

    小括号里面的可以放任何值,最终都转为boolean类型

    自增自减运算

    前缀先运算在操作,后缀先操作再运算

    总结: 字符串的比较是逐位比较的,"|10">"2"为false switch倒着写可以实现累加的效果 剩下的多少秒:秒数%60 剩下小时 = 小时数 %24

    循环

    目的:处理重复 循环小括号的变量为全局变量

    while循环:

    var i =15; while(i > 10){ i--; console.log(i); }

    do-while循环(while循环的变异)

    var i = 15; do{ i--; }while(i<10);

    至少执行一次

    for循环

    for(var i = 15;i<10;i--){ console.log(i); }
    var i = 0; for(;i<10;i++){ console.log(a); } for (int i = 0; i < 10; i+2){ console.log(i); } for (var i = 0;i < 10; salary = salary *0.1 ){ i++; }

    循环跳转:

    break:跳出当前循环; continue:跳出·此次循环,执行下次循环 continue的书写顺序要靠前,放在最后执行了效果等于没执行

    循环的嵌套

    for循环里面的还可以继续嵌套

    DEBUG:

    函数:

    目的:处理重复 可以重复利用的工具

    如何定义函数(%):

    语法:function 函数名(){ 代码段; }

    函数的定义其实是赋值过程,在内存中开辟fn的空间,fn存放代码

    函数的调用:

    函数名();//调用函数内部的代码 fn()中fn其实是数据类型(function),里面存放的是function后面的代码

    定义一个函数:

    function fn(){ console.log(123); }

    在内存的显示:

    f fn(){ console.log(123); } function //返回类型

    形参:形式上的参数

    实参:实际意义上的参数,用于给形参赋值,调用时候的小括号内,类型和个数需要和形参相对应 函数的优点:重复执行,模块化编程 函数的书写:先写核心代码,然后用函数包裹起来

    匿名函数:

    var fn=function(){//定义变量fn,赋值一个函数 console.log(123); } fn();//调用

    使用场景:事件中

    总结:函数可以没有名字,然后将函数赋值给一个变量----同样能使用

    原因:函数的定义过程,其实就是在内存空间中开辟了空间,存放一段代码作为值

    fn里面的值:

    自调用函数(匿名函数使用小括号包起来):

    匿名函数的fn代表的是:

    function(){ console.log(123); }

    那么fn()就是

    (function(){ console.log(123); })();

    也可以写成:

    ! function(){ console.log(123); }();

    !可以换成~,能看懂别人这么写就可以

    好处是什么?省去了调用

    函数提升篇:

    代码执行顺序:

    从上而下,从左至右,逐字符依次执行。只有有名字的函数才叫函数的定义(打%的地方)。

    预解析:

    从所有代码中找到变量的定义和函数的定义,找到了就会将变量的定义和函数的定义放到所有代码的最前面,然后再执行。

    注意:函数的大括号可以约束声明提升,但是if语句等的大括号不具有约束性

    var a = 10; 分为两个步骤:定义a,将a赋值为10

    题目检测:

    console.log(fn); fn(); var fn = function(){ console.log(123); }

    运行结果: undefined 报错

    fun(); var fn = function(){ console.log("我是fn函数"); } function fun(){ console.log("我是fun函数"); } fn(); fn = 100; fn();

    运行结果 我是fun函数 我是fn函数 报错

    fn(); function fn(){ console.log("我是一个fn函数"); } fn(); var fn = 100; fn();

    运行结果 我会fn函数 报错

    这里预解析的时候函数和变量重名,保留函数

    var a= b; a = 0; b = 0; console.log(a); console.log(b);

    直接报错 因为b没被定义就被使用,一定要先定义再使用

    var fun = 200; fun(); var fun = function(){ console.log("我是一个fun函数"); }

    直接报错,因为预解析后fun这个空间的值是200,不是函数,无法调用

    function fn(a){ console.log("我是fn函数"); a(); functio a(){ console.log("我是函数a"); } } fn(10);

    我是fn函数 我是函数a

    注意:形参赋值是在函数提升和参数提升之前的

    console.log(num); if(false){ var num = 100; }

    undefined

    注意:不会执行的代码也是要预解析的

    return关键字

    让一个函数返回值,后面的语句都不会执行 return只能停止函数,break只能停止循环和switch 函数中的循环可以加return 循环中的函数可以加break;

    没有return的函数默认返回undefined

    函数的书写步骤

    先写核心代码再写上函数外壳然后寻找形参,提出来

    作用域

    能起作用的区域

    在不同地方定义的函数和变量,起作用的范围是不同的

    不在任何函数内定义的变量称为全局变量

    在函数内定义的变量称为局部变量

    全局变量在局部范围内有效 局部变量在全局范围内无效

    函数定义好了就相当于创建了个作用域,任何函数都可以创建作用域

    作用域可以嵌套成作用域链

    作用域链的使用规则:

    赋值: 先从当前作用域查找变量的定义,没有找上一级,直到全局,全局有就赋值给全局变量;全局没有就隐式定义这个变量-----不过不存在提升过程。

    运算、比较、输出等操作,先从当前作用域查找变量的定义,没有就杀上一级,直到全局,全局没有就报错,有则使用。

    递归函数:

    注意内存溢出错误(Maximum call stack size encoded)

    先定义一个空函数,然后往空函数里面输入值:

    function fn(){ if(num ==1){ return 1; } return num*fn(num-1); }

    注意一定要写return

    事件

    匿名函数的应用:

    目的:

    处理用户在网页上的行为,如点击,右击等

    事件三要素:

    事件源:

    能触发某种行为的HTML标签

    事件类型:

    拖拽,移动

    事件处理程序:

    函数

    在js中使用标签id代表标签,不要使用常见的关键字(name,start,stop)

    语法(事件的定义):

    事件源.onclick = function(){ console.log(123); }

    常见的事件类型

    事件类型含义click单击dblclick双击mouseover鼠标移入mouseout鼠标移出submit事件源form,点击的是submit常见于表单验证,点击之后,跳转页面keydown键盘按下,window.onkeydownkeyup键盘抬起,window.onkeyupfocus获得焦点/光标blur失去焦点load等页面所有加载完后最后开始加载,window.onload,可以让script放在任何位置,不用考虑加载顺序问题

    注意,知识点来了:事件的函数是由系统来调用的,事件的类型有系统提供的

    事件的书写

    第一种:

    div.onclick = function(){ console.log(123); }

    第二种;

    btn.onclick =fn; function fn(){ console.log(123); }

    第三种:行内书写

    onclick ="javascript:console.log(123);"//只能写一个语句 onclick=onclick(){}

    js的关键字:

    this:在全局中表示window(浏览器窗口),在事件中代表事件源

    对象

    对象分为数组/json对象/null

    json:

    定义:

    多个数据(键值对)组成的集合 直接定义:

    var obj ={ name:"张三", age:12 }

    构造函数:

    var obj =new Obj({ name:张三"" });

    对象数组的组成:

    键值对形式: 键必须是字符串,在定义的时候可以不加;键中包含连字符“-”,那就须要加上引号; 值是任意类型(可以是函数)

    对象的操作:

    增删改查:

    操作写法增对象.键 = 值;/对象[“键”] = 值 ;删delete 对象.键/delete 对象[“键”]改存在那个键值对,增的形式就可以修改查console.log(obj.name/obj[“name”])

    对象的遍历:

    js提供了特殊的for

    for(var attr in obj){ obj[attr]; }

    attr是键,obj是对象

    **注意:**错误写法如下

    var a ="name"; obj.a;//这么写是错误的,因为obj里面没有a这个键

    正确写法:

    var a = "name"; obj[a];

    对象的方法

    对象的值如果是函数,那么这个键就叫做对象的方法

    如果碰到多个键值对,就用对象

    构造函数初体验

    被用来new创建对象的函数都是构造函数

    任意函数都可以new来当构造函数,当一个函数被用来创对象,就可叫构造函数

    系统提供了一些构造函数来创建对象

    //系统内置的构造方法 var num = new Number(12); String(); Booelan(); 这里的num是对象型,可以参与数学运算并得到结果

    原理:js的底层处理任何的数据都是对象处理的,为了让开发者更加接近于正常的理解,js提供了基本数据类型,供开发者使用。

    数组

    也是多个数据的集合,但是相较于对象,数组在内存是按顺序排列的

    数组的定义

    一:直接定义

    var arr=[1,2,3,4,5];

    二:构造方法

    var arr =new Array(5); 创建了5个empty 不建议使用

    上面两种方式的区别只存在都给里面放个数字

    var arr=['a']; vae arr = new Array('a'); //这两个是一致的

    数组的特性:

    数组对象里面有属性length,可通过arr.length获取数组长度

    数组第一个下标为0,最后一个下标为arr.length-1

    数组的操作

    操作写法增var arr[i]= [1,2,3]删delete arr[i] 或者arr.length = 0;改arr[i ] =“d”,arr[i]已经存在查arr[i]

    数组遍历:

    方法一:

    var length = arr.length;//因为每次判断都要取值一次,浪费时间 for(var i = 0;i <length;i++){ console.log(arr[i]); }

    方法二:

    for(var i in arr){ console.log(arr[i]); }

    这个方法是遍历对象的,当然可以遍历数组

    二维数组:

    数组的元素类型没有限制,所以是数组类型也可以

    嵌套两层为二维数组,嵌套三层为多维数组

    查看三维数组中的某个元素arr[0][2][1];

    建议:数组里面只放一种数据类型,对象里面放多种数据类型

    数组的操作方法:

    splice(开始位置,删除个数,增加元素)

    参数一和参数2必须写,参数三为可选项 最常用,插入删除修改数组

    pop():删除最后一个元素 unshifted():开头加上元素 shift():开头减少元素 push():末尾加上一个任意类型元素

    concat()数组拼接:

    var res =arr1.concat(arr2); var res1 = arr1.concat(“a”,“b”);

    数组的排序sort:

    arr.sort(function(a,b){ return b-a;//降序 return a - b;为升序 })

    连接join:

    arr.join("-") 按照指定字符拼接成字符串

    利用数组写页面

    var arr = [ { name: "手机", img: "https://www.baidu.com/img/dong_8ff048ec89a4c8b4d638def4ce4dafda.gif", price: 50, desc: "真便宜,没好货" } ] document.write("<ul>"); document.write(" <li><img src="+arr[0].img +" alt=\"\"><p>"+arr[0].name+"</p><span>50</span> <div>"+arr[0].desc+"</div></li>"); document.write(" <li><img src="+arr[0].img +" alt=\"\"><p>"+arr[0].name+"</p><span>50</span> <div>"+arr[0].desc+"</div></li>"); document.write(" <li><img src="+arr[0].img +" alt=\"\"><p>"+arr[0].name+"</p><span>50</span> <div>"+arr[0].desc+"</div></li>"); document.write("</ul>");

    基本类型的内存机制:

    栈内开辟空间,放入数据,b=a就是将a内存里面的数据复制一份到b

    引用类型的内存机制:

    数组在栈内开辟空间,将数组内容放在堆内存,栈内存存放数据的地址,b=a赋值的是数组的地址,修改的是堆内存的数组,对a的值也会产生改变

    冒泡算法

    算法原理:每相邻的两个元素比较大小,不符合规则就交换两个元素的位置

    var arr=[1, 5, 3, 7, 6, 14, 9, 1, 4, 8, 2]; var length = arr.length; for(var i = 0; i<arr.length;i++){ for(var j = 0;j<length -1;j++){ if(arr[j]>arr[j+1]){ var tmp =arr[i]; arr[j] = arr[j+1]; arr[j+1] =tmp; } } } console.log(arr);

    选择排序

    原理:每次选择最小的或最大的值放在合适的位置

    var arr = [1, 5, 3, 7, 6, 14, 9, 1, 4, 8, 2]; for(var j = 0; j <arr.length - 1 ; j ++ ){ var min = arr [j]; for(var i = j+1 ;i <arr.length; i++ ){ if(arr[j]> arr[i] ){ var tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp; } } } console.log(arr);

    ES5 简单认识

    ES5 兼容性最好的版本

    ES6也称为ES2005

    ES:ECMAScript的简写

    严格模式:

    “use strict”;

    要求:

    不允许隐式定义变量不允许普通函数内this代表window不允许形参重名(js函数形参重名是可以执行的,但是不建议这么写)

    写法:

    在script的最前面或者在函数的最上面写上"use strict";

    好处:

    消除怪异语法,更加规范化 运行效率更高

    严格模式也受到作用域限制

    数组方法:

    indexOf():查第一个值在数组中第一次出现的下标,查不到返回-1map():将数组的每个值处理,返回新元素组成的新数组 arr.map(function(v,i,a){ return v*0.3; }) v:数组元素,i:数组下标;a:数组本身 i,a是可选项 filter方法: 过滤函数 满足条件的元素组成新数组返回。 参数和map一致 爱如如.filter(function(v,i,a){ return v< 60; })

    4.reduce方法:归并

    arr.reduce(function(v,i,a){ return v<60; })

    a:第一次值为arr[0],之后是上一次函数的return,没有返回undefined b:a[次数];

    map和filter用的最多

    字符串

    字符串的比较规则

    从左到右逐个字符比较的

    字符大小规则遵循ASCII码

    数字<大写字母<小写字母

    排名越靠前越小(a<z)

    字符串的操作

    操作形式查str[i]增删改没有,都会形成新的字符串

    遍历字符串

    for(var char of String){ console.log(“字符”+char); }

    常见的API

    charAt():通过指定的下标获取字符串的字符(极其鸡肋,不要记) str.charAt() 2.charCodeAt():通过指定下标获取字符对应的ASCII码

    3.固定写法:String.fromCharCode()-----通过ASCII码返回一个字符

    var num= 97var s = String.fromCharCode(num); console.log(s);

    indexOf() 查字符在字符串中第一次出现的下标,没有返回-1

    lastIndexOf(): 查字符串最后一次出现的下标,返回值为下标或者-1

    substr(): 截取字符串,参数一开始截取的下标,参数二截取长度(不写默认截取到尾)

    substring():截取字符 参数一:开始下标 参数二:结束下标(不写默认到结尾,不包含参数二的)

    slice() 截取字符串,和substring一样的 截取从左到右,不是从右到左 开始下标为负数的话,-1表示倒数第一个 数组里面也有slice方法

    split(): 把字符串转成数组(俗称“炸”) 使用指定的分隔符将字符串分割成很多小字符串,组成数组并返回 没有参数将整个字符串当做元素放入数组 split(""):每个字符都当成元素组成新数组

    replace(): 替换字符串中的指定内容,只能替换一次,循环才可以替换多次 str.replace(“html”,“css”); var s = str.replace("")

    trim() 去除左右的空格,可分为trimLeft()和trimRight()

    toLowerCase();//全部小写 toUpperCase()//全部大写

    Math Date

    math对象:系统内置的对象

    math不像String和Date是对象的类,因此没有构造函数Math(),像Math.sin()这样的函数只是函数,不是某个对象的方法。无需创建,通过把慢作为对象使用就可以调用其所有的属性和方法

    格式功能Math.PI圆周率Math.round()四舍五入Math.pow(底数,幂数)次方Math.random()获取随机数Math.floor()向下取整Math.ceil()向上取整Math.max()最大值Math.min()最小值Math.abs()求绝对值

    对Math.random()进行封装

    function(a,b){ var res = parseInt(Math.random()*(b-a))+a; return res; }

    生成一个[a,b)的随机整数

    进制转化

    除了十进制以外的进制都是字符串形式

    10进制转为其他进制: num.toString(8);//转为八进制 其他进制转为10进制: var res = parseInt(str,n); //str为进制字符串,n为str是什么进制的

    Date对象

    系统提供的构造函数

    var date =new Date(); console.log(date);//当前时间

    date对象在我们打印日期的时候自动调用toString方法。

    格里尼治时间戳:从格林尼治的1970.1.1.0.0.0到现在的毫秒数,就是现在的时间戳

    获取:

    var date =new Date();

    获取什么格式获取年var year = date.getFullYear()获取月var month = date.getMonth()获取日var day = date.getDate()获取时var hour = date.getHours()获取分var minute = date.getMinutes()获取秒var seconds = date.getSeconds()获取毫秒var milisecond = date.getMilliseconds()获取时间戳var timec = date.getTime()获取星期几var week = date.getDay()快速获取时间戳var res =+new Date();

    注意:js里面的月份是0~11,输出时需要加1

    设置:

    get改为set就可以了

    星期是不可以设置的

    设置时间戳:date.setTiems(0)//格林尼治时间 在线运行js

    设置·指定时间的时间戳: var date = new Date(“2020-10-10 11:21:05”); var date = new Date(1010,10,10,0,0,0);

    通过构造方法设置时间戳: var d = new Date(0);

    格式化输出时间日期: date.toLocaleString();//只看年月日 date.toLocaleTimeString();//只看时分秒 date.toLocaleString();//都看

    BOM(浏览器对象模型)

    Browser Object Model

    操作浏览器都是使用对象来操作的:window对象(浏览器窗口)

    window有子对象,每个子对象都针对着一个操作

    js实现跳转的方法

    window.open(): window.location.href=“地址” window.location.assign(): window.location:

    window子对象:BOM中的顶级对象

    注:window可省略

    navigator(获取浏览器信息)

    没什么卵用,对于学爬虫的估计有用 window.navigator.appCodeName 浏览器内核名称 window.navigator.appName浏览器名称 window.navigator.appversion:浏览器版本 window.navigator.userAgent:浏览器信息

    history历史记录(你打开的网页记录)

    前进: history.back(); 后退: history.forward() 刷新: history.go();//正数前进,负数后退,0刷新当前页面

    location:地址栏

    href属性: location.href是完整的地址栏地址,赋值可以实现跳转

    search属性: 获取地址栏数据 location.search 也可以赋值设置,注意是键值对形式

    hash属性: 获取地址栏的锚点: location.hash="#bottom"

    页面重定向(跳转方法): location.assign(“地址”);

    新地址替换当前地址: location.replace();

    刷新当前页面: location.reload();

    window弹出方法:

    alert(); prompt(); confirm();

    注意: 全局变量其实是window的属性,全局函数是window的方法,只不过平时省略了window,全局中的普通函数中的this代表的就是window对象。

    window获取浏览器的尺寸

    innerWidth/innerHeight 包含滚动条,相当于视窗的宽高(去掉了window)

    window事件(重点):

    window.onload = function(){ //页面加载完再执行 //放在同步中就是同步加载完的最后,异步中就是异步最后 }

    window.onreszize = function(){ //改变窗口大小就执行 }

    window.onscroll = function(){ //浏览器滚动条滚动时执行 }

    定时器(重点):

    分两种:每隔一段时间执行一次和延时一段时间只执行一次

    第一种:

    var timer = window.setInterval (function( console.log(123); ),2000)

    清除:

    clearInetrval(timer); //形参是当前页面第几个定时器,一般为定时器返回值或者数字,会执行一次

    注意:定时器一定要停,不然内存溢出

    上一个(死循环,递归函数) 第二种:

    window.setTimeout(function{ console.log(123); },2000) //也有返回值,也用来清除,同样代表第几个定时器

    清除:clearTimeout();

    重点:定时器的返回值

    timer这个返回值其实是最后一次点击的定时器的返回值

    清除定时器的时候,其实是清除了最后一个定时器,前面几次点击产生的定时器没有清除,也清除不掉了

    同步操作和异步操作

    同步: 上面的语句执行完,下面才会执行,排队等待 异步: 同时执行(和同步)

    运行流程:

    js是单线程的(同时只能做一件事)当js线程看到异步代码(栈空间),将异步交给浏览器(多线程)浏览器等异步操作执行时机,时机成熟放入一各队列等待时机js线程如果将所有的同步执行完,会从队列中找到需要执行的代码才会执行。

    总结: 定时器和延时器不一定精准(因为异步的定时器会受到同步时间的耽误) 所有异步都是在同步执行完之后执行的 异步效率高

    DOM操作

    dom(document object model)文档对象模型 **操作HTML文档**的方法

    之前存在id名代表这个标签,如:

    box.onclick (function(){ console.log(123); })

    如何获取标签元素

    操作写法使用id名获取document.getElementById(“id名”);类名获取元素document.getElementsByClassName(“box”);标签名document.getElementsByTagName(“”);使用name属性获取document.getElementsByName(“sex”);CSS选择器获取元素document.querySelector(“选择器”)CSS选择器选择元素的集合var oDiv = Document.querySelectorAll(“li”)

    注意:2,5,6条低版本IE不兼容

    属性操作:

    操作写法查getAttribute(“属性的键”)删removeAttribute("键”)有则改,无则增setAttribute(键,值)

    特殊的: img.src和input.value

    最重要的:inout.checked

    内容操作

    元素.innerText,值为标签内容,设置标签样式是不生效的 元素.innerHTML:标签内容,值为标签生效

    特殊情况:

    表单元素的值: document.querySelector(“input”).value; 0

    设置样式:

    写在行内的style标签里面的

    类名操作:

    标签.className:""; 这么写清空类名

    滚动过的距离

    垂直滚动document.documentElement.scrollTop水平滚动document.documentElement.scrollLeft

    当文档声明没有时,documentElement换成body

    兼容写法:

    var t = document.documentElement.scrollTop||document.body.scrollTop

    立即回到顶部:

    t = 0;也可以定时器不断减少慢慢变化

    html基本结构获取写法

    部位写法htmldocuemnt.documentEleemntbodydocument.bodyheaddocument.headtitledocument.title

    节点

    节点:html文档的组成部分

    DOM节点分(了解): 元素节点(标签),属性节点(),文本节点(文本内容),注释节点(注释) 注意: 文本节点:标签内的文本和标签之间的换行空格(为什么写移动端最好别换行空格,因为算文本,会被当做文字放大)都算文本节点

    获取节点:

    上面的getElementById等都是获取节点,但是这里的获取节点是依靠关系,不是直接获取

    重点:

    获取什么怎么获取子节点childNodes子标签children父节点parentNode父标签parentElement第一个节点firstChild最后一个节点lastChild子元素中第一个标签firstElementChild子元素中最后一个标签lastElementChild获取上一个节点previousSibling获取下一个节点nextSilbling获取上一个节点元素previousElementSibling获取下一个节点元素nextElementSibling获取所有属性节点atributes

    节点属性

    都是属性,不是方法

    写法作用nodeType获取节点类型nodeName获取节点名nodeValue获取节点值

    nodeType返回值: 1表示元素节点;3表示文本节点;8表示注释节点;2表示属性节点

    nodeName: 标签节点为标签名的大写形式(DIV),文本节点为(#text),注释节点为(#comment)

    nodeValue: 标签为null,文本节点为文本内容,注释节点为注释内容

    节点操作

    操作写法删除当前元素元素.remove()新建元素createElement(“元素名”)父元素加子节点(追加在子元素最末尾)父元素.appendChild(oDiv)将子节点插到某个子节点之前父元素.insertBefore(新元素 ,被插队的节点)替换节点父元素.replace(新节点,旧节点)删除节点removeChild(被删除的子节点)复制节点自身元素.cloneNode()

    复制节点传参true可以将里面的内容也复制

    下面全程高能

    获取样式:

    var styles = window.getComputedStyle(元素); styles.属性

    低版本IE不兼容

    兼容写法

    function getStyle(){ try{ return window.getComputedStyles(ele[attr]); }catch(e){ return ele.currentStyles[attr];//IE兼容写法 }

    获取元素大小

    clientWidth/Heightnumber型,不含边框offsetHeight/Width含边框

    都是只读类型,offsetHeight对于行内一直为0

    获取元素的位置

    offsetLeft/offsetTop获取到设置过定位父元素的距离{机制和定位机制一样,逐级向上寻找定位元素}offsetParent获取设置过定位的父元素,最终到body

    获取窗口大小:

    window.innerHeight/Width含滚动条document.documentElement.clientWidth/clientHeight不含滚动条

    变量定义技巧

    一个局部想要使用另一个局部的变量,可以将变量定义在全局

    使用自调用函数传参(形成保留作用域)

    for (var i = 0; i < ulis.length; i++) { ( function(i) { ulis[i].onclick = function () { that.className=""; that =this; for (var j = 0; j < ulis.length; j++) { ulis[i].className = ""; } this.className = "active"; for (var j = 0; j < olis.length; j++) { olis[j].className = ""; } olis[i].className = "active"; } })(i); }

    下拉框select>option里面的value可以

    document.querySelector(“select”).value获取到

    事件

    为了提高浏览器检索优先级:能不用标题标签就别用

    事件:用户的动作(单击,右击等)

    下面是事件类型:

    鼠标类

    右击contextmenu鼠标按下mousedown鼠标抬起mouseup鼠标移入mouseover鼠标移出mouseout鼠标滚轮mousewheel(火狐里面用DOMmousescroll)鼠标单击click鼠标双击dblclick鼠标移动mousemove移入mouseenter移出mouseleave

    mouseover和mouseenter的区别:

    相同点:没有子元素时候行为一致

    mouseover用的比较多,mouseenter经常被忘掉

    mouseenter不会冒泡,mouseover会

    不论鼠标指针穿过被选元bai素或其子元素,都会du触发 mouseover 事件。对应mouseout 只有zhi在鼠标指针穿过被选元dao素时,才会触发 mouseenter 事件。对应mouseleave 这样的话,mouseenter子元素不会反复触发事件,否则在IE中经常有闪烁情况发生。(复制自百度)

    键盘类

    keypress键盘按下keydown看英文,不解释keyup按键抬起(一定要注意执行时机,获取按下那个键的键盘码不能用这个)

    区别自己百度,使用最多的是keyup

    表单事件

    focus光标点进去blur光标(闪烁的竖杠)丢失就触发该事件change下拉框改变就触发input实时监听文本框的内容变化(类似百度的搜索框,IE中是propertychange)submit给submit标签绑定的(form.submit,必须要结合提交按钮使用)

    事件流

    事件从开始触发到执行结束的流程(一连串的事情) 捕捉阶段:从文档由外向内找目标元素 目标阶段:找到目标文件,执行文件 冒泡阶段:执行完就要离开

    事件外的元素也绑定了事件的话,冒泡阶段由内向外会触发外面的事件

    事件侦听器(一个事件绑多个函数)

    onClick的缺点:一个元素绑多个onClick会被覆盖

    事件侦听器(兼容性):

    元素.addEventListener(“click”,function(){ //可以实现多个不覆盖,但是IE不行 }) 元素.attachEvent(onclick,function(){

    })

    function bindEvent(btn,type,handler){ try{ btn.addEventListenter("type",handler); }catch(e){ btn.attachEvent(on+"type",handler); } }

    第二种:

    function bindEvent(btn ,type,hander){ if(btn.addEventListener){ btn.addEventListener(type,hander) }else if(btn.attachEvent)){ btn.attachEvent("on"+type,handler) }else{ btn["on"+type] = handler } }

    第三种:

    function bindEvent(btn,type,handler){ try{ btn.addEventListener(type,handler) }catch(err){ try{ btn.attachEvent("on"+type,handler) }catch(e){ btn["on"+type] = handler }}}

    访问对象中不存在的属性是undefined

    好处:

    同一类型事件可以绑定多次: button.addEventListener("click",function(){ console.log("点击"); }); button.addEventListener("click",function(){ console.log("点击"); }); button.addEventListener("click",function(){ console.log("点击"); }); 可以指定当前事件在捕获阶段执行有第三个参数,代表是否在捕捉阶段执行(默认false表示冒泡阶段执行) attachEvent没有第三个参数,因为IE浏览器的事件流,没有捕获阶段

    事件解绑

    按钮能点击,说明加载到内存中了,所以点击才能生效


    点击完后还能点击,希望只执行一次,减少内存负担(所需要解绑)
    null为引用类型的空,undefined为基本类型的空 btn.onclick = null;//解绑

    事件监听器解绑

    前提里面的函数不能是匿名函数了

    var fn = function(){ console.log(123); } 解绑: 事件源.removeEventListener("click",fn); 事件源.detachEvent("onclick",fn);

    解绑又有兼容性问题----封装函数:

    function unbindEvnet(ele,type,handler){ if(ele.removeEventListener){ ele.removeEventListener(type,handle) }else if(ele.detachEvent){ ele.detachEvent(“on”+type,handle); }else { ele[“on”+type] = null; } }

    阻止事件冒泡

    事件时有系统调用的,不是我们手动调用的,系统将事件对象放在小括号内,存放和当前事件相关的一系列信息。

    small.onclick = function(e) { console.log(e); e.stopPropagation();//阻止事件冒泡 }

    在IE中的兼容写法 事件对象:window.event 阻止冒泡:e.cancelBubble=true;

    事件对象的简单操作

    e.type事件类型如“click”等e.button鼠标按键信息左键是0,右键是2,滚轮是1e.keyCode键盘码回车13,数字字母遵循ASCII码e.shiftKey/ctrlKey/altKey组合键true或者falsee.offsetX/Y光标在元素上的坐标位置e.clientX/Y指光标在浏览器上的位置指视窗距离,不包含滚动过的距离e.pageX/Y光标在房钱页面上的绝对位置包含滚动过的距离

    注意:键盘码低版本火狐不兼容 兼容写法:

    var keycode =e.keyCode||e.which

    简单的拖拽效果

    var div = document.querySelector("div"); //拖拽一定先按下鼠标 div.style.position="absolute" div.style.left="0" div.style.top="0" div.onmousedown = function(e){ //这里代吗都是在鼠标按下的时候执行的-----按下后再移动鼠标(鼠标移动事件) var e = e ||window.event; var x = e.offsetX; var y =e.offsetY; div.onmousemove = function(ev){ //这里写div可以将鼠标甩出来,换成 document,解绑也需要document //鼠标移动只会执行这里的代码 var ev = ev ||window.event; var x1 = ev.clientX; var y1= ev.clientY; var l = x1 - x; var t = y1 - y; div.style.left=l+"px"; div.style.top = t+"px"; } } 只要鼠标在div上,触发onmosemove,外面的onmousedown就不会停止,需要解绑里面的 这时需要解绑: div.onmouseup= function(){ div.onmousemove =null; } 存在点击后快速离开,解绑无效果,那么把移动的事件源由div改为document(就算被甩出div范围也依旧在document范围)

    拖拽限制

    var div = document.querySelector("div"); //拖拽先按下鼠标 div.style.position = "absolute" div.style.left = "0" div.style.top = "0" div.onmousedown = function (e) { //这里代吗都是在鼠标按下的时候执行的-----移动鼠标-----鼠标移动事件 var e = e || window.event; var x = e.offsetX; var y = e.offsetY; document.onmousemove = function (ev) { //鼠标移动只会执行这里的代码 var ev = ev || window.event; var x1 = ev.clientX; var y1 = ev.clientY; var l = x1 - x; var t = y1 - y; if (l < 0) { l = 0; } if (t < 0) { t = 0; } if (l > document.documentElement.clientWidth - div.offsetWidth) { l = document.documentElement.clientWidth - div.offsetWidth; } if (t > document.documentElement.clientHeight - div.offsetHeight) { t = document.documentElement.clientHeight - div.offsetHeight; } div.style.left = l + "px"; div.style.top = t + "px"; } } div.onmouseup = function () { document.onmousemove = null; }

    阻止默认行为

    链接的跳转,鼠标右键出现的窗口都是默认行为

    return false(事件函数最后加上)e.preventDefaulte          e.returnValue =false(IE中)(利用事件对象来阻止)将链接地址改为javascript:;

    事件委托

    将子元素的事件委托给父元素:例如点击事件,委托后每个子元素都可以有点击

    好处:你新增的元素不需要再次单独绑定事件,十分方便

    兼容写法:

    target = e.target ||e.srcElement;(兼容低版本IE) target代表的是所有子元素

    <ul> <li>11111111111</li> <li>22222222222</li> <li>33333333333</li> <span>4444444444</span> </ul> <button>添加</button> </body> <script> var ul = document.querySelector("ul"); ul.onclick = function(e){ var e = e||window.event; var target = e.target ||e.srcElement; if(target.nodeName=="LI"){ target.innerText="修改";//加条件限制target范围 console.log(target); } }

    注意点:

    拖拽的时候一定是事件嵌套,事件的事件对象是不一样的mouseover和mouseout是一对,mouseenter和mouseleave是一对,尽量不要混用在head里面写script标签,要将代码写在这个事件内部;script在body的底部,就不要加了,加了也没用,还会覆盖前面的键盘事件通常是keyup获取键盘码时有些特殊键盘码无法显示,大小写有时候会混乱,不要研究为什么

    offset的一个坑

    没有设置小盒子的时候,光标就是大盒子上的位置,就是offsetX 一旦设置了小盒子的位置,光标立马就会在小盒子上,此时的offset就是光标在小盒子上的位置。

    拖拽效果不要使用offsetX/Y

    e.clientX/Y都是只读数据

    正则表达式

    用处:验证字符串,提取满足的字符串,替换字符串

    但是还有很多用法,无法说清,不仅仅只是简单地实现表单验证

    书写规则:

    创建: var reg =new RegExp(); var reg = /规则/;

    可接受写法 var reg = /html/; var reg =/^html$/; var reg = /\w$/; var reg =/\d$/; var reg =/^\d{5,12}$/;

    符号意义^放在规则前表示必须是这个开头$放在规则结尾表示必须以这个结尾{m,n}至少m个,至多n个{n,}至少n位,多了不限制{n}必须是n位\w任意字母数字下划线\d任意数字.代表一个字符(注意字符是重点)\s代表一个空格[a-z]小写a到小写z,不是固定解法,[a-zA-Z]表示任意一个字母\u4e00 -\u9fa5汉字,不要记,会查就行+至少一个?最少0个,最多1个*{0,},任意个()表示包起来的是一个整体,还有个用法是用来捕获变量

    手机号:

    方式一:

    var str = "28715260980"; var reg =/^1[3-9][0-9]{9}$/; var res= reg.test(str); console.log(res);

    方式2:

    var str = "28715260980"; var reg =/^1[3-9]\d{9}$/; var res= reg.test(str); console.log(res);

    qq邮箱

    var reg = /^[1-9]\d{4,11}@qq\.com$/; //.有特殊意义,需要转义 var res = reg.test("1974744790@qq.com"); console.log(res);

    网易邮箱

    var reg = /^[a-zA-Z]\w{5,17}@(163|162)\.com$/; var str = "shaoguoqing10@163.com"; console.log(reg.test(str)); 注意:空格也算在规则内

    QQ邮箱+网易邮箱:

    var reg= /(^[1-9]\d{4,11}@qq\.com$)|(^[a-zA-Z]\w{5,17}@(163|162)\.com$)/; var str = "1974744790@qq.com"; console.log(reg.test(str));

    方法:

    test正则方法,验证是否满足规则search验证是否有满足规则的那一段,有返回下标,没有返回-1exec正则方法,找到匹配的输出为数组的第一个元素,找不到为nullmatch字符串方法,没有匹配返回null,和exec没什么区别replace(reg,“str”)将str里和reg匹配的替换成js,只能替换一次,替换多次/html/g;多次忽略大小写/html/gi;

    注意: exec(): 正则方法 在字符串中找到匹配的为输出的数组第一个元素,找不到为null 如果想要具体的某个值,可以给那个值加上(),第二个元素为小括号内的值

    文件格式检测:

    var reg = /^\w{1,}\.(jpg|jpeg|bmp)$/ var str ="1.jpg"; var res= reg.test(str); console.log(res);

    字符串首行去空格

    var str=" ab dc "; var reg = /(^\s+)|(\s+$)/g; var replace = str.replace(reg,""); console.log(replace);

    ES5,ES6语法

    表单验证要么都是失去焦点的验证,要么都是提交按钮的验证,不然冲突,失去焦点优先级高,提交按钮无效。

    数组方法

    v,i,a形参,名字随便起的,代表数组元素,下标,调用数组,一般第二第三个参数都是省略不写的foreach()只能遍历,没有返回值some判断数组中至少有一个满足条件every判断数组中是否所有元素都满足条件find()查找数组中第一个满足元素的元素findIndex()满足条件的下标(用法类似find)

    foreach:

    arr.foreach(function(v,i,a){ console.log(v); })

    some:

    var res = (function(v,i,a){ return v>30; })

    every:

    var res = arr.every(function(v,i,a){ return v==60; })

    find:

    var res = arr.find(function(){ return v>5; })

    ES6:

    定义变量:

    var的特点:能预解析,全局变量属于window 两个关键字定义变量: const,let 特点:不能预解析;不在window上(因为自己的作用域) let定义的变量,创建了一个作用域

    for(let i = 0; i<3;i++){}; console.log(i);//报错,表示i未定义

    let定义过的变量,不能重复定义: 好处:以前事件外循环参数需要函数传入,现在将循环参数改为let就可传入,因为let创建了个作用域

    var button = document.querySelectorAll("button"); for (let i = 0; i < button.length; i++) { button[i].onclick = function () { console.log(i); } } function f2(){ var i = 5; for(var i=0;i<=10;i++){ } console.log(i); // 11 var j = 5; for(let j=0;j<=10;j++){ } console.log(j); // 5 } f2();

    const:常量,值可被初始化,但不能赋值。也不在window上,也不能预解析,不希望改变的量就用const来定义

    箭头函数

    形参列表只有一个参数,小括号可以省略 大括号内只有一行代码,省略大括号 若一行代码内只有return关键字,return关键字可以省略

    let fn = res=> res; let fn= function (res){ return res; }

    函数默认值

    function(a,b=10){ console.log(a,b);//b不传值就是10,传值10被覆盖 } 如果a有默认值,不想改变,可以实参传undefined

    …运算符

    将多个形参整合成一个数组: let fn = (...arr)=>{ console.log(arr); } fn(10,20,30); 将数组拆分成多个值 let fn = (a,b,c)=>a+b+c; let arr =[1,2,3]; const res = fn(...arr); console.log(res); 可以将对象拆分成多个键值对 var ch ={naem:"翠花",age:12} var zz = {name="李四",age:14,wife:{...ch}} 这里注意加载顺序

    总结:实参分解形参合并,对象直接拆

    对象

    键与值相同可以只写一个: var name="张三"; var age = 12; var obj = {name,age} 方法也可以简写: var ff ={eat:function(){console.log("eat");}}; 改写: var ff = {eat(){console.log("eat")}} 调用: obj.eat(); 解构赋值 快速将对象或者数组中的值赋给多个变量 var name="张三"; var age = 12; var zs ={ name, age, eat(){console.log("吃");}, sport(){console.log("运动");}, wife:{name:"翠花",age:12} } var {name.age,eat,sport}=zs; console.log(name,age,eat,sport);

    注意变量名和键名需要保持一致

    取别名: var {name:n,age:a,eat:e,sports:s}=zs; console.log(n,a,e,s); 套娃操作:

    var {wife}=zs; var name={wife}; 简化套娃操作:var {wife:{name:n}} = zs;

    数组结构:

    var arr = [1,2,3,4]; var[a,b,c] =arr; var [a] =arr; //只想获取c var [_,_,c]=arr; //数组的多重解构(套娃) var arr =[ "马蓉", "王宝强", [ "贾乃亮", "PGOne", "李小璐" ] ] var [_,_,[a]] = arr;

    字符串

    字符串是不支持多行定义的,使用模板字符串就可以了(反引号)

    var name="张三"; var str=` 姓名:${name} `; name+str;

    字符串方法

    返回值是boolean型: startsWidth:字符串是否以某个文字开头; 字符串是否以某个文字结尾; includes:判断字符串是否有某个字符(split炸要是成三段就是含有这个字符)

    具体查看数据类型:

    Object.portotype.toString.call(对象名);

    伪数组

    是对象,像数组能遍历,但是不能用数组方法

    之前getElementByTagNames等获取到的就是。

    特点:

    键是数字,有一个键为length,值为元素个数数组的length属性颜色淡,但是可以调用对象没有length,但是伪数组有伪数组的键其实是字符串,也有引号 arr[“0”];

    自创伪数组:

    var weishuzu={ 0:"第一个", 1:"第二个", 2:"假设这是极限", length:3 } for(let i = 0;i<wieshuzu.length;i++{ console.log(weishuzu[i]); }

    伪数组转为数组

    var arrv = Array.prototype.slice.call(obj);

    伪数组的遍历

    for(var i = 0 ; i <obj.length;i++){ console.log(obj[i}); }

    函数中的关键字:arguments

    function fn(){ console.log(arguments); } fn(1,2,3);arguments是存放实参的伪数组

    this关键字代表什么

    所在范围代表全局,普通函数window定时器中window自调用函数window对象方法中当前对象箭头函数自己所处作用域的this用对象调用的方法this代表这个对象事件代表事件源

    所有用对象调用的方法,this代表这个对象 函数定义不知道this是什么,只有调用的时候才知道。

    点击调用函数的时候,相当于调用了document的onclick方法

    for(var i=0;i<imgs.length;i++){ imgs[i].onclick = function(){ var path = this.src; //利用this获取变化的i值 document.body.style.backgroundImage = 'url('+path+')'; document.body.style.backgroundRepeat = 'no-repeat'; document.body.style.backgroundSize = '100% 100%'; box.style.height = 0; } }

    如何改变this

    将fn中的this改为arr

    1. call方法:被函数调用的方法

    fn.call(arr)//相当于函数的调用 本质:调用函数被改成函数.call() 调用call之后函数就被调用了 var obj = { fn(a,b){console.log(a,b);} } var arr =[1,2,3]; obj.fn.call(arr,1,2); 相当于arr调用了obj里面的fn方法,第一个参数后面的都是obj.fn需要的参数

    感觉讲的非常详细,可以点这个链接去看看 undefined+undefined = NaN

    apply:

    也是调用函数,和call差不多,也能改变this

    函数的实参会组成数组传入

    var arr =[1,2,3]; var obj ={ name:"张三", fn(a,b,c){ console.log(c) } } obj.fn.apply(arr,[1,2,3]);

    bind:

    复制函数,参数相当于复制出函数里面的this

    下一篇:DOM高级-运动

    注:全篇为个人笔记,仅供参考,如有错误请指出

    Processed: 0.036, SQL: 8