JavaScript

JavaScript

JavaScript第一步

https://developer.mozilla.org/zh-CN/docs/Learn/JavaScript/First_steps

1.脚本调用——async和defer


    <script  async src="jquery.js"></script>
    <script  asynnc src="index.js"></script>

async 异步,可以解决调用顺序问题,告知浏览器在遇到<script>元素时不要中断后续HTML内容的加载,而是直接下载然后运行。

注意点
1.只能用于外部脚本;
2.直接下载然后运行,导致脚本的运行次序无法控制;
3.使用情况,当脚本无需等待页面解析,且无依赖独立运行时;

    <script  defer src="jquery.js"></script>
    <script  defer src="index.js"></script>

defer 脚本将按照在页面中出现的顺序加载和运行

使用情况
当脚本需要等待页面解析,且依赖于其他脚本,调用这些脚本时应使用defer,将关联的脚本按所需顺序置于HTML中。

2.字符串 String


  • 查找字符串 indexOf()

    str = 'my piana';
    str.indexOf('piana');  //返回3
    str.indexOf('your');  //返回-1
    
  • 提取字符串
    slice(start[,end]) 注: 可为负索引,不修改原String和Array
    substring(start[,end])
    substr(start[,length]) 注: 可为负索引

      str.slice(0,3);
      str.slice(2);
    
  • 转换大小写
    toUpperCase()
    toLowerCase()

  • 替换
    replace() 注: 只替换首个匹配;可使用正则表达式匹配字符

3.字符串与数组之间的转换


字符串 -> 数组 split()
数组 -> 字符串 join() toString()

    let myData = 'a,b,c,d,e,f';
    let myArray = myData.split(','); //["a","b", "c", "d", "e", "f"]
    let myyNewString = myArray.join('*');  //"a\*b\*c\*d\*e\*f"
    let str = ['dog','cat'];
    str.toString();    //"dog,cat"

实例:

  • number-guessing-game-start.html
  • index.html
    style.css
    raw-text.txt
    main.js

0527

创建JavaScript代码块

https://developer.mozilla.org/zh-CN/docs/Learn/JavaScript/Building_blocks

  • if-else switch
  • 循环:for while
  • 基本函数
  • 事件
  • 事件冒泡与事件捕获

1. 条件——switch

实例:theme.html

2. break和continue

break 立即退出循环
continue 结束当前循环,转而执行下一个循环

3. 事件


  • 事件处理器属性
    例如:
    btn.oncilick = function(){};
    onfocus、onblur、onchange、onmouseover、onmouseout

    const btn = document.querySelector('button');
    btn.onclick = function() {
    const rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
    document.body.style.backgroundColor = rndCol;
    }
    
  • 行内事件处理器 (勿用)

  • addEventListener()和removeEventListener()
    参数1:事件 参数2:执行的操作
    随机背景颜色转换代码:

    const btn = document.querySelector('button');
    function bgChange() {
      const rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
      document.body.style.backgroundColor = rndCol;
    }
    btn.addEventListener('click', bgChange);
    
其他事件

在处理函数内部,会有一个固定指定名称的参数。例如eventevte。被称为事件对象

function bgChange(e) {
  const rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
  e.target.style.backgroundColor = rndCol;
  console.log(e);
 }
 btn.addEventListener('click', bgChange);

4. 事件冒泡及事件捕获


捕获阶段:

  • 浏览器检查元素的最外层祖先<html>,是否在捕获阶段中注册了一个onclick事件处理程序,如果是,则运行它。
  • 然后,它移动到<html>中单击元素的下一个祖先元素,并执行相同的操作,然后是单击元素再下一个祖先元素,依此类推,直到到达实际点击的元素。

冒泡阶段: (默认情况下)

  • 浏览器检查实际点击的元素是否在冒泡阶段中注册了一个onclick事件处理程序,如果是,则运行它
  • 然后它移动到下一个直接的祖先元素,并做同样的事情,然后是下一个,等等,直到它到达<html>元素。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dquUFXWC-1646193593383)(img/bubble.png)]

Array详解

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array

1. 遍历数组 forEach()


var fruits = ['Apple', 'Banana'];
fruits.forEach((item, index, Array) => {
  console.log(index, item);
})

2. 数组添加、删除项 push() pop() unshift() shift()


push() pop()
数组末尾添加,返回数组长度
unshift() shift()
数组起始处添加,返回变动的元素

    let myArr = ['cat','dog'];
    myArr.push('dollar'); //['cat','dog','dollar']
    let nowLength = myArr.push('blue'); //4
    let removeItem = myArr.shift(); //'cat'

3. 删除、替换现有元素或原地添加新的元素 splice()


语法:array.splice(start[, deleteCount[, item1[, item2[, ...]]]])
start起始位置
deleteCount删除的元素个数
item添加的元素

返回值:删除——输出删除的元素组成的数组;否则返回空数组

const months = ['Jan', 'March', 'April', 'June'];
// 添加
months.splice(1, 0, 'Feb'); // inserts at index 1
console.log(months);  // expected output: Array ["Jan", "Feb", "March", "April", "June"]
// 删除
months.splice(4, 1);  // replaces 1 element at index 4
console.log(months);  // expected output: Array ["Jan", "Feb", "March", "April"]
// 替换
months.splice(1,1,'2');
console.log(months);  // expected output: Array ["Jan", "2", "March", "April"]

4. 分割、深拷贝数组 slice()


语法:arr.slice([begin[, end]])
返回值:一个含有被提取元素的新数组

let newFruits = fruits.slice();
const animals = ['ant', 'bison', 'camel', 'duck', 'elephant'];
animals.slice(2);// expected output: Array ["camel", "duck", "elephant"]
animals.slice(2, 4);// expected output: Array ["camel", "duck"]
animals.slice(1, 5);// expected output: Array ["bison", "camel", "duck", "elephant"]

5. 查找第一个满足测试函数的元素 find()


返回元素的值 find()
返回元素的索引 findIndex()

const array1 = [12, 7, 99, 34];
let found = array1.find(element => element>10);
console.log(found);  // 12
let foundIndex = array1.findIndex(element => element<10);
console.log(foundIndex);  // 1

6. 创建新数组 map()


返回值为一个原数组每个元素执行回调函数的结果组成的新数组

const array2 = [1, 3, 4, 6, 9];
let doubleArray = array2.map(element => element*2);
console.log(doubleArray); // [1, 9, 36, 81]

7. 过滤数组成员 filter()


返回值:满足条件的新数组

    let array1 = [1, 3, 5, 6];
    array1.filter((elem) => {
        return (elem > 3)
    }); // [5,6]

回顾答疑


1. 问: String的slice方法和Array中的slice方法有设区别?

  • String.slice(start,end) 返回起止下标之间的字符;
    Array.slice(start,end) 是对数组深拷贝的过程,常用的除了分割数组,就是数组的深拷贝;

2. 问:深拷贝与浅拷贝的差别

  • 浅拷贝

    • 基本数据类型(number, string, boolean, null, undefined):
      名值存储在栈内存中,值引用,实际上内存引用,指向了某一处内存的值

      let a = 1;
      let b = a;
      
      栈内存
      nameval
      a1

      复制 b=a ,栈内会新开辟一块内存

      栈内存
      nameval
      a1
      b1
      此时修改a的值,此时不会改变b的值
    • 引用数据类型(Object, Array, Date):
      名存在栈内存中,值存在堆内存中,栈内存会提供一个引用的地址指向堆内存中的值。数组指向了同一处内存的值,如果 该处内存值发生了变化,浅拷贝的赋值变量值也会改变。

          let myArr = [0, 1, 2, 3, 4];
          let newArr = myArr;
          a[0] = 1;
      

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UUaoZv7Y-1646193593387)(img/shallow_copy1.png)]
      当newArr = myArr进行拷贝时,复制myArr的引用地址
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2RleTq8e-1646193593390)(img/shallow_copy2.png)]
      修改数组myArr的值,newArr也会改变
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YBq8OMOV-1646193593395)(img/shallow_copy3.png)]

  • 深拷贝
    则是指从原数组内存处取出值,重新赋值到一块新的内存中,原数组值的修改不会影响到新的数组。
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KnjOKaG9-1646193593398)(img/deep_copy.png)]
    slice concat深拷贝过程

     let a=[1,2,3,4],
         b=a.slice();
     a[0]=2;
    console.log(a,b);
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bjfI7ebo-1646193593400)(img/Array_slice1.png)]

      let a=[0,1,[2,3],4],
      b=a.slice();
      a[0]=2;
      a[2][0] = 100;
      console.log(a,b);
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nIgR2oCM-1646193593402)(img/Array_slice2.png)]
    b对象的一级属性确实是深拷贝的过程,拥有独立的内存。但是二级属性还是公用了地址,所以还是浅拷贝的过程。
    综上:slice concat是不完全的深拷贝

3. 问:全部替换应该怎么做

  • 使用正则表达式 /g 全局搜索匹配

    let str = 'my test replaceAll my test.'
    let newStr = str.replace(/my/g,'your');
    console.log(str);
    console.log(newStr);
    

4. const arr3 = arr1.concat(arr2)修改 arr1之后arr3会有影响吗?修改arr2呢?

  • cancat返回一个新数组,修改原数组,arr3不变;深拷贝过程

5. 在对数组遍历过程中 在forEach遍历中,break/return会有什么影响吗?

  • 在foreach中是不能通过break continue return来终止循环,会报错

6. 性能调优:怎么在ES5范畴内终止数组遍历?ES6上有没有其他的方法呢?

Object详解

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object


1. 箭头函数

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions

  • 基础语法

    // 传递多个参数
    (param1, param2,, paramN) => { statements }
    (param1, param2,, paramN) => expression;  //相当于:(param1, param2, …, paramN) =>{ return expression; }
    // 当只有一个参数时,圆括号是可选的:
    (singleParam) => { statements }
    singleParam => { statements }
    // 没有参数的函数应该写成一对圆括号。
    () => { statements }
    // 声明函数 用const更命名,方便调用
    const setTheme = ()=>{}
    setTheme();  // 函数调用和执行
    
  • 箭头函数有几个使用注意点。

    • (1)箭头函数没有自己的this对象。function/this.js
    • (2)不可以当作构造函数,也就是说,不可以对箭头函数使用new命令,否则会抛出一个错误。
    • (3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
    • (4)不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
    • (5)由于箭头函数没有自己的this,所以当然也就不能用call()、apply()、bind()这些方法去改变this的指向。

ES6

https://es6.ruanyifeng.com/

1. let 和 const


let

  • 暂时性死区(temporal dead zone,简称 TDZ):在代码块内,使用let命令声明变量之前,该变量都是不可用的。
    ES6 明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。
    注: typeof会因为TDZ出现错误

         typeof x;  // ReferenceError
         let x;
       typeof y; //undefined
    

- 不存在变量提升。`var`声明变量可以在声明之前使用,值为**undefined**;`let`声明变量可以在声明之前使用会**报错**
- 不允许在系统作用域内,重复声明同一个变量

**`const`**

- 声明一个只读变量,一旦声明,常量值不能改变,且一旦声明,必须立即初始化。只声明不赋值会报错
- *其他性质同 let*

### 2. 变量的解构赋值

___
**解构:** ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。

- Array
   解构不成功,变量的值=undefined

   ```js
   let [a, b, c] = [1, 2, 3];  // 可以从数组中提取值,按照对应位置,对变量赋值。
  • 解构赋值允许指定默认值。默认值可以引用解构赋值的其他变量,但该变量必须已经声明。

    let [x, y = 'b'] = ['a']; // x='a', y='b'
    let [x, y = 'b'] = ['a', undefined]; // x='a', y='b'
      let [x = 1, y = x] = [];     // x=1; y=1
      let [x = 1, y = x] = [2];    // x=2; y=2
      let [x = 1, y = x] = [1, 2]; // x=1; y=2
    
  • Object
    属性基本相同
    Object与Array解构的区别:
    数组的元素是按次序排列的,变量的取值由它的位置决定;
    而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。

        let { bar, foo } = { foo: 'aaa', bar: 'bbb' };
        foo // "aaa"
        bar // "bbb"
    
        let { baz } = { foo: 'aaa', bar: 'bbb' };
        baz // undefined
        // 变量名与属性名不一致时:
        let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
        baz // "aaa"
    

    注意点:

    1. 如果要将一个已经声明的变量用于解构赋值,必须非常写法。

      let x;
      ({x} = {x: 1});
      
    2. 解构赋值允许等号左边的模式之中,不放置任何变量名。因此,可以写出非常古怪的赋值表达式。

    3. 由于数组本质是特殊的对象,因此可以对数组进行对象属性的解构。

      let arr = [1, 2, 3];
      let {0 : first, [arr.length - 1] : last} = arr;
      first // 1
      last // 3
      
  • String
    字符串解构赋值时,字符串被转换成了一个类似数组的对象。

        const [a, b] = 'hi';
        a // "h"
        b // "i"
        // length属性解构赋值
        let {length : len} = 'hello';
        len // 5
    
  • Number boolean
    解构赋值时,如果等号右边是数值和布尔值,则会先转为对象。
    解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。
    由于undefined和null无法转为对象,所以对它们进行解构赋值,都会报错。

    let {toString: s} = 123;
    s === Number.prototype.toString // true
    
  • function 函数
    写法不同,结果也会不同

    function move({x, y} = { x: 0, y: 0 }) {
        return [x, y];
    }
    move({x: 3, y: 8}); // [3, 8]
    move({x: 3}); // [3, undefined]
    move({}); // [undefined, undefined]
    move(); // [0, 0]
    

用途:

  1. 交换变量值
  2. 从函数返回多个值
  3. 函数参数的定义
  4. 提取JSON数据
  5. 遍历Map解构
  6. 函数参数的默认值
  7. 输入模块的指定方法

4. 字符串的扩展


  • 字符的Unicode表示法

    1. 采用\uxxxx形式表示一个字符,其中xxxx表示字符的 Unicode 码点。

    2. 字符范围:\u0000 ~ \uFFFF

    3. 超出范围的字符,使用两个双字节表示,故此码点需要放入大括号内

      "\uD842\uDFB7"     // "𠮷"
      "\u20BB7"   // " 7"  等价于 \u20BB+7
      "\u{20BB7}"     // "𠮷"  正确结果
      

    注意点:
    字符的六种表示方法

        '\z' === 'z'  // true
        '\172' === 'z' // true
        '\x7A' === 'z' // true
        '\u007A' === 'z' // true
        '\u{7A}' === 'z' // true
    
  • 字符串的遍历器接口

    1. 使用for…of遍历字符串。
    2. 可识别大于0xFFFF的码点
  • 模板字符串
    插入变量时,变量名、变量表达式、调用函数需写在${}

    $('#result').append(`
        There are <b>${basket.count}</b> items
        in your basket, <em>${basket.onSale}</em>
        are on sale!
    `);
    

5. 字符串的新增方法


  • 实例方法 includes() startsWith() endsWith()
    includes():返回布尔值,表示是否找到了参数字符串。
    startsWith():返回布尔值,表示参数字符串是否在原字符串的头部。
    endsWith():返回布尔值,表示参数字符串是否在原字符串的尾部。
  • repeat()
    返回一个新字符串,表示将原字符串重复n次,小数则取整
  • padStart() padEnd()
    padStart(maxLength, addStr):头部补全,二参默认空格
    padEnd(maxLength, addStr):尾部补全,同上
  • trim() trimStart() trimEnd()
    消除空格,返回新字符串

7.数值的扩展


  • 进制
    二进制:0boB
    十六进制:0o0O
    转十进制:Number(0b1111)
  • Number.isFinite() Number.isNaN()
    Number.isFinite():检查数值有限,即非Infinity
  • Number.parseInt(), Number.parseFloat()
  • Number.isInteger()
  • Math对象扩展
    • Math.trunc方法用于去除一个数的小数部分,返回整数部分。
    • Math.sign方法用来判断一个数到底是正数、负数、还是零。对于非数值,会先将其转换为数值。
    • Math.expm1(x) 返回 ex - 1,即Math.exp(x) - 1。
    • Math.log1p(x) 方法返回1 + x的自然对数,即Math.log(1 + x)。如果x小于-1,返回NaN
    • Math.log10(x) 返回以 10 为底的x的对数。如果x小于 0,则返回 NaN。
    • (**) 指数运算符,例如 2**3

8.函数扩展


  • 函数参数
    • 参数变量是默认声明的,所以不能用let或const再次声明。
    • 参数默认值可以与解构赋值的默认值,结合起来使用
  • rest参数
    (形式为…变量名),用于获取函数的多余参数,rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。
  • 严格模式
    • 规定只要函数参数使用了默认值、解构赋值、或者扩展运算符,那么函数内部就不能显式设定为严格模式,否则会报错。
    • 函数内部的严格模式,同时适用于函数体和函数参数。
  • 尾调用,尾递归
    指某个函数的最后一步是调用另一个函数(或自身)。

9.函数的扩展


  • 扩展运算符
    • 扩展运算符(spread)是三个点(…)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列
    • 主要用于函数调用。
    • 替代函数的apply方法。
    • 应用:
      1. 复制数组同cancat——深拷贝
      2. 合并数组
      3. 与解构赋值结合
      4. 将字符串转为真正的数组
      5. 任何定义了遍历器(Iterator)接口的对象(参阅 Iterator 一章),都可以用扩展运算符转为真正的数组。
      6. Map 和 Set 结构,Generator 函数

10. 对象的扩展


  • 属性的可枚举性
    描述对象的enumerable属性,称为“可枚举性”,如果该属性为false,就表示某些操作会忽略当前属性。
    • Object.getOwnPropertyDescriptor方法可以获取该属性的描述对象
    • 有四个操作会忽略enumerable为false的属性。
      • for…in循环:只遍历对象自身的和继承的可枚举的属性。
      • Object.keys():返回对象自身的所有可枚举的属性的键名。
      • JSON.stringify():只串行化对象自身的可枚举的属性。
      • Object.assign(): 忽略enumerable为false的属性,只拷贝对象自身的可枚举的属性。
  • 遍历
    • (1)for…in
      for…in循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)。
    • (2)Object.keys(obj)
      Object.keys返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)的键名。
    • (3)Object.getOwnPropertyNames(obj)
      Object.getOwnPropertyNames返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)的键名。
    • (4)Object.getOwnPropertySymbols(obj)
      Object.getOwnPropertySymbols返回一个数组,包含对象自身的所有 Symbol 属性的键名。
    • (5)Reflect.ownKeys(obj)
      Reflect.ownKeys返回一个数组,包含对象自身的(不含继承的)所有键名,不管键名是 Symbol 或字符串,也不管是否可枚举。
  • super属性,指向当前对象的原型对象。

11. 对象的新增方法


  • Object.is() 同值相等

  • Object.assign() 方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。

    • 语法:Object.assign(target, source1, source2);
    • 注意点
      • 浅拷贝
      • 同名属性替换
      • 可处理数组
    • 应用
      • 为对象增加属性
      • 为对象增加方法
      • 克隆对象
      • 合并多个对象
      • 为属性指定默认值
  • Object.getOwnPropertyDescriptors() 方法,返回指定对象所有自身属性(非继承属性)的描述对象。

  • __proto__ 属性(前后各两个下划线),用来读取或设置当前对象的原型对象(prototype)。

  • Object.setPrototypeOf 方法的作用与__proto__相同,用来设置一个对象的原型对象(prototype),返回参数对象本身。

  • Object.setPrototypeOf 方法与Object.setPrototypeOf 方法配套,用于读取一个对象的原型对象

16. Promise 对象


  • 含义
    Promise 是异步编程的一种解决方案。所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。

    • 特点
      • (1)对象的状态不受外界影响
      • (2)一旦状态改变,就不会再变,任何时候都可以得到这个结果
  • 基本用法

    const promise = new Promise(function(resolve, reject) {
        // ... some code
     if (/* 异步操作成功 */){
        resolve(value);
     } else {
       reject(error);
      }
    });
    
  • Promise.prototype.then()

    • then方法是定义在原型对象Promise.prototype上的。它的作用是为 Promise 实例添加状态改变时的回调函数。
    • 返回值:一个新的Promise实例
  • Promise.prototype.catch() 方法是.then(null, rejection).then(undefined, rejection)的别名,用于指定发生错误时的回调函数。

  • Promise.prototype.finally() 方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。

  • Promise.all(),Promise.race() 方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。

  • Promise.allSettled(),Promise.any() 方法接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例

21. Class的基本语法


类的方法内部如果含有this,它默认指向类的实例。

22.Class的继承


Flex布局:实例篇

https://www.ruanyifeng.com/blog/2015/07/flex-examples.html
基准线:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WeAyfv1Y-1646193593407)(img/flex1.png)]

1. 骰子布局

实例:touzi.html + touzi.css

2. 网格布局

  • 基本网格布局——平均分布
  • 百分比布局,其余网格平均分配剩余空间
  • 圣杯布局 shengbei.html
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hvaPH1vG-1646193593410)(img/flex2_shengbei.png)]
  • 输入框布局
  • 悬挂式布局
  • 固定的底栏
  • 流式布局

知识点回顾

https://juejin.cn/post/6844903922084085773

1. 在浏览器输入URL回车之后发生了什么( HTTP(端口80) 请求)?

  1. URL解析

    • 地址解析:判断输入的URL是否合法
    • HSTS 会强制可会断使用HTTPS(端口403)访问页面
    • 检查缓存
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZZZtNFKi-1646193593416)(img/check_storage.png)]
  2. DNS查询

    • 基本步骤
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JLQnbyhw-1646193593418)(img/main_step.png)]
      • 检查浏览器缓存,无则调用系统库函数进行查询
      • OS的DNS缓存:检查域名是否在本地的Hosts文件里,无则向DNS服务器发送查询请求
      • 路由器缓存
      • ISP DNS缓存
      • 根域名服务器查询
        [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ruVhwQVX-1646193593423)(img/URL_check.png)]
  3. TCP连接

    TCP/IP四层结构
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S7ZsWH3j-1646193593427)(img/TCP_IP.png)]

    • 应用层:发送 HTTP 请求
      根据得到服务器的 IP 地址,浏览器开始构造一个 HTTP 报文,其中包括:
      • 请求报头(Request Header):请求方法、目标地址、遵循的协议等等
      • 请求主体(其他参数)
        注意点:
        浏览器只能发送 GETPOST 方法,打开网页使用的是GET方法
    • 传输层:TCP 传输报文
      传输层会发起一条到达服务器的 TCP 连接,为了方便传输,会对数据进行分割(以报文段为单位),并标记编号, 方便服务器接受时能够准确地还原报文信息。
      在建立连接前,会先进行 TCP 三次握手,结束时四次挥手。
    • 网络层:IP协议查询Mac地址
      将数据段打包,并加入源及目标的IP地址,并且负责寻找传 输路线。
      判断目标地址是否与当前地址处于同一网络中,是的话直接 根据 Mac 地址发送,否则使用路由表查找下一跳地址,以 及使用 ARP 协议查询它的 Mac 地址。
    • 链路层:以太网协议
      以太网协议
      根据以太网协议将数据分为以“”为单位的数据包,每一帧分为两个部分:
      标头:数据包的发送者、接受者、数据类型
      数据:数据包具体内容
      Mac 地址
      以太网规定了连入网络的所有设备都必须具备“网卡”接口,数据包都是从一块网卡传递到另一块网卡,网卡的地址就 是 Mac 地址。每一个 Mac 地址都是独一无二的,具备了 一对一的能力。
      广播
      发送数据的方法很原始,直接把数据通过 ARP 协议,向本网络的所有机器发送,接收方根据标头信息与自身 Mac 地址比较,一致就接受,否则丢弃。
      注意:接收方回应是单播。
    • 服务器接受请求
      接受过程就是把以上步骤逆转过来,参见上图。
  4. 服务器处理请求
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bZaBcw39-1646193593431)(img/server.png)]

  5. 接受响应

    • 查看 Response header,根据不同状态码做不同的事(比如上面提到的重定向)。
    • 如果响应资源进行了压缩(比如 gzip),还需要进行解压。
    • 对响应资源做缓存。
    • 根据响应资源里的 MIME 类型去解析响应内容(比如 HTML、Image各有不同的解析方式)。
  6. 熏染页面
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NBBidHrk-1646193593433)(img/ll.png)]

  7. JavaScript编译执行
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6ykWpN1c-1646193593437)(img/JS.png)]

DOM

https://www.w3school.com.cn/htmldom/index.asp

1. DOM方法


  1. 获取元素

    • getElementById(id) - 获取带有指定 id 的节点(元素)
    • getElementsByTagName() - 返回包含带有指定标签名称的所有元素的节点列表(集合/节点数组)。
    • getElementsByClassName() - 返回包含带有指定类名的所有元素的节点列表。
  2. 节点的增删改查

    • appendChild(node) - 插入新的子节点(元素)作为父元素的最后一个元素
    • insertBefore() - 作为父元素的第一个元素进行添加
    • removeChild(node) - 删除子节点(元素)
    • replaceChild() - 替换子节点。
    • createAttribute()- 创建属性节点。
    • createElement()- 创建元素节点。
    • createTextNode()- 创建文本节点。
    • getAttribute() - 返回指定的属性值。

2. DOM属性


  • innerHTML - 节点(元素)的文本值
  • nodeName - 规定节点的名称(只读)
  • nodeValue - 规定节点的值
  • nodeType - 返回节点的类型(只读)
  • parentNode - 节点(元素)的父节点
  • childNodes - 节点(元素)的子节点
  • attributes - 节点(元素)的属性节点

3. DOM修改


  • 改变 HTML 内容
  • 改变 CSS 样式
  • 改变 HTML 属性
  • 创建新的 HTML 元素
  • 删除已有的 HTML 元素
  • 改变事件(处理程序)

4. DOM事件


  • 当用户点击鼠标时 onclick onmousedown onmousesetup
  • 当网页已加载时 onload onunload
  • 当图片已加载时 ``
  • 当鼠标移动到元素上时 onmouseover onmouseout
  • 当输入字段被改变时 onchange
  • 当 HTML 表单被提交时
  • 当用户触发按键时
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值