Java Script 3.0


# 函数

# 创建

<div>
  <input type="text" class="num1" />
  <input type="text" class="num2" />
  <button class="add">add</button>
  <div>结果是:<span>0</span></div>
</div>
// 创建的时候不执行,调用的时候执行
// 调用 函数名()
// 1.函数式创建
function fun() {
  console.log("lgd加油1");
  console.log("lgd加油2");
  console.log("lgd加油3");
}

// 2.变量式创建 将一个匿名式函数,创建给一个变量
var addFun = function (a, b) {
  //创建形参相当于在函数内部声明了两个变量但是没有赋值,调用的时候传递了实参就相当于给变量赋值
  var res = a + b;
  //当外界(函数之外)想要获取函数内部计算的结果需要给函数添加 返回值
  //return必须写在函数的最后面,因为return后面的语句就不会执行了
  return res;
};
$(".add").click(function () {
  var num1 = $(this).parent().find("input").eq(0).val() * 1;
  var num2 = $(this).parent().find("input").eq(1).val() * 1;
  var res = addFun(num1, num2);
  // addFun(100, 200); // 这句话变成了函数中 return res 的值
  //当函数设置了返回值的时候,函数调用这句话先执行函数内部的操作,然后整句话变成了返回的那个值
  $(this).next().find("span").text(res);
});

# Js 作用域

作用域分两种 1. 全局 (可以获取到其他 js 文件中或其他 script 标签的变量) 2. 局部
全局作用域 的意思是在该作用域下定义的内容 任何地方都可以访问
局部作用域 的意思是在该作用域下定义的内容 只有本身作用域和后代作用域可以访问

重要:变量的声明会直接提升到当前作用域的顶端
重要:函数式创建的函数会直接提升到当前作用域的顶端

console.log(str); //undefined
var str = "hello";

function fun() {
  console.log(num); //undefined
  var num = 100;
}
fun();

// 函数式创建的函数会直接提升到当前作用域的顶端
xx(); //哈哈哈
function xx() {
  console.log("哈哈哈");
}

// 首先会处理函数声明,其次会处理变量声明,
// 如果变量名跟已经声明的形参或函数相同,则变量声明不会干扰已经存在的这类属性。

console.log(foo); // 会打印函数,而不是 undefined
function foo() {
  console.log("foo");
}
var foo = 1;

# 立即执行函数 (匿名函数)

  • 主要用来 封装作用域
  • 匿名函数 不会自己创建 一般都是 当作参数传递
  • 匿名函数会 立即执行
  • 因为 全局变量越多 就会 污染全局环境
  • 使用框架的时候框架会自动封装作用域
(function () {
  console.log(1);
})();

(function () {
  //  一顿操作
  var loop = "轮播图操作";
  //将作用域内的loop 暴露出去(暴露到全局)
  window.xxx = loop;
})();
console.log(xxx); // 轮播图操作

for (var m = 0; m < liArr.length; m++) {
  (function (m) {
    liArr[m].onclick = function () {
      for (var i = 0; i < length; i++) {
        liArr[i].className = "";
        sliderArr[i].className = "slider";
      }
      this.className = "active";
      sliderArr[m].className = "slider active";
    };
  })(m); //这里的m是实参
}

var mySwiper1 = new MySwiper(".my-swiper-one", {
  imgArr: ["./imgs/a1.png", "./imgs/a2.png", "./imgs/a3.png"],
  currentIndex: 1, // 默认展示的第几张
  isHasPagination: true,
});
(function () {
  function MySwiper(selector, options) {
    this.eleDom = document.querySelector(selector);
    this.options = Object.assign(this.defaultOptions, options);
    this.init();
  }
  MySwiper.prototype.init = function () {
    console.log("初始化函数");
  };
  window.MySwiper = MySwiper; // 因为作用域进行了封装,所以要将对象暴露出去
})();

# 模块化开发规范

CommonJS规范(服务器)编写代码
声明:
    module.exports = {
      outA: showA,
      outB: showB
    }
引入:(同步执行)
    var moduleA = require('moduleA.js');
    moduleA.outA();
    moduleA.outB();


AMD规范:(客户端/浏览器)
声明:
    define(function(){
        //代码
        return {
          outA: showA,
          outB: showB
        }
    })
引入:(异步执行)
    require(["moduleA.js"], function(moduleA){
      //这里的代码。模块引入之后执行。
      moduleA.putA();
      moduleA.outB();
    })

    alert("hello world");


ECMA6(模块化规范)
声明:
    export = {
      outA: showA
      outB: showB
    }

引入:
    import moduleA from "moduleA.js"
    moduleA.outA()
    moduleA.outB();

# 箭头函数

【注】适当的省略函数中的 function 和 return 关键字。
箭头函数需要注意的部分
1、箭头函数,不能用 new
2、箭头,如果返回值是一个对象,一定要加 ();
3、箭头函数中的 this,指向的是上一层函数的主人。

function add(x) {
  return x + 10;
}
var add = (x) => x + 10; //等同于上边的函数

1、无参数,无返回值
function show() {
alert("hello world");
}
var show = () => {
alert("hello world");
};

2、有一个参数,无返回值
function xxx(num) {
alert(num);
}
var xxx = (num) => {
alert(num);
};

3、有一个参数,有返回值
function add(x) {
return x + 10;
}
var add = (x) => {
//代码
return x + 10;
};
// 或
var add = (x) => x + 10;

4、多个参数,有返回值
function show(x, y) {
  alert(x + y);
}
var show = (x, y) => {
  alert(x + y);
};

# 回调函数

把一个函数当作参数传进去,在合适的地方调用的形式叫做回调函数

function KFC(food, eatFunc) {
  alert("您的餐" + food + "准备好了,请您及时就餐");
  eatFunc();
}
KFC("香辣鸡腿堡", function () {
  alert("堂食");
});

# arguments (函数实参集合)

函数内的关键字 arguments
指的是 函数的实参集合 也就是将函数的实参组成一个类数组
类数组 只能 .length 或者 [n] 不能使用真正函数的方法之类的

/* function fun() {
  console.log(arguments); 
  // Arguments(9) [1, 2, 3, 4, 5, 6, 7, 8, 9, callee: ƒ, Symbol(Symbol.iterator): ƒ]
}
fun(1, 2, 3, 4, 5, 6, 7, 8, 9); 
*/

var res = 0;
function fun() {
  for (var i = 0; i < arguments.length; i++) {
    res += arguments[i];
  }
  return fun;
}
// 函数返回值尤为重要 只要逻辑正确 返回什么值都可以
fun(1, 2, 3, 4, 5, 6, 7, 8, 9)(10, 11, 1, 2)(1, 2, 34);
//因为返回值是一个函数 所以相当于第一次调用返回一个fun函数然后再调用第二个括号
console.log(res); //106

# 定时器 setInterval

连续点击,速度越来越快。
原因:每点击一次就开一个定时器,点击几次就有几个定时器同时工作。
解决:保证每次只有一个定时器工作,先 clearInterval ()

var res = setInterval(function () {
  // 语句
}, 1000);
// 其中函数可以是自定义函数

clearInterval(res); //关闭定时器

# 延时器 setTimeout

clearTimeout () 停止
setTimeout () 用法和 setInterval 一样

setTimeout(function () {
  console.log("111111");
}, 1000);

# 同步和异步

  • 同步:阻塞,当前程序运行,必须等前一个程序运行完毕以后,才能运行。
  • 异步:非阻塞,当前程序运行,和前面程序的运行没有任何关系。
  • 同步操作:写的代码 90% 都是同步操作
  • 异步操作:jQuery 动画 计时器 ajax……
  • 异步和同步都出现的时候,同步优先于异步执行
function x(a) {
  console.log(a);
}
for (var i = 0; i < 3; i++) {
  setTimeout(function () {
    x(i);
  }, 1000);
}
// 答案是一秒之后输出 3次3
// 把 var 换成 let 输出 0 1 2

# RegExp 正则表达式

其实就是一个用来检测字符串或数字的规则
这里边写什么东西就代表要检测什么东西,最两边不可以有空格

# 创建

  • 1、通过 new 去声明正则表达式
    第一个参数:正则表达式的主体 字符串
    第二个参数:修饰符 i g
    【注】修饰符没有顺序

  • 2、省略 new 运算符去声明正则表达式

  • 3、通过常量赋值

var box1 = new RegExp("hello", "ig"); // /hello/gi
var box1 = RegExp("hello", "ig"); // /hello/gi
var re = /A/; //包含一个大写字母A   //  /A/
var box1 = /hello/gi;
alert(box1); //  /hello/gi

# 规则

单个数字和字符的元字符:
.          匹配单个的任意字符
[范围]     匹配单个范围内的字符
[0-9]      匹配单个的数字
[123]      检测一位1或2或3
[a-zA-Z0-9_] 匹配单个的数字、字母下划线
var re = /g[a-zA-Z0-9_]ogle/;
var re = /[a-zA-z]/ 代表一位字母,大小写无所谓
[^范围]     匹配任意一个除括号范围内的字符
[^0-9]     匹配任意一个非数字字符
[^abcdef]   一位非小写字母a b c d e f 的字符    就相当于对中括号内的内容取反
\w         一位数字字母下划线  等价于 [a-zA-Z0-9_]
\W         一位非数字字母下划线
\d         一位数字  等价于 [0-9]
\D         一位非数字  等价于 [^0-9]
var userRe3 = /[^\u4e00-\u9fa5\w]/; // 一位 非汉字 数字 字母 下划线

汉字:
var re = /[\u4e00-\u9fa5]/

重复字符  x(任意的单个字符)
x?    匹配0个或者1个x
x+    匹配至少一个x字符
x*    匹配任意个x字符
x{m,n}匹配至少m个,最多n个x字符,包括n
x{n}  必须匹配n个x字符
(xyz)+ 小括号括起来的部分是当作单个字符处理

var re = /^[b-m]{8}/ 以8位b-m的小写字母开头
{数字}  多少位
{10} 10位
{1,} 简写成 +  至少一位
{0,1} 简写成 ? 没有或者有一位
{2,5}   2-5 位
{0,} 简写成 * 有没有都可以
要注意 {} 只能对前面的一位生效

空白字符
\s   匹配任意单个的空白字符
\S   匹配任意单个非空白字符

锚字符
^  行首匹配  必须以这个正则开头
$  行尾匹配  必须以这个正则结尾
var re = /^hello$/==>以同一个hello开头和结尾,而不是在开头和结尾各有一个hello

转义字符:
\.  代表本来.字符的意思
\*  代表本来*字符的意思

替代字符  |   或运算 可以写多个
var box = /google|baidu|bing/
var re = /a(b|c)/ 包含ab或ac

修饰符
i  忽略大小写
g  全局匹配
m  换行匹配  【注】如果在字符串,遇到换行,重新开始计算行首。
var str = "1、ba13idu\n2、go33ogle\n3、b12ing";
var box = /^\d/gm;
alert(str.replace(box, "*")); //只替换123而字符串里边的不替换
/* *、ba13idu
*、go33ogle
*、b12ing */

() 分组
分组内的一个特殊写法   (?=x)  后面紧跟着 x 的
var re2 = /a(?=[ab])/;
console.log(re2.test("abaac")); //true

// replace 后边跟函数案例
function template(templateStr, data) {
  // 这里的 \$ 是转义 $
  const re = /\${([a-zA-Z]+)}/g;
  // 有几个分组就写几个 b,从 b 依次类推
  return templateStr.replace(re, (a, b) => {
    // a:匹配的字符串  b:分组(正则的分组())匹配到的  没有分组的话指的是开始匹配的索引
    // console.log(a, b);
    return data[b];
  });
}

# 方法

test
格式:正则.test(字符串)
功能:在字符串中匹配这个正则是否存在
返回值:如果匹配成功返回true,匹配失败返回false。

exec(了解  W3C)
格式:正则.exec(字符串)
功能:在字符串中匹配这个正则是否存在
返回值:返回匹配到的串
匹配成功,返回一个装有字符串的数组(第一项是字符串内满足正则的部分,可以使用[0]获取)
匹配失败,返回null

var str = "how aRe you";
var box = /are/i;
alert(box.test(str)); //true

var str = "how aRe you";
var box = /are/i;
alert(box.exec(str)[0]);

# 在字符串中使用正则的方法

字符串的函数:

match()
    格式:字符串.match(正则)
    功能:在字符串匹配是否有符合正则表达式,
    返回值:匹配成功,返回装有匹配到子串的数组
            匹配失败,返回null
replace()
    格式:字符串.replace(oldStr/正则, newStr);
    功能:用newStr将oldStr替换,先整体看,然后再替换
    返回值:替换成功的新字符串。
    $& 插入匹配的子串。var newStr = str.replace(re, "-$&");
    //将匹配到的字符串替换成 -匹配到的字符串

    //把一个字符串的驼峰写法变成烤串写法
    // 例如 'helloWorld' 变成 'hello-world' 'mainTopLeft' 变成 'main-top-left'
    function hump(str) {
      var re = /[A-Z]/g;
      var newStr = str.replace(re, "-$&");
      newStr = newStr.toLowerCase();
      return newStr;
    }
    var name = hump("mainTopLeft");

split()
    格式:字符串.split(分割符/正则);
    功能:用分割符将原字符串进行分割
    返回值:分割剩下的子串组成的数组。

search()
    格式:字符串.search(子串/正则)
    功能:找到符合条件的子串第一次出现的位置
    返回值:
        如果找到,返回>=0的下标
        否则,返回-1(代表什么都没找到)
var str = "how are Are ARE you";
var box = /arex/gi;
console.log(str.match(box)); //null
var box = /are/gi;
console.log(str.match(box)); //(3) ["are", "Are", "ARE"]

var str = "how are Are ARE you";
var newStr = str.replace(/are/gi, "*");
console.log(newStr); //how * * * you

var str = "how are Are ARE you";
var arr = str.split(/are/i);
console.log(arr); //(4) ["how ", " ", " ", " you"]

var str = "how Are are ARE you";
console.log(str.search("are")); //8
console.log(str.search(/are/gi)); //4

# 手机号练习 (手机号 11 位)

中国电信号段
133、149、153、173、177、180、181、189、190、191、193、199
中国联通号段
130、131、132、145、155、156、166、167、171、175、176、185、186、196
中国移动号段
134(0-8)、135、136、137、138、139、1440、147、148、150、151、152、157、158、159、172、
178、182、183、184、187、188、195 、197、198

1     第一位
3(0-9)    4(45789)    5(012356789)   6(67)   7(1235678)    8(0-9)   9(01356789)

134(0-8)    144(0)    特殊

手机号规则
var phoneRe = /^1(3[012356789]|4[5789]|5[012356789]|6[67]|7[1235678]|8\d|9[01356789])\d{8}$/;
var phoneRe1 = /^(134[0-8]|1440)\d{7}$/;

var phoneRe = /^1(3[012356789]\d|4[5789]\d|5[012356789]\d|6[67]\d|7[1235678]\d|8\d{2}|9[01356789]\d|34[0-8]|440)\d{7}$/;
var str = "14408585721";
console.log(phoneRe1.test(str)); //true
console.log(phoneRe.test(str)); //true

# 练习

文件是否是压缩包 zip  rar  gz
var box = /^\w+\.(zip|rar|gz)$/;
// 文件名至少是一个数字字母下划线后面必须跟一个点它必须以zip,rar,gz结尾
alert(box.test("hello.zip"));

验证是否是正确的手机号码
var box = /^1\d{10}$/;
// 以1开头后面是任意的10个数字

验证是否是正确的身份证号码(18位)
var box = /^[1-9]\d{16}(\d|x)$/;
验证字符串是否是纯中文
var box = /^[\u4e00-\u9fa5]+$/;
alert(box.test("我爱北京啊大大"));

判断重复
x(?=y) 匹配 x 后面仅仅跟着 y 的内容
/^(\d)\1+$/  全部是相同的数字
()\1    前面括号内的相同的
var re = /^(ab)\1+$/;
var str = "abab";
console.log(re.test(str));  //true
var re2 = /a(?=[ab])/; //检测a后面跟没跟着a或b

var re = /\d{2}/;
var str = "今天最高 30 摄氏度,最低 10 摄氏度";
var str1 = "今天 30 摄氏度";
console.log(re.exec(str1)[0]);  //拿到了30
console.log(re.exec(str));  //拿到了30

# Js 内 \ 转义符

console.log("\'""); 输出'"

# BOM (浏览器对象模型 浏览器窗口)

# 系统对话框

window 方法 (一般情况下window可以省略)

alert() 弹出警告框

confirm() 弹出一个带确定和取消的提示框
返回值:如果点击确定,返回true
        如果点击取消,返回false

prompt() 弹出一个带输入框的提示框
参数:
    第一个参数:面板上显示的内容
    第二个参数:输入框里面的默认(可以不传入)
返回值:点击确定,返回输入框中的内容
        点击取消,返回null。

# open,close 方法

open()
第一个参数:跳转的url  打开一个新窗口,加载url
第二个参数:字符串,给打开的窗口起一个名字
第三个参数:一串特殊含义的字符串,可以控制打开窗口的属性

$(".btn").click(function(){
  open(
  "https://www.baidu.com",
  "xxx",
  "width=400,height=400,top=200,left=300,scrollbars=yes"
);
})
close() 关闭某一个窗口

# onresize 属性

该属性是监听窗口变化的事件函数 (绑定事件时最直接的那个函数)

window.onresize = function () {
  console.log("窗口大小变化了");
};

# onscroll 原生的页面滚动条事件

window.onscroll = function () {
  // 滚动条距离顶部的距离
  var x = window.scrollX;
  // 别称 pageXOffset
  var y = window.scrollY;
  // 别称 pageYOffset
  console.log(x, y);
};

# requestAnimationFrame()

让浏览器帮助你反复执行一件事,执行的时候每秒限定次数 每秒 60 次,类似于递归但又不是递归

递归:函数内部调用函数本身

var num = 0;
function step() {
  num++;
  if (num < 100) {
    console.log("111");
    window.requestAnimationFrame(step);
    // step() //这里是递归,控制台出现一堆,而requestAnimationFrame是一个且前面有执行次数
  }
}
window.requestAnimationFrame(step); //99次111

# history 对象

window.history 掌管的是,当前窗口 (注意不是浏览器) 历史记录 (只要加载的 url 不一样就会产生历史记录)

属性
    history.length 输出当前窗口历史记录的条数
方法
    history.back()  返回上一条历史记录
    history.forward() 前进到下一条历史记录
    history.go()
    参数:   0  刷新当前页面
            正整数 前进n条记录
            负整数 后退n条记录

# location 对象 (地址栏)

中文版:协议:// 主机名:端口号 / 路径 /? 查询字符串 #锚点
英文本:protocol://hostname:port/pathname/?search#hash

# 方法

方法:
location.assign(url)
【注】在当前窗口跳转到这个url,有历史记录
location.replace(url)
【注】在当前窗口替换成新的url。不会产生历史记录。
location.reload()
【注】刷新窗前窗口
location.reload(true)   不经过浏览器缓存强制从服务器重载

# 属性

location.href  获取或者设置当前页面的地址
location.protocol  file: 本地磁盘访问;
                   http:
                   https: 证书认证协议;

location.host   获取主机(域名)和端口号(如果后面带了)
location.hostname  主机名(域名) IP(在全球范围内找到你当前网络的地址)
                   域名 就是 IP的别称

location.port 端口号(默认隐藏的)
注:是当前电脑中使用网络的软件,随机给它分配一个编号 0-65535
可以直接定位到当前使用网络的程序
小细节:浏览器8080  http80  https443

location.pathname   路径

location.search 查询字符串(前后端交互) ?
?name1=value1&name2=value2

location.hash   获取或者设置当前页面地址的锚点
window.onhashchange = function(){}//监听锚点事件

当网页在不同的平台打开时可以使用 navigator 获取一些打开该页面的应用程序的信息

$(".navigator").click(function () {
  console.log(navigator.appCodeName);
  console.log(navigator.appName);
});

# 递归 (函数内调用函数本身)

递归方法:

  • 1. 首先去找临界值 ,即无需计算,获得的值
  • 2. 找 这一次和上一次 的关系
  • 3. 假设当前函数已经可以使用, 调用自身计算上一次

当形成递归的时候 递归函数内声明的变量是不可以相互访问的 需要递归函数设置返回值,最后的 return 才是真正的返回值
return 后面什么都不写代表:返回,不往下面跑了,函数不需要返回值,所以就什么都不加

# 二叉树的查找

var arr = [
  {
    id: 1,
    label: "一级 1",
    children: [
      { id: 2, label: "二级 1-1", children: [{ id: 3, label: "三级 1-1-1" }] },
    ],
  },
  {
    id: 4,
    label: "一级 2",
    children: [
      { id: 5, label: "二级 2-1", children: [{ id: 6, label: "三级 2-1-1" }] },
      { id: 7, label: "二级 2-2", children: [{ id: 8, label: "三级 2-2-1" }] },
    ],
  },
  {
    id: 9,
    label: "一级 3",
    children: [
      {
        id: 10,
        label: "二级 3-1",
        children: [{ id: 11, label: "三级 3-1-1" }],
      },
      {
        id: 12,
        label: "二级 3-2",
        children: [{ id: 13, label: "三级 3-2-1" }],
      },
    ],
  },
];
function findObjById(id, arr) {
  var currentObj = null;
  currentObj = arr.find(function (item) {
    return item.id === id;
  });
  if (currentObj) {
    return currentObj;
  } else {
    for (var i = 0; i < arr.length; i++) {
      // children 属性返回元素的子元素的集合
      // 这里 arr 的 length 为 3
      if (arr[i].children && arr[i].children.length > 0) {
        // 第二层 find 三次
        currentObj = findObjById(id, arr[i].children);
        if (currentObj) {
          return currentObj;
        }
      }
    }
  }
}
var res = findObjById(2, arr);
console.log(res);

# 另一种二叉树查找

var arr = 用的是上边的树;
//创建一个查找序列 将二叉树的第一层数据放进去
var newArr = arr.slice(0);
var id = 2;
var obj = null;
for (var i = 0; i < newArr.length; i++) {
  // console.log(newArr.length); //如果一直没找到,这里的 length 会一直变大
  if (newArr[i].id === id) {
    obj = newArr[i];
    break;
  } else {
    if (newArr[i].children && newArr[i].children.length > 0) {
      newArr = newArr.concat(newArr[i].children); //concat连接数组
      // 如果没在父级找到,就将本层的子元素连接上,从子元素中找
    }
  }
}
console.log(obj);

# 闭包

闭包就是 能够读取其他函数内部变量的函数 。
例如在 js 中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成 “ 定义在一个函数内部的函数 “。
在本质上,闭包是将函数内部和函数外部连接起来的桥梁。

// 函数内嵌套函数就形成了闭包
// 闭包就是作用域的嵌套 而且嵌套关系永远存在
// 闭包外层定义的变量会一直存储在内存中,等待闭包内层作用域访问
// 内存占用比较大
function fun() {
  var num = 10;
  function fun1() {
    num++;
    console.log(num);
  }
  return fun1;
}
var newFun = fun();
newFun(); //11
newFun(); //12

/* for (var i = 0; i < 5; i++) {
  // var x = function (j) {
  //   console.log(j); //0 1 2 3 4
  // };
  // x(i);

  (function (j) {
    setTimeout(function () {
      console.log(j);
    }, 1000); //一秒之后 01234
  })(i);

  // setTimeout(function () {
  //   console.log(i);
  // }, 1000); //一秒之后 5个5
} */

//   页面中 ul > 5个 li 点击 li 分别输出对应索引
var liArr = document.querySelectorAll("ul li");
for (var i = 0; i < liArr.length; i++) {
  /* (function (j) {
    liArr[j].onclick = function () {
      console.log(j);
    };
  })(i); */
  // 或者 总之形成闭包就可以
  liArr[i].onclick = (function (j) {
    return function () {
      console.log(j);
    };
  })(i);
}

function fun(n, o) {
  // 第一层闭包外层
  console.log(o);
  return {
    // 第一层闭包内层
    fun: function (m) {
      return fun(m, n); //又生成了一个闭包(相当于把最外层的整个fun复制到了这里)
    },
  };
}
// var a = fun(0); //undefined
// 0只给了n,没给o
// a 拿到的是第一个return返回的那个函数(第一层闭包内层),所以之后的每次调用都是调用第一次的
// a.fun(1); //0 因为形成了闭包所以是0(因为父级是0)
// a.fun(2); //0
// a.fun(3); //0

// var b = fun(0).fun(1).fun(2).fun(3); //undefined 0 1 2
//像这种连续的就会一直返回最外层的fun,就一直复制粘复制粘

var c = fun(0).fun(1); //undefined 0
// a 拿到的是前两个(第一个return和第二次return)的函数,
// 所以之后的每次调用都是在第二次的基础上
c.fun(2); //1
c.fun(3); //1

# DOM (document 文档对象模型)

# 节点类型

<div id = 'div'>div文本</div>
元素节点(标签)  <div></div>
属性节点(标签的属性)  id = 'div1'
文本节点(标签内的文本内容)  div文本

# 元素节点的获取

document.getElementById(id);
例:var box = document.getElementById("box")

node.getElementsByTagName(标签名);
功能:从node节点开始,通过标签名获取符合条件的元素节点。
使用起来和数组类似,一般情况,把这种叫做伪数组/类数组(自己起)
返回值:伪数组/类数组
例:var box = document.getElementsByClassName("div")[1]

node.getElementsByClassName(class名字)   (IE8以下不兼容)
功能:通过class名字获取符合条件的元素节点。
返回值:伪数组/类数组
例:var box = document.getElementsByClassName("box")[1]

document.getElementsByName(name属性的值);
功能:通过name属性的值获取符合条件的元素节点。
【注】一般使用在表单元素里。

document.querySelector()
返回值:一个元素节点,找到符合条件的第一个元素节点。
var node = document.querySelector("#ol1");
参数:字符串  CSS选择器格式字符串。

document.querySelectorAll()
返回值:返回值,是一个伪数组。
var nodes = document.querySelectorAll('#ul1');
var nodes = document.querySelectorAll("ul [name=hello]");
参数:字符串  CSS选择器格式字符串。

element.firstElementChild /lastElementChild 返回第一个/最后一个子元素(不包括文本节点以及注释节点)

# 事件绑定

原生 dom 元素.on 事件名 = function ()

onclick;
onchange 就是域的内容发生改变的时候触发,在input上失去焦点的时候触发
oninput 就是域的内容发生改变的时候触发,在input上实时触发
onblur 触发条件是当元素失去焦点时触发,
document.querySelector(".btn").onkeydown = function (event) {
  // 获取键盘码  根据键盘码判断到底的是什么键
  // 需要通过事件对象  event
  // event.preventDefault()   阻止默认行为
  // event.stopPropagation //阻止事件冒泡
  // event.pageX  //距离文档左部的距离
  // event.pageY  //距离文档顶部的距离
  // event.target //鼠标真正接触到的元素 this:谁绑定的事件就是谁
  // event.type //事件类型
  // event.keyCode  //键盘码
  // event.which  //按键码 鼠标左键1
  // event.timeStamp  // 事件属性可返回一个时间戳(指示发生事件的日期和时间)
  // 优化js高频率代码的一种解决方式
};

// 当页面准备好的时候
$(document).ready(function () {});
上面的简写
$(function(){})

window.onload = function () {};

# 修改样式

dom 元素.style
获取该元素的行内样式表对象 这个对象内的属性可以直接修改 也可以获取

var box = document.querySelector(".box");
box.style.width = "300px";
box.style.backgroundColor = "red";

# 修改属性,获取属性,删除属性

// .className 可以获取或修改元素的class名
box.className;
box.className = box.className + " " + "active";

dom.tagName;    元素的标签名 且是大写的字符串 //element.tagName === "BUTTON"

<li>
  666
  <button class="del" onclick="delFun(event)">删除</button>
</li>
onclick="delFun(event)" ===> del.onclick = function(event){delFun()}
//在delFun前加个this就可以拿到del对象

// 修改属性;
// 原生dom元素.setAttribute(名,值)
box.setAttribute("title", "我是box");
// 获取属性
// 原生dom元素.getAttribute(名)
console.log(box.getAttribute("class"));
// 删除属性
// 原生dom元素.removeAttribute(名)   跟设置成空类似
box.removeAttribute("title");

# 访问对象下的属性可以使用 []

var obj = {
  "a-b": 10,
  x: 1000,
};
var x = "x";
console.log(obj[x]); // 1000
console.log(obj["a-b"]); //10
console.log(obj["x"]); //1000

# 元素节点的属性 (文本内容)

innerHTML  获取标签间内容  会解析标签
innerText  获取标签间纯文本  不会解析标签,设置纯文本
outerHTML  从外标签开始到外标签结束   会解析标签

# 获取子节点

childNodes   访问当前节点下所有的子节点
firstChild   访问子节点中的首位
lastChild    访问子节点中的最后一位
nextSibling  访问当前兄弟节点中的下一个节点(下一个同胞节点)
previousSibling  访问当前兄弟节点中的上一个节点(前一个同胞节点)

【注】上述这些属性都包含文本节点


【注】下述这些方法只获取子节点中的元素节点。(IE8以下不兼容)
children 属性返回元素的子元素的集合
firstElementChild 第一个节点
lastElementChild  最后一个节点
nextElementSibling 下一同级节点
previousElementSibling  上一同级节点

         nodeType     nodeName    nodeValue
元素节点     1          标签名       null
属性节点     2          属性名       属性值
文本节点     3          #text       文本内容

空格、回车、换行 看不见,是字符。

【注】获取当前节点的父节点通过parentNode获取。

【注】获取当前整个页面的根节点  document

# 属性节点

attributes 获取当前元素节点上的所有的属性节点

<div id="div1" title="hello" class="box">
  div文本
</div>;

var oDiv = document.getElementById("div1");
alert(oDiv.attributes["title"].nodeName);
alert(oDiv.attributes["title"].nodeType);
alert(oDiv.attributes["title"].nodeValue);

表单元素.value属性  获取或修改
console.log(textarea.value);

# 节点操作

document.write()
【注】会覆盖页面上原有的内容。

createElement()
格式:document.createElement()
参数:标签名
返回值:创建好的这个节点
document.createElement("li")

appendChild()
格式:node1.appendChild(node2);
功能:将node2节点插入到node1节点子节点的末尾
将新节点追加到子节点列表的末尾

append()  //ie不支持
node1.append(node2,node3)
功能:将node2,node3节点插入到node1节点子节点的末尾
将新节点追加到子节点列表的末尾

createTextNode()
格式:document.createTextNode(文本);
功能:创建文本节点(纯文本)

insertBefore()
格式:box1.parentNode.insertBefore(box2, box1);
功能:将box2添加到box1的前面
必须用box1的父节点去调用

replaceChild()
格式:box1.parentNode.replaceChild(box2, box1);
功能:用box2节点将box1节点替换掉。
必须用box1的父节点去调用

cloneNode()
格式:node.cloneNode()
格式2:node.cloneNode(true);  克隆节点本身和子节点
返回值:克隆出来的新节点

removeChild()
格式:box.parentNode.removeChild(box);
功能:将box节点从页面上删除
必须用box1的父节点去调用
父元素.removeChild(子元素)

remove()  //ie不支持
元素.remove()
删除元素自己(元素是谁就删除)

.parentNode //查找父级
不能加括号,因为是属性

# 节点操作例子

<body>
  <div id="div1">
    <em>em</em>
    div文本
    <strong>strong</strong>
  </div>
  <button id="btn1">节点操作</button>
</body>;

window.onload = function () {
  var oBtn = document.getElementById("btn1");
  var oDiv = document.getElementById("div1");
  oBtn.onclick = function () {
    // document.write("<h1>hello world</h1>");
    /* var oP = document.createElement("p");
    var oTxt = document.createTextNode("<h1>hello world</h1>");
    oP.appendChild(oTxt);

    // oDiv.appendChild(oP);

    //将oP节点插入到oDiv节点的前面
    // document.body.insertBefore(oP, oDiv);

    //用oP节点,将oDiv节点替换掉
    document.body.replaceChild(oP, oDiv); */

    // var newNode = oDiv.cloneNode();
    /* var newNode = oDiv.cloneNode(true);
    document.body.appendChild(newNode); */

    document.body.removeChild(oDiv);
  };
};

文章作者: Mrr-cxh
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Mrr-cxh !
赏
 上一篇
Java Script 4.0 Java Script 4.0
讲述音乐播放器案例,this关键字,强制改变this的方法,offset系列,事件(事件冒泡,委托,监听器……),本地存储技术,Set和Map集合,prototype,函数防抖和节流,深浅拷贝
2020-11-15
下一篇 
Java Script 2.0数组专栏 Java Script 2.0数组专栏
数组专栏。数组是用于储存多个相同类型数据的集合。JavaScript(简称“JS”) 是一种具有函数优先的轻量级,解释型或即时编译型的编程语言。虽然它是作为开发 Web 页面的脚本语言而出名,但是它也被用到了很多非浏览器环境中。
2020-09-29
  目录