JS笔记

js概念

什么是js

js是一种基于对象和事件驱动的解释性脚本语言.

基于对象: js可以使用自己创建出来的对象

事件驱动: 由事件去触发的

解释性: 编译性来说, 不需要进行编译打包,浏览器可以直接识别

跨平台性: 只要有浏览器就可以识别执行

组成部分:

​ ECMAScript: 语法标准

​ DOM: 文档对象模型

​ BOM: 浏览器对象模型

js可以做什么:

​ \1. 数据请求

​ \2. 动态效果

​ \3. 表单验证

引入方式

行内:

很少

内嵌: script双标签, 从上到下依次执行,遇到script标签去执行其中的代码, 放于任何位置, 推荐放置于body的结束标签之前

<script>
    alert(2); // 阻塞页面
</script>

外链: script双标签, src引入地址, 例子:

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        div{
            width: 200px;
            height: 200px;
            background: red;
        }
    </style>
    <script src="index.js"></script>
</head>

注意: 外链式中不可以写内嵌代码

<script src="index.js">
    alert(4);    
</script>
获取元素的方式

​ document.getElementById(‘id名’)

​ document: 文档

​ get: 获取

​ Element: 元素

​ ById: 通过id

添加事件

元素.事件 = function(){ 要执行的代码 }

// alert(document.getElementById('box'));
console.log(document.getElementById('box'));
document.getElementById('box').onclick = function(){
    alert(1);
    console.log('这是新的内嵌事件');
}
window.onload

等待页面及资源加载完成后在执行其中的代码: window.onload = function(){ }

window.onload = function () {
    // alert(document.getElementById('box'));
    console.log(document.getElementById('box')); // div
    document.getElementById('box').onclick = function () {
        alert(1);
        console.log('这是新的内嵌事件');
    }
}
鼠标事件

​ 元素.事件 = function(){}

​ 单击: onclick

​ 双击: ondblclick

​ 滑入: 鼠标从外部移到元素内部 onmouseover/onmouseenter

​ 移出: onmouseout/onmouseleave

​ 移动: onmousemove

​ 右击: oncontextmenu

document.getElementById('box').ondblclick = function(){
    console.log(1);
}
document.getElementById('box').onmouseover = function(){
    console.log(2);
}
document.getElementById('box').onmouseenter = function(){
    console.log(3);
}
document.getElementById('box').onmouseout = function(){
    console.log(4);
}
document.getElementById('box').onmouseleave = function(){
    console.log(5);
}
document.getElementById('box').onmousemove = function(){
    console.log(666);
}
document.getElementById('box').oncontextmenu = function(){
    console.log(6);
}
box1.onmousedown = function(){
    console.log('按下');
}
box1.onmouseup = function(){
    console.log('抬起');
}
box1.onclick = function(){
    console.log('单击');
}
变量
  1. 声明

    1. 先声明后赋值:

      1. 单个声明: var 变量名; 变量名 = 值;
      2. 多个声明: var 变量名1, 变量名2; 变量名1 = 值1; 变量名2 = 值2;
    2. 声明的同时并赋值

      1. 单个声明: var 变量名 = 值;
      2. 多个声明: var 变量名1 = 值1, 变量名2 = 值2;
      var day;
      day = '星期一';
      console.log(day);
      
      var userName, password;
      userName = '李琦';
      password = 'qwer1234';
      console.log(userName, password);
      
      var day1 = '星期一';
      console.log(day1);
      
      var userName1 = '付娟', password1 = '1234qwer';
      console.log(userName1, password1);
      
  2. 变量的命名规范

    ​ \1. 遵循驼峰命名法, 见名知意; userName password

    ​ \2. 由字母、数字、_、 $组成, 数字不能开头

    ​ \3. 不能使用关键字和保留字

    ​ \4. 不能重复

  3. alert与console的区别

    1. alert会阻塞页面
    2. alert一次只能弹出一个,console.log可以一次性输出多个
  4. 注释

    1. 单行注释: ctrl + / //
    2. 块注释: ctrl + shift + / /* 要注释的代码 */
  5. over 与 enter的区别

    1. 区别: over: 子元素会触发父元素身上的事件 enter: 不会

      // over:2次 enter: 1次
      // 区别: over: 子元素会触发父元素身上的事件  enter: 不会
      var box1 = document.getElementById('box1');
      // box1.onmouseover = function(){
      //     console.log(1);
      // }
      box1.onmouseenter = function(){
          console.log(1);
      }
      
  6. 变量拼接: 一删 二加 三替换

    console.log('今天是' + year + '年' + month + '月' + date + '号');
    
操作元素
  1. 操作表单元素

    • 获取表单的内容: 表单元素.value

    • 设置表单的内容: 表单元素.value = 值;

      <input type="text" value="123456" id="inp">
      <input type="password" id="inp1">
      <input type="button" value="获取密码">
      <textarea name="" id="txt" cols="30" rows="10">
          这是一个文本区域
      </textarea>
      <select name="" id="sel">
          <option value="beijing">北京</option>
          <option value="chengdu">成都</option>
          <option value="shanghai">上海</option>
      </select>
      
      var inp = document.getElementById('inp');
      console.log(inp.value);
      inp.value = '这是新的内容';
      
      var txt = document.getElementById('txt');
      console.log(txt.value);
      txt.value = '这是新的文本域内容';
      
      // 下拉列表
      var sel = document.getElementById('sel');
      console.log(sel.value); // 北京
      // 如果option上没有value属性, 获取设置根据option双标签中的文本进行操作
      // sel.value = '上海';
      // sel.value = '上海 ';
      
      console.log(sel.value); // beijing
      sel.value = '北京';
      sel.value = 'beijing';
      // 如果option上有value属性, 获取设置根据option的value进行操作
      
  2. 事件三部曲

    • 获取元素

    • 添加事件, 鼠标操作的是谁就给谁加

    • 具体的操作

      // 1. 获取元素
      var btn = document.getElementById('btn');
      var inp1 = document.getElementById('inp1');
      console.log(btn, inp1);
      // 2 添加事件
      btn.onclick = function(){
          // 3. 具体的操作
          console.log(inp1.value);
      }
      
  3. 操作闭合标签内容

    1. innerHTML: 获取: 元素.innerHTML 设置: 元素.innerHTML = 值;

      ​ 获取可以获得标签; 设置时会覆盖原标签中的所有内容;设置时可以渲染标签

    2. innerText: 获取: 元素.innerText 设置: 元素.innerText = 值;

      ​ 不能获取到标签; 设置时会覆盖原标签中的所有内容; 设置时不能渲染标签

    var box = document.getElementById('box');
    console.log(box);
    console.log(box.innerText); // 12345 这是一个box
    console.log(box.innerHTML); // <b>12345</b> 这是一个box
    
    // box.innerText = '<b>这是新新新的内容</b>';
    box.innerHTML = '<b>这是新新新的内容</b>';
    
  4. 操作元素属性

    1. 获取: 元素.属性名 元素.id

      ​ 元素[‘属性名’] 元素[‘id’]

    2. 设置: 元素.属性名 = 值; 元素.id = 值;

      ​ 元素[‘属性名’] = 值; 元素[‘id’] = 值;

      var box = document.getElementById('box');
      console.log(box);
      console.log(box.id); // box
      box.id = 'b';
      
      console.log(box['id']);
      box['id'] = 'box';
      
      var n = 'id';
      console.log(box.n, box['n']); // 属性名为n的属性的属性值
      console.log(box[n], box['id']);
      
  5. 操作元素的属性-src

    1. 获取: 元素.属性名 元素.src

    2. 设置: 元素.属性名 = 值; 元素.src = 值;

      var img = document.getElementById('img');
      console.log(img);
      console.log(img.src); // file:///E:/%E4%B8%AD%E5%85%AC%E6%95%99%E8%82%B2/20200511/day01/img/2.jpg 
      // 获取到的是绝对路径
      img.src = 'img/3.jpg';
      
  6. 操作元素的属性-class

    1. 获取: 元素.属性名 元素.src 元素.className

    2. 设置: 元素.属性名 = 值; 元素.src = 值; 元素.className = 值;

      <div id="box" class="a"></div>
      
      div{
          width: 200px;
          height: 200px;
      }
      .a{
          background: red;
      }
      .b{
          background: blue;
      }
      
      var box = document.getElementById('box');
      console.log(box);
      console.log(box.className); // a
      box.className = box.className + ' b';
      
  7. 操作元素的属性-style

    1. 获取:元素.属性名 元素.style 元素.style.属性名

    2. 设置:元素.属性名 = 值; 元素.style.属性名 = 值;

      注意:

      • 只能获取\设置行内样式
      • js中不识别连字符, 转成驼峰命名方式进行操作
      <div id="box" style="color: #f00cff; font-size: 30px;">这是一个div</div>
      
      #box{
          width: 200px;
          height: 200px;
          background:pink;
      }
      
      var box = document.getElementById('box');
      console.log(box);
      console.log(box.style);
      console.log(box.style.color); // rgb(240, 12, 255)
      console.log(box.style.width); // 空
      
      box.style.width = '400px';
      box.style.background = 'orange';
      
      // console.log(box.style.font-size); // js中不识别连字符, 转成驼峰命名方式进行操作
      console.log(box.style.fontSize); // 30px
      box.style.fontSize = '50px';
      
  8. 操作元素样式-cssText

    1. 获取: 元素.style.cssText 行内所有样式

    2. 设置: 元素.style.cssText = 值; 会覆盖行内的所有样式

      <div id="box" style="color: #f00cff; font-size: 30px;">这是一个div</div>
      
        #box{
            width: 200px;
            height: 200px;
            background:pink;
        }
      
      console.log(box.style.cssText); // color: rgb(240, 12, 255); font-size: 30px;
      box.style.cssText = box.style.cssText + 'background: orange;'
      

======================================================================================

day 02

数据类型

数据类型分类
  1. 基础数据类型: number(数字/值类型) string(字符串) boolean(布尔类型) null undefined
  2. 复杂数据类型: object(对象) array(数组) function(函数)
number
  1. 整型: 整数
  2. 浮点型: 小数, 有一位小数点并且后面不为0
  3. 特殊值:
    • 以0为开头,并且后面不超过8的数,表示的是8进制数
    • 0x开头, 表示16进制, 0-9a-f表示0-15
    • e,十的多少次方
    • Infinity–正无穷大 -Infinity-----负无穷大
    • NaN: 当计算错误的时候会出现的结果 Not a Number

NaN的特点:

  1. typeof 结果是number
  2. NaN与任何数值都不相等包括自己
  3. 在计算错误的时候会出现
  4. NaN和任何数值的计算结果都是NaN
检验方式

typeof 要检验的数据

typeof(要检验的数据)

var num = 10;
console.log(num);
console.log(typeof num); // number

var num1 = 0.5;
var num2 = .5;
console.log(num1, num2);
var num3 = 10.0;
console.log(num3);
console.log(typeof num1); // number


var num4 = 070;
var num5 = 019;
console.log(num4);
console.log(num5);
console.log(typeof num4); // number

var num6 = 0xf;
console.log(num6);
console.log(typeof num6); // number


var num7 = 2e10;
console.log(num7);

var num8 = 2e9999999;
console.log(num8);

console.log(1/0); // Infinity
console.log(-1/0); // -Infinity
console.log(typeof num8); // number

console.log(typeof NaN);
console.log(10 - 'a'); // NaN

var a = 10;
console.log(a == num3); // true

var n = NaN;
var m = NaN;
console.log(n == m); // false

console.log(1 - NaN);
字符串 string
  1. 概念: 字符串, 被成对的单双引号包裹的就是字符串

  2. 变量.length: 获取到字符串的长度

  3. 获取指定下标的字符: 变量.charAt(下标) ie8以上: 变量[下标]

    var str = 'qwertyu12345';
    console.log(typeof str); // string
    
    var str1 = "12345";
    console.log(typeof str1); // string
    
    var str2 = '中国天气网讯 中央气象台6月9日06时继续发布暴雨黄色预警:预计,6月9日08时至10日08时,广东中部、广西中北部、云南东南部、湖南东部和南部、湖北东南部、江西大部、福建东部、安徽南部以及河南中部等地的部分地区有大到暴雨,其中,广东北部等地局地有大暴雨(100~160毫米)。上述部分地区伴有短时强降水(最大小时降雨量30~50毫米,局地可超过70毫米),局地有雷暴大风等强对流天气。';
    // 变量.length: 获取到字符串的长度
    console.log(str2.length); // 193
    // 下标: 从左开始, 以0为开头
    // 获取指定下标的字符: 变量.charAt(下标)
    // ie8以上: 变量[下标]
    console.log(str2.charAt(19));
    console.log(str2[19]);
    
boolean: 布尔值,
  1. boolean: 布尔值, true false

  2. 用于判断条件的结果或者是判断的条件

    var t = true;
    console.log(typeof t); // boolean
    console.log(typeof false);
    
    console.log(10 == 10); // true
    console.log(NaN == NaN); // false
    
    if(true){
        alert(1);
    }
    
null和undefined
  1. null: 只有一个值, 就是自身, typeof以后结果是object

  2. undefined: 只有一个值, 就是自身

  3. null和undefined的区别:

    null本身就是空, undefined表示未初始化, 声明未赋值。

    var n = null;
    var m = undefined;
    console.log(n, m);
    console.log(typeof null); // object
    console.log(typeof undefined); // undefined
    
    var a;
    console.log(a); // undefined
    
object
  1. 一切皆对象:

    console.log(window);
    console.log(document);
    console.log(typeof window); // object
    console.log(typeof document); // object
    var box = document.getElementById('box');
    console.log(typeof box); // object
    
  2. object: var 变量名 = {};

    var obj = {}; // 空对象
    console.log(obj);
    
  3. json数据的格式, 键值一一相对的键值对

    var obj1 = {
        'name': '付双钰',
        'height': 180
    };
    
  4. 获取对应属性名的属性值: 变量.属性名

    console.log(obj1);
    console.log(obj1.name);
    console.log(obj1.height);
    console.log(obj1['name']);
    
Array
  1. 数组, 有序排列的值得集合, 用于存放不定数量不定类型的数据, 是一个存放数据的容器

  2. 创建: var 变量名 = [];

    // 空数组
    var arr = [];
    console.log(arr);
    console.log(typeof arr); // object
    
    // 非空数组
    var box = document.getElementById('box');
    var arr = [1, 2, 'abc', true, null, undefined, box, document, window];
    console.log(arr);
    
  3. 获取数组的长度: length

  4. 获取指定下标的值: 变量[下标]

  5. // 获取数组的长度: length
    console.log(arr.length);
    // 获取指定下标的值: 变量[下标]
    console.log(arr[0]);
    
Function
  1. function: 函数 用来存放一段代码在有需要的时候调用

  2. 使用: 1. 声明函数: function 函数名() { // 代码块 } 2. 调用函数: 函数名();

    function sum(){
        console.log(20 + 30);
    }
    sum();
    sum();
    sum();
    sum();
    sum();
    
    console.log(typeof sum); // function
    
typeof
  1. typeof检验返回值: number string boolean undefined object function
  2. 数据分类:
    1. 基础数据类型,数据类型比较单一化, 复杂数据类型数据类型比较多样化
    2. 基础数据类型存储数据容量较小, 复杂数据类型存储数据容量较大
强制转换
  1. Number(要转换的数据): 将数据转换成number类型, 可转换: 空字符、空格字符、纯数字字符串、 布尔、null\空数组\数组中有一项并且为数字字符串

    var str = ''; // 空字符串
    console.log(typeof str);
    console.log(Number(str)); // 0
    console.log(Number('  ')); // 0
    console.log(Number('abc')); // NaN
    console.log(Number('1234')); // 1234
    console.log(Number('12.5')); // 12.5
    console.log(Number('12a')); // NaN
    
    console.log(Number(true)); // 1
    console.log(Number(false)); // 0
    
    console.log(Number(undefined)); // NaN
    console.log(Number(null)); // 0
    
    console.log(Number({})); // NaN
    console.log(Number([]));  // 0
    console.log(Number(['a'])); // NaN
    console.log(Number(['123'])); // 123
    console.log(Number([null])); // 0
    console.log(Number(['123', '1234'])); // NaN
    function sum(){}
    console.log(Number(sum)); // NaN
    
  2. parseInt(要转换的数据, [进制]) []中表示可选参数

    将数据转换成number, 整型数据, 从左往右依次转换, 遇到不能转换的就结束.如果第一个就不能转换就返回NaN

    console.log(parseInt('12')); // 12
    console.log(parseInt('12.5')); // 12
    console.log(parseInt('12px')); // 12
    console.log(parseInt('a12')); // NaN
    
    // 进制: 2-32进制
    console.log(parseInt('70'));
    console.log(parseInt('070', 10));
    
  3. parseFloat(要转换的数据), 可以保留一个小数点, 从左往右依次转换, 遇到不能转换的就结束.如果第一个就不能转换就返回NaN

    console.log(parseFloat('12.5')); // 12.5
    console.log(parseFloat('12.5.5.5')); // 12.5
    console.log(parseFloat('12.534356')); // 12.534356
    console.log(parseFloat('a12.5')); // NaN
    
  4. isNaN(要判断的数据): 判断一个数据 是不是 不是一个数字

    不是数字返回true

    是数字就返回false

    console.log(isNaN('12.5')); // false
    console.log(isNaN('12.5a')); // true
    console.log(isNaN('')); // false
    console.log(isNaN(' ')); // false
    console.log(isNaN({})); // true
    
  5. 注意事项: 由于计算机的精度问题,小数计算会出问题, 所以尽量避免使用

    console.log(0.1 + 0.2); // 0.30000000000000004

string
  1. String(要转换的数据): 将其他数据类型转换成string类型

    console.log(String(12.5));
    console.log(typeof String(12.5)); // string
    console.log(String(NaN)); // NaN
    console.log(String(Infinity)); // Infinity
    console.log(String(2e10)); // 20000000000
    console.log(String(true)); // 'true'
    console.log(String(false)); // false
    console.log(String(null));
    console.log(String(undefined));
    
    var obj = {};
    console.log(String(obj)); // [object Object]
    var arr = [];
    console.log(String(arr)); // 空字符串
    var arr1 = [1,2,3];
    console.log(String(arr1)); // '1,2,3'
    function sum(){}
    console.log(String(sum)); // function sum(){}
    console.log(typeof String(sum)); // string
    
  2. 要转换的数据.toString(进制): 将其他数据类型转换成string类型

    2-32进制, 表示将要转换的数值转成多少进制的字符串

    var num = 10;
    var t = true;
    var n = null;
    var u = undefined;
    console.log(num.toString());
    console.log(num.toString(2)); // 1010
    console.log(num.toString(16)); // a
    
    console.log(t.toString());
    // console.log(n.toString());
    
  3. 区别:String可以转换null和undefined 而toString不能

    toString: 由对象提供的转换方法

    String: 强制转换

boolean
  1. Boolean(要转换的数据); true false

  2. js中的假: 0 NaN 空字符串 null undefined false

    js中的真: 除以上,其他都是真的

    console.log(Boolean(0)); // false
    console.log(Boolean(10)); // true
    console.log(Boolean(NaN)); // false
    
    console.log(Boolean('')); // false
    console.log(Boolean(' ')); // true
    console.log(Boolean('aa')); // true
    
    console.log(Boolean(null)); // false
    console.log(Boolean(undefined)); // false
    
    var obj = {};
    console.log(Boolean(obj));
    
    var arr = [];
    console.log(Boolean(arr));
    
    function sum(){}
    console.log(Boolean(sum));
    

=============================================================================

day 03

运算符

算术运算符
  1. 算术运算符: + - * / % ++ –

  2. ++ 可以放在变量的前面也可以放在变量的后面

  3. 注意:++在后, 先输出或者是运算,再自加, ++在前, 先自加,再输出或运算

    console.log(10 + 10); // 20
    console.log(10 - 1); // 9
    console.log(10 * 10); // 100
    console.log(10 / 10); // 1
    console.log(10 % 3); // 1
    console.log(10 % 1); // 0
    
    // ++ 可以放在变量的前面也可以放在变量的后面
    var n = 10;
    // n++;
    ++n;
    // n = n + 1;
    console.log(n);
    
    // ++在前或后的区别, ++在后, 先输出或者是运算,再自加
    var m = 10;
    console.log(m++); // 10
    
    // console.log(m); // 10
    // m = m + 1;
    // console.log(m); // 11
    
    var s = 10;
    var mn = s++;
    console.log(mn);
    
    // mn = s; // 10
    // s = s + 1;
    
    var m = 30;
    n = m++; // 
    
    // n = m;
    // m = m + 1;
    
    // ++在前, 先自加,再输出或运算
    var a = 10;
    console.log(++a); // 11
    
    // a = a + 1;
    // console.log(a); // 11
    
    var sn = 10;
    m = ++sn;
    console.log(m); // 11
    
    // sn = sn + 1;
    // m = sn;
    
  4. –在前, 先运算后输出或赋值; --在后,先赋值或输出后运算

    var o = 10;
    console.log(o--); // 10
    
    console.log(o); // 9
    
    console.log(--o); // 8
    
赋值运算符
  1. 赋值运算符: = += -= *= /= %=

    var n = 10;
    
    n += 10;
    
    // n = n + 10;
    console.log(n); // 20
    
    n -= 10;
    // n = n - 10;
    console.log( 10);
    
    var n = 1;
    n *= 10;
    console.log(n); // 10
    
    var m = 10;
    m /= 2;
    console.log(m); // 5
    
    var mn = 10;
    mn %= 3;
    // mn = mn % 3;
    console.log(mn); // 1
    
比较运算符
  1. 比较运算符: > < >= <= ==(相等) =(恒等) !=(不等) !(恒不等)

  2. 比较结果为真返回true, 比较结果为假返回false

    console.log(10 > 3); // true
    console.log(NaN < 3); // false
    console.log(10 >= 10); // true
    console.log(10 <= 10); // true
    
  3. 字符串比较的规则: 从左往右依次比较每一位的ASCII码值, 如果有一位比较出来大小,就结束比较

    ASCII码值 0-48 a-97 A-65

    console.log('a' < 'b'); // true 97 < 98
    console.log('a' < 1); // false 97 < 49
    console.log('aa' < 'ab'); // true
    console.log('a' < 'ab'); // true 0
    console.log('12' < '1000000'); // false 
    
  4. 双等:只比较值,不比较数据类型 三等: 既比较值,也比较数据类型

    console.log('1' == 1); // true
    console.log('1' === 1); // false
    
  5. 不等: 只比较值,不比较数据类型 恒不等: 既比较值,也比较数据类型

    console.log('1' != 1); // false
    console.log('1' !== 1); // true
    
逻辑运算符
  1. 逻辑运算符: &&(与) ||(或) !(非、取反)

    • && : 左右各有一个条件,当左右条件均为真的时候,返回true, 有一个为假返回false。全真为真 一假为假

      var x = 2;
      console.log(1 < x && x < 3); // true && true  true
      x = 3;
      console.log(1 < x && x < 3); // true && false false
      console.log(1 < x && x == 3 && x < 9); // true && true && true
      console.log(1 < x && x == 3 && x > 9); // true && true && false
      
    • ||或: 左右各有一个条件,当有一个条件为真时,就为true, 当所有条件都为假,才是假. 一真为真,全假为假

      console.log(1 < x || x < 3); // true || false  true
      console.log(1 < x || x <= 3); // true || true  true
      console.log(1 > x || x < 3); // false || false false
      console.log(1 < x || x == 3 || x < 9); // true || ture || true true
      console.log(1 > x || x < 3 || x > 9); // false || false || false
      
      var m = 10, n = 3;
      console.log(m < 1 || n > 1 && n < 4); // false || true---true && true true
      console.log(m < 1 || ( n > 1 && n < 4)); // false || (true && true) -- true true
      
    • 取反: ! 返回值: true\false js中的假: 0 NaN null undefined ‘’ false-- 取反返回–> true

      console.log(!true); // false
      console.log(!''); // true
      console.log(!(1-'a')); // !NaN true
      
三目运算符:
  1. 语法: 条件 ? 条件成立的时候执行的代码 : 条件不成立的时候所执行的代码;

  2. 注意: 代码只能写一行,中间不能加分号分隔

    var x = 1;
    x >= 1 ? alert('这是1') : alert('这不是1');
    
隐式转换
规则
  1. 数值之间进行计算的, 进行数学计算

  2. 加法中, 当有一方是字符串的时候, 将另一方转成字符串后再进行拼接

  3. 遇到对象或者复杂数据类型, 调用对象自身的toString方法,转成字符串之后再进行对应的操作

  4. 除加法以外的其他运算尽可能的转成数值后在进行计算(Number)

  5. 加法中, 除字符串以外的类型进行计算的时候尽可能的转成数值后在计算

    // +:
    console.log(10 + 'a'); // 10a
    console.log(null + 'a'); // nulla
    console.log(undefined + 'a'); // undefineda
    console.log(true + 'a'); // truea
    console.log({} + 'a'); // [object Object]a
    console.log([] + 'a'); // a
    console.log([1,2,3] + 'a'); // 1,2,3 + 'a' ===> 1,2,3a
    
    // -:
    console.log(10 - 1); // 9
    console.log(10 - 'a'); // 10 - NaN  NaN
    console.log(10 - ''); // 10 - 0 10
    console.log(10 - '12'); // -2
    console.log(10 - true); // 9
    console.log(10 - false); // 10
    console.log(10 - {}); // NaN 10 - NaN 
    console.log(10 - ['12']); // 10 - 12 -2
    console.log(null - undefined); // 0 - NaN NaN
    console.log(true - false); // 1
    
    // *:
    console.log(10 * null); // 10 * 0 0
    console.log('a' * true); // NaN * 1
    console.log({} * []); // NaN
    
    // /:
    console.log(10 / false); // 10 / 0 Infinity
    console.log(true / undefined); // 1 / NaN
    console.log([] / 'a'); // NaN 
    
    // +其他数据类型: 
    console.log(true + false); // 1
    console.log({} + []); // [object Object]
    console.log(null + undefined); // NaN
    
    var n = 'a'; 
    n++;
    console.log(n); // NaN
    
    var m = true;
    m++;
    console.log(m); // 2
    
    console.log('a' < 'b'); // true 97 
    console.log('a' < 1); // false
    console.log('a' > 1); // false
    console.log(true < false); // false 1 < 0
    
    console.log('a' == 'b'); // false
    console.log('a' == 1); // false
    console.log('a' != 1); // true
    console.log({} == []); // false
    console.log(null == undefined); // js中规定null和undefined是相等的
    console.log(null === undefined);
    
流程控制语句
  1. 流程控制语句:控制代码按照固定的流程顺序执行
  2. 分类:
    • 顺序结构: 从上到下的代码的执行顺序
    • 条件结构(分支语句): 根据不同的条件进行不同的代码的执行, if\if else\switch
    • 循环语句: 让代码块执行固定的循环次数, for\while\do while
    • 其他语句: break\continue
条件结构
if

语法:

if(条件){

​ 条件为真时,所执行的代码

​ }

if(false){
    alert(1);
}

// if('a' < 'b'){ // 97 < 98
//     alert(2);
// }
if else

语法:

​ if(条件){

​ 条件为真时,所执行的代码

​ } else {

​ 条件为假时, 所执行的代码

​ }

var age = 19;
if(age == 18){
    alert('小姑娘');
} else {
    alert('老阿姨');
}
if else if

​ if(条件一){

​ 条件一为真的时候要执行的代码

​ } else if(条件二){

​ 条件二为真的时候要执行的代码

​ } else {

​ 以上条件均不满足的时候要执行的代码

​ }

// 90分以上弹出优秀,80以上弹出良好,70以上弹出及格,其余不及格

// 有一个成绩
// core大于等于90  
// core大于等于80 与 小于90
// core大于等于70 与 小于80
// 小于70 else
var core = 66;
if(core >= 90){
    alert('优秀');
} else if(core >= 80 && core < 90){
    alert('良好');
} else if(core >= 70 && core < 80){
    alert('及格');
} else {
    alert('不及格');
}
if简写

if后面没有{}, 只能控制其后的一行代码

if(条件) 要执行的代码

var m = 10;
if(m > 10){
    alert(6);
    alert(7);
}

if(m > 10) alert(8); 
alert(9);
switch

​ switch(要判断的条件){

​ case 结果1:

​ 当符合结果1时, 要执行的代码;

​ break;

​ case 结果2:

​ 当符合结果2时, 要执行的代码;

​ break;

​ case 结果3:

​ 当符合结果3时, 要执行的代码;

​ break;

​ default:

​ 以上结果都不满足的时候, 要执行的代码;

​ break;

​ }

var a = 10;
var b = 20;
var s = '%';
// 判断s
switch(s){
    case '+': 
        console.log(a + b);
        break;
    case '-':
        console.log(a - b);
        break;
    case '*':
        console.log(a * b);
        break;
    default: 
        console.log('运算符错误');
        break;
}
break

break: 防止穿透

switch执行的时候,如果匹配到一个结果,那么后面的结果都不再匹配而是直接执行其中的代码,所以需要加上break防止穿透

==============================================================================

day 04

获取元素

通过标签名获取

document.getElementsByTagName(‘标签名’);
父元素.getElementsByTagName(‘标签名’);

var lis = document.getElementsByTagName('li');
console.log(lis); // HTMLCollection
console.log(lis.length); // 6
console.log(lis[3]); // <li>004</li>
lis[3].onclick = function(){
    lis[3].style.background = 'red';
}

var ul = document.getElementsByTagName('ul')[0];
console.log(ul);
var lis1 = ul.getElementsByTagName('li');
console.log(lis1);
通过类名获取

document.getElementsByClassName(‘标签名’);
父元素.getElementsByClassName(‘标签名’);

var as = document.getElementsByClassName('a');
console.log(as); // 集合 HTMLCollection(2) [li.a, li.a]
console.log(as[0]);

var ula = ul.getElementsByClassName('a');
console.log(ula); // 一个a类名元素的集合 HTMLCollection [li.a]
console.log(ula[0]);
各种获取方式的区别

​ id:

​ 1. 具体的某一个元素

​ 2. 直接去使用和操作

​ 3. 只能通过document获取

​ 4. 静态: 在获取的时候存在就是存在, 不存在就是不存在; 先获取后添加拿不到

​ tagName\className:

​ 1. 集合

​ 2. 需要通过下标获取到具体的元素之后在使用和操作

​ 3. 既可以是document也可以是父元素

​ 4. 动态性:获取的时候没有, 后面添加的, 后续也能拿得到; 先获取后添加也能拿得到

​ 5. className只支持ie8以上

var a123 = document.getElementById('a123');
var lis = document.getElementsByTagName('li');
console.log(a123, lis);

var box = document.getElementById('box');
console.log(box); // null

var ul = document.getElementsByTagName('ul')[0];
console.log(ul);
ul.innerHTML = ul.innerHTML + '<li id="box">1234</li>';
console.log(box);
console.log(lis);
for

​ for(初始化变量; 循环结束的条件; 变量更新){

​ // 代码块

​ }

// 1-10之间的每个数字都输出
for(var i = 1; i <= 10; i++){
    console.log(i);
}
for循环执行的过程

​ 1. 初始化变量: var i = 1;

​ 2. 判断循环结束的条件: i <= 10

​ 3. 循环体代码块: console.log(i)

​ 4. 变量更新: i++

​ 2.3.4.2.3.4.2

断点调试

Sources —> 找到要断点调试的文件 —> 点击需调试的行数

for in
  1. 用途:遍历对象

  2. 语法:

    for(var i in 对象){

    ​ i—>键, 属性名

    ​ 对象[i] — > 值, 属性值

    }

    var obj = {
        'name': '彭于晏',
        'height': 180,
        'age': 18
    };
    console.log(obj.name);
    console.log(obj['name']);
    var n = 'name';
    console.log(obj[n]);
    
    for(var i in obj){
        console.log(i);
        console.log(obj[i]);
    }
    
for和for in注意

但凡有长度的都可以使用for循环遍历

for in一次性拿到所有的对象中的属性名和属性值,不会单独获取

所有for、forin循环在一瞬间执行完成

for循环变种

语法:

​ var i = 0;

​ for(;循环结束的条件;){

​ // 循环体

​ // 变量更新

​ }

var i = 0;
for(;i <= 10;){
    console.log(i);
    i++;
}
while

语法:

初始化变量: var i = 0;

​ while(循环结束的条件){

​ // 循环体

​ // 变量更新

}

var s = 0;
while(s<=10){
    console.log(s);
    s++;
}
while和for的区别

​ for循环能做的while也能做, while能做的for循环也可以

​ for: 循环次数明确的时候

​ while: 循环次数不明确的时候

do while

语法:

​ 1. 初始化: var i = 0;

​ do{

​ 2. 循环体

​ 3. 变量更新

​ }while(4. 循环结束的条件)

​ 执行顺序: 1234234234234

// var i = 0;
// do{
//     console.log(i);
//     i++;
// }while(i <= 3);
while和dowhile的区别

while循环在第一次条件就不符的时候, 不会执行循环体

var i = 10;
while(i < 10){
    console.log(i);
    i++;
}

dowhile循环在第一次条件就不符的时候, 会执行一次循环体

var s = 10;
do{
    console.log(s);
    s++;
}while(s < 10);
其他语句
break
  1. break: 防止穿透; 终止循环; break后面的代码都不执行;

    for(var i = 0; i < 10; i++){
        console.log(i);
        if(i == 5){
            break;
        }
    }
    
continue
  1. continue: 结束本次循环, continue后面的代码不再执行

    for(var i = 0; i < 10; i++){
        console.log(i);
        if(i == 5){
            continue;
        }
    }
    
this
对this的理解

this: 存在于页面的任何位置, 要么在函数中,要么在函数外

​ 全局中this指向window

​ 普通函数: window

​ 事件处理函数: 事件触发谁就是谁, 触发源—点谁就是谁

function sum(){
    console.log(this); // window
    console.log(10 +20);
}
sum();
console.log(window);
window.sum();
console.log(this); // window

var div = document.getElementsByTagName('div')[0];
div.onclick = function(){
    // alert(1);
    console.log(this); // <div>1234</div>
}
this的用途

在for循环的添加的事件中找到对应的触发元素

<ul>
    <li>001</li>
    <li>002</li>
    <li>003</li>
    <li>004</li>
    <li>005</li>
</ul>
// 点击每一个li都弹出提示
var lis = document.getElementsByTagName('li');
console.log(lis); // 集合 类数组 有长度有下标

for(var i = 0; i < lis.length; i++){
    // 获取到每一个li元素
    // console.log(i); // 下标
    // console.log(lis[i]); // 对应下标的元素
    lis[i].onclick = function(){
        // alert('弹出');
        console.log(i);
        console.log(lis[i]);
        console.log(this);
        this.style.background = 'red';
        // lis[i].style.background = 'red';
    }
}

==========================================================================

day 05

this

设置自定义属性
  1. 当自定义属性直接写在元素身上的时候, 无法获取

  2. 通过js的方式设置给元素一个自定义属性,元素身上看不到,但是可以获取和操作

    <img src="./img/dark.jpg" alt="" class="a" tag="1">
    <img src="./img/dark.jpg" alt="" class="a">
    <img src="./img/dark.jpg" alt="" class="a">
    <img src="./img/dark.jpg" alt="" class="a">
    
    var flag = 1; // 假设创造了一个开关,1的时候是关灯,2的时候是开灯
    var img = document.getElementsByTagName('img');
    for (var i = 0; i < img.length; i++) {
        img[i].onclick = function () {
            console.log(this.className);
            console.log(this.tag); // undefined 当自定义属性直接写在元素身上的时候, 无法获取
            this.tag1 = 1; // 给元素设置自定义属性tag1
            console.log(this.tag1); // 1
        }
    }
    
this的用法
  1. for循环添加的事件中找到对应触发元素

  2. 在for循环中给每个元素添加自定义属性, 元素集合[下标].属性名 = 属性值; 事件中: this.属性名的方式去获取和操作

    var img = document.getElementsByTagName('img');
    for (var i = 0; i < img.length; i++) {
        img[i].flag = 1; // 给每一个img添加自己的开关flag
        img[i].onclick = function () {
            console.log(this.flag);
            if (this.flag == 1) {
                // 关灯状态 ---- > 开灯状态
                this.flag = 2;
                this.src = './img/bright.jpg';
            } else {
                // 开灯状态-----> 关灯状态
                this.flag = 1;
                this.src = './img/dark.jpg';
            }
        }
    }
    
  3. 自定义索引: 自定义一个属性,存储元素对应的下标, 一般自定义下标用index

    <button>黄色</button>
    <button>粉色</button>
    <button>绿色</button>
    
    // 点击对应的按钮,将网页背景颜色改为对应的颜色
    // 获取元素
    var btns = document.getElementsByTagName('button');
    // 声明一个数组存储颜色
    var arr = ['yellow', 'pink', 'green'];
    // 给每一个按钮添加点击事件
    for(var i = 0; i < btns.length; i++){
        // 自定义一个属性,存储元素对应的下标, 一般自定义下标用index
        console.log(i);
        btns[i].index = i; // 自定义下标
        btns[i].onclick = function(){
            // 获取到对应按钮的下标
            console.log(i);
            console.log(this.index);
            // 获取对应的颜色, 从数组中获取对应的值
            console.log(arr[this.index]);
            // 改变页面背景颜色
            // document.getElementsByTagName('body')[0]
            document.body.style.background = arr[this.index];
    
            // 排他思维: 先将所有的按钮的背景色都去掉, 然后再给对应的按钮加上背景色
            for(var j = 0; j < btns.length; j++){
                this.style.background = 'transparent';
                this.style.color = '#000';
            }
    
            // 更新对应按钮的背景色
            this.style.background = '#000';
            this.style.color = '#fff';
        }
    }
    
  4. 排他思维: 先将所有的按钮的背景色都去掉, 然后再给对应的按钮加上背景色

函数

  1. 概念: 用来保存一段代码在有需要的时候被调用, 函数都是事件驱动的或者是被调用的

    函数声明
    1. 函数声明

      ​ \1. 函数声明: function 函数名(){ // 代码块 }

      ​ \2. 调用函数: 函数名();

      sum();
      
      function sum(){
          console.log(20 + 30);
      }
      
    2. 表达式声明

      ​ \1. 表达式声明: var 函数名 = function(){ // 代码块 }

      ​ \2. 调用函数: 函数名();

      var sum1 = function(){
          console.log(20 + 30);
      }
      sum1();
      
    3. 两种声明方式的区别

      函数声明的函数在声明前后调用都可以, 表达式声明的函数只能在声明后面调用

函数使用
  1. 封装(有目的性): 写一个函数用来完成某个功能

    function sum(){
        var s = 0;
        for(var i = 1; i <= 100; i++){
            s += i;
        }
        console.log(s);
    }
    sum();
    
  2. 事件处理函数: 元素.事件 = function(){} function就是事件处理函数

    var div = document.getElementsByTagName('div')[0];
    div.onclick = function(){
        alert(div.innerText);
    }
    
  3. 对象的方法: tip冒号后面的function就叫做方法

    var obj = {
        'name': '张三',
        'age': 18,
        'tip': function(){
            console.log('我会挣钱');
        }
    }
    console.log(obj.tip);
    obj.tip(); // 通过对象的方法名调用函数
    
  4. 复用

    复用步骤:

    • 创建一个空函数
    • 重复的代码放入
    • 在原有代码位置上调用一次, 调试
    • 抽取参数
    • 再次传参调试调用
right1.onclick = function () {
    move();
}

left1.onclick = function(){
    n -= 2;
    move();
}

function move(){
    n++;
    if(n < 0){
        n = 3;
    }
    if(n > 3){
        n = 0;
    }
    img.src = arr[n].src;
    tit1.innerHTML = arr[n].des;
    tit2.innerHTML = arr[n].tit;
}
函数的参数
  1. 形参: 形式参数, 用来占位的一个参数, 函数声明时函数后面的()里

  2. 实参: 实际的参数, 具体的数据传递给形参, 函数调用时的()里

    注意: 形参和实参是一一对应, 多个形参和实参之间, 用逗号分隔

    function sum(){
        console.log(10 + 30);
    }
    sum();
    
    // 单个参数
    function sum1(num){ // 形参---类似变量
        console.log(num);
        console.log(10 + num);
    }
    sum1(30);
    sum1(300);
    
    // 多个参数
    function sum2(a, b){
        console.log(a + b);
    }
    sum2(20, 30);
    sum2(33, 21);
    
  3. arguments: 实参的集合, arguments和形参是同一个, 存在于任何一个函数中

    // 不定个数的参数
    function sum3(){
        console.log(arguments);
        // console.log(arguments[0]);
        // 将arguments中的每一个值相加
        var s = 0;
        for(var i = 0; i < arguments.length; i++){
            s += arguments[i];
        }
        console.log(s);
    }
    sum3(20);
    sum3(20,70,90,40);
    sum3(20,70,90,40,44,32);
    
参数的数据类型

所有的数据类型都可以作为参数传递

可以作为参数的数据类型:number\string\boolean\null\undefined\object\array\function

function len(str){
    console.log(str.length);
}
len('1234werq');

function bool(bl){
    if(bl){
        // alert(1);
    } else {
        alert(2);
    }
}
bool(true);

function getA(obj){
    console.log(obj);
}
getA(null);
getA(undefined);

var obj = {
    'name':'张三',
    'tip': function(){
        console.log('会挣钱');
    }
}
function tips(object){
    console.log(object); // {tip: ƒ}
    object.tip();
    console.log(object.name);
}
tips(obj);

var arr = [1,2,3,4];
function getArray(array){
    for(var i = 0; i < array.length; i++){
        console.log(array[i]);
    }
}
getArray(arr);
getArray(['a', 'b', 'c']);

function getAlert(){
    alert(1);
}
function getFun(fn){
    console.log(fn);
    fn();
}
getFun(getAlert); // 不加(), 将整个函数传递进去; 加了()表示调用
函数中的问题
  1. 函数的命名规范与变量的命名规范一致

  2. 参数个数不相等时候:

    • 形参个数多余实参个数, 多余的形参被赋值成undefined
    • 实参个数多余形参个数, 多余的实参无法通过形参获取
  3. 函数名重复的时候(函数和函数的名字, 同一种声明方式时), 后面的覆盖前面

    function a1(a,b,c){
        console.log(a, b, c);
        console.log(arguments);
    }
    a1(1,2);
    
    a1(1,2,3,4);
    
    function c1(){
        console.log(1);
    }
    function c1(){
        console.log(2);
    }
    c1();
    
作用域
  1. 概念: 变量和函数作用的区域, 在这个区域中,变量和函数可以被读\写

  2. 作用: 读、写

  3. 作用域由函数来进行划分, function内部: 局部作用域 script 双标签: 全局作用域

  4. 在全局作用域中用var和function声明的变量和函数, 可以在任何作用域中被读写, 全局变量、全局函数

  5. 在局部作用域中用var和function声明的变量和函数, 只能在局部作用域以内的区域被读写, 出了{}就会被销毁, 局部变量、局部函数

    var n = 10;
    function a(){
        console.log(n);
        console.log(1);
    }
    a();
    
    function b(){
        var c = 10;
        console.log(c); // 10
    }
    b();
    console.log(c); // 报错
    
  6. 作用域链: 由于作用域的嵌套, 查找变量和函数的时候, 会形成向上的查找机制。 是js中的一种查找机制, 由内而外的向上查找

    var n = 10;
    
    function s(){
        var m = 10; // 局部变量
        function mn(){ // 局部函数
            console.log(m); // 36 10
            console.log(n); // 21  10
        }
        mn(); // 38-39
    }
    s();
    
预解析
  1. js解析器解析代码的过程(假设有这个名字):

    1. 找东西: 找var和function, 将var声明的变量提到最前声明(var 变量名), 将function声明的函数整个存储在内存中

    2. 逐行解析

      // console.log(a);
      // function s(){
      //     console.log(a);
      // }
      // var a = 10;
      // s();
      
      // -----解析过程-----
      var a;
      function s(){
          console.log(a);
      }
      console.log(a); // 25a undefined
      a = 10;
      s(); // 27 -- 30a --- 10
      

=========================================================================

day 06

函数

函数的返回值
  1. 为了将函数内的某些数据释放到函数外
  2. 所有的函数都有返回值, 如果没有设置返回值, 会返回undefined
  3. 设置返回值: return 值;
  4. return:
    1. 结束代码, return后面的代码都不在执行
    2. 给函数设置返回值
  5. 多个返回值要返回用对象来返回
// 求和函数 30-50
function sum(){
    var s = 0;
    for(var i = 30; i < 51; i++){
        s += i;
    }
    console.log(s);
    console.log(i);
    // return s, i;
    // return i;
    return {
        's': s,
        'i': i
    };
}
var m = sum();
console.log(m); // undefined --设置返回值--> 840 --返回多个--> {s: 840, i: 51}
console.log(m.s);
获取非行间样式
  1. 标准: getComputedStyle(元素).属性名

  2. ie678: 元素.currentStyle.属性名

    console.log(getComputedStyle(div).width);
    console.log(window.getComputedStyle);
    console.log(div.currentStyle.width);
    
  3. 兼容解决: 一个是方法,一个是属性, 用方法是否存在来判断

    if (window.getComputedStyle) {
        // 标准浏览器
        console.log(getComputedStyle(div).width);
    } else {
        // ie浏览器
        console.log(div.currentStyle.width);
    }
    
  4. 封装兼容函数

    var w = getStyle(div, 'width');
    var h = getStyle(div, 'height');
    console.log(w, h);
    
    // 封装
    function getStyle(elem, attr) {
        // elem: element 元素
        // attr: attribute 属性
        if (window.getComputedStyle) {
            // 标准浏览器
            return getComputedStyle(elem)[attr];
        } else {
            // ie浏览器
            return elem.currentStyle[attr];
        }
    }
    

    定时器

    setTimeout

    setTimeout: 延迟定时器, 隔一段时间之后执行一次, 广告\ 提示\关不掉弹框

    setTimeout(函数, 时间); 单位: ms 1s = 1000ms

    setTimeout(function(){
        alert(1);
    }, 3000);
    
    // 隔3秒后, 让图片显示出来
    var img = document.getElementsByTagName('img')[0];
    function move(){
        console.log(this);
        img.style.display = 'block';
    }
    setTimeout(move, 3000);
    

    ====================================================================================

day 07

定时器

setTimeout

setTimeout: 延迟定时器, 隔一段时间之后执行一次, 广告\ 提示\关不掉弹框

setTimeout(函数, 时间); 单位: ms 1s = 1000ms

setTimeout(function(){
    alert(1);
}, 3000);

// 隔3秒后, 让图片显示出来
var img = document.getElementsByTagName('img')[0];
function move(){
    console.log(this);
    img.style.display = 'block';
}
setTimeout(move, 3000);
setInterval

setInterval: 间隔定时器, 每隔一段时间就执行一次, 计时器\倒计时\轮播图

setInterval(函数, 时间); 时间: ms

// setInterval(函数, 时间); 时间: ms
var img = document.getElementsByTagName('img')[0];
var n = 1;
// 每隔两秒钟换一张图片
setInterval(function(){
    // 更新n
    n++;
    if(n == 5){
        n = 1;
    }
    img.src = './img/' + n + '.jpg';
}, 2000);
clear

页面开启定时器的时候, 定时器会返回一个唯一标识(数字), 可以用来清除定时器

因为定时器一旦开启,不会自动关闭

​ clearTimeout(timerId)

​ clearInterval(timerId)

var t = 10;
// 每隔一秒输出当前倒计时的时间
console.log(t);
var timer = setInterval(function () {
    t--;
    if (t <= 0) {
        t = 0;
        clearInterval(timer);
    }
    console.log(t);
}, 1000);
console.log(timer);

Math

console.log(Math);
console.log(2e2);
console.log(Math.PI);

console.log(Math.ceil(4.00000000001)); // 向上取整
console.log(Math.floor(4.999999999999999)); // 向下取整
console.log(Math.round(4.499999999999)); // 四舍五入
console.log(Math.round(4.50)); // 四舍五入

console.log(Math.abs(-10)); // 取绝对值
console.log(Math.sqrt(9)); // 开根号
console.log(Math.sqrt(2)); // 开根号
console.log(Math.pow(2, 10)); // Math.pow(底数, 几次方);  幂次方

console.log(Math.max(20,3,1,23,12,34)); // 求一组数之间的最大值
console.log(Math.min(20,3,1,23,12,34)); // 求一组数之间的最小值

// 求随机数 Math.random() * 数
/* 
    0-1: Math.random()
    0-数: Math.random() * 数  求0到数之间的随机数
    20-30: Math.random() * (最大值 - 最小值 + 1) + 最小值
*/
console.log(Math.random());
console.log(Math.random() * 66);

=============================================================================

day 08

时间对象 Date

创建时间对象

创建时间对象: var date = new Date();

获取特定格式的时间
var date = new Date();
console.log(date); // 对象
console.log(typeof date);
// 转成特定格式的时间
console.log(date.toString()); // 字符串的时间
console.log(typeof date.toString());
console.log(date.toLocaleString()); // 2020/6/17 上午10:09:12
console.log(date.toLocaleDateString()); // 2020/6/17
console.log(date.toLocaleTimeString()); // 上午10:10:02

console.log(date.toDateString()); // Wed Jun 17 2020
document.write
  1. document.write(‘要写进去的内容’)

    // document.write('123');
    // document.write('456<em>12345</em>');
    
  2. document.write 与 document.body.innerHTML的区别

    1. document.write: 直接操作body 不能操作其他标签, document.write不会覆盖自身所写的内容, 可以识别标签

    2. innerHTML: 可以操作所有的闭合标签, innerHTML会覆盖自身所写的内容, 可以识别标签

    3. document.wirte == document.body.innerHTML

      var div = document.getElementsByTagName('div')[0];
      document.write('1234');
      // document.body.innerHTML = '123';
      
创建未来时间
  1. 创建当前时间

            var date = new Date(); 
            console.log(date);
    
  2. 创建未来时间 new Date(年, 月(0-11), 日, 时, 分, 秒)

    var date1 = new Date(2020, 5, 18, 0, 0, 0); // 数字: 年, 月(0-11), 日, 时, 分, 秒
    var date2 = new Date(2020, 5, 18); // 数字: 年, 月(0-11), 日, 时, 分, 秒
    console.log(date1);
    console.log(date2); // Thu Jun 18 2020 00:00:00 GMT+0800 (中国标准时间)
    
  3. 创建未来时间 new Date(‘年 月 日 hh:mm:ss’); 月份是1-12

    // 一般用连字符、空格、斜杠
    var date3 = new Date('2020 6 18 00:00:00');
    console.log(date3);
    var date4 = new Date('2020 6 18');
    console.log(date4);
    var date5 = new Date('2020%6%18');
    console.log(date5);
    
moment
  1. 下载地址:http://momentjs.cn/

  2. moment.js: 带格式的js文件 学习 moment.min.js: 压缩文件 工作

  3. 创建时间对象

    var date1 = new Date();
    console.log(date1);
    var date = moment();
    console.log(date);
    
  4. 获取moment的查询时间

    YYYY–年份 MM–月份 DD–日期 hh–小时 mm-分钟 ss–秒

    直接自带前导0

    console.log(date.format()); // 2020-06-17T14:55:29+08:00
    // YYYY--年份  MM--月份 DD--日期 hh--小时  mm-分钟  ss--秒
    // 直接自带前导0
    console.log(date.format('YYYY MM DD'));
    console.log(date.format('YYYY年MM月DD日 hh:mm:ss'));
    console.log(date.format('YYYY')); // 年
    console.log(date.format('MM')); // 月
    console.log(date.format('DD')); // 日期
    
    // 特殊值获取
    console.log(date.format('d')); // 星期 0-6-----> 日--六
    console.log(date.format('X')); // 秒数的时间戳
    console.log(date.toDate()); // 原生时间对象
    console.log(date.valueOf()); // 毫秒---时间戳
    console.log(date.getTime()); // 时间对象获取时间戳
    
  5. 创建时间

    1. 创建当前时间: var date1 = new Date();

    2. 创建未来时间: var date = moment(‘2020-06-18 00:00:00’);

    3. 创建未来时间: moment(对象)

      // 不加前导0和有其他特殊符号的时候会出现警告
      var date = moment('2020-06-18 00:00:00');
      console.log(date);
      var date1 = moment('2020-05-18 08:10:10');
      console.log(date1);
      var date2 = moment({
          year: 2020,
          month: 7, // 0-11
          date: 20,
          hour: 13,
          minute: 30,
          second: 30
      });
      console.log(date2.format('YYYY-MM-DD hh:mm:ss'));
      
    4. 获取特定时间和设置时间

      var date = moment();
      console.log(date.year()); // 年
      console.log(date.month()); // 月 0-11代表1-12
      console.log(date.date()); // 日
      console.log(date.day()); // 星期
      console.log(date.hour()); // 小时
      console.log(date.minute()); // 分钟
      console.log(date.second()); // 秒
      
      console.log(date.week()); // 一年中的第几周
      console.log(date.isLeapYear()); // 是否闰年
      console.log(date.dayOfYear()); // 一年中的第几天
      console.log(date.quarter()); // 当前是第几个季度
      console.log(date.daysInMonth()); // 当前所在月份的天数
      
      // 设置: 年月日时分秒
      date.year(2021);
      date.set('year', 2022); // date.set(属性, 值)
      date.set({
          'year': 2023
      });
      console.log(date.format());
      
  6. 查询时间: 返回结果都是布尔值

    先去对比年,对比月,对比日,对比小时,分钟,秒

    1. moment时间对象.isAfter(时间字符串, [哪一个层级年月日时分秒]);

      console.log(moment().isAfter('2020-06-18')); // 前面时间是否在后面时间之后
      console.log(moment().isAfter('2020-06-16')); // 前面时间是否在后面时间之后 true
      console.log(moment().isAfter()); // 前面时间是否在后面时间之后, 不传时间表示当前时间
      console.log(moment().isAfter('2020-06-16', 'year')); // 前面时间的年是否在后面时间的年之后, 不传时间表示当前时间 false
      console.log(moment().isAfter('2020-06-16 16:10:00', 'minute')); // 前面时间是否在后面时间之后, 不传时间表示当前时间 true
      
    2. moment时间对象.isBefore(时间字符串, [哪一个层级年月日时分秒]);

      console.log(moment().isBefore('2020-06-16 16:10:00', 'minute')); // 前面时间是否在后面时间之后, 不传时间表示当前时间 false
      
    3. moment时间对象.isSame(时间字符串, [哪一个层级年月日时分秒]);

      console.log(moment().isSame('2020-06-17 16:15:00', 'date')); // 判断前面时间的日期和后面时间的日期是否一致  true
      console.log(moment().isSame()); // true
      
    4. moment时间对象.isBetween(时间, 时间);

      console.log(moment().isBetween('2020-05-20', '2020-06-20')); // 判断前面的时间是不是在后面两个时间之间
      console.log(moment().isBetween('2020-05-20')); // 当前我时间是否在起始时间之后
      

字符串

创建字符串
  1. 概念: 被单双引号包裹的就是字符串

  2. 表达式声明法: var 变量名 = 值;

    var str = 'qwert';
    
  3. 构造函数创建: var 变量名 = new String(‘字符串’);

    var str1 = new String('12345');
    
  4. 表达式是字符串string, 构造函数是对象

    var str = 'qwert';
    var str1 = new String('12345');
    console.log(str, str1);
    console.log(typeof str, typeof str1); // string object
    
字符串基本
  1. 当前字符串的长度

    var str = '1234567890';
    // 当前字符串的长度
    console.log(str.length);
    
  2. 指定下标的字符

    console.log(str[3]); // ie8
    console.log(str.charAt(3));
    
  3. 获取指定下标的字符的ASCII值 a—97 A—65 0—48 1—49

    // 字符串.charCodeAt(下标)
    console.log(str.charCodeAt(3));
    
  4. 字符串的比较: 从左往右依次比较每一个字符的ASCII值,比较出来大小之后就结束比较

    console.log('10000' > '2'); // false
    
字符串方法
  1. 查找

    1. 字符串.indexOf(‘要查找的字符’, [起始位置下标]): 从左往右依次查找,找到字符就返回当前字符的下标, 如果找不到就返回-1

    2. 字符串.lastIndexOf(‘要查找的字符’, [起始位置下标]): 从右往左依次查找,找到字符就返回当前字符的下标, 如果找不到就返回-1

      var str = 'dshuksdhnsksdklADJKDR';
      console.log(str.indexOf('s')); // 1
      console.log(str.lastIndexOf('s')); // 11
      
      console.log(str.indexOf('s', 2)); // 5
      console.log(str.lastIndexOf('s', 10)); // 9
      
  2. 截取

    1. substring: 字符串.substring(起始下标, 结束下标);

      • 字符串.substring(): 截取整个字符串

        var str = '221sfehtagsjasfvhdnksdjhnl';
        console.log(str.substring());
        
      • 字符串.substring(起始下标): 从起始下标位置开始截取,到字符串的末尾结束

        console.log(str.substring(2)); // 1sfehtagsjasfvhdnksdjhnl
        
      • 字符串.substring(起始下标, 结束下标): 从起始下标开始截取,到结束下标为止, 包含起始下标的字符不包含结束下标的字符

        console.log(str.substring(4, 6)); // fe
        
      • 当结束下标小于起始下标, 将小的数字作为起始下标, 将大的数字作为结束下标

        console.log(str.substring(5, 2)); // 2-5   1sf
        
      • 当结束下标为负数的时候, 将负数转成0,然后再按照上面的规则去截取

        console.log(str.substring(5, -1)); // 0-5 221sf
        
    2. slice: 字符串.slice(起始下标, 结束下标);

      • 字符串.slice(): 表示截取整个字符串

        var str = 'sjkdkjadkjdaka';
        console.log(str.slice());
        
      • 字符串.slice(起始下标): 表示从起始下标位置开始截取到字符串结束为止

        console.log(str.slice(3)); // dkjadkjdaka
        
      • 字符串.slice(起始下标, 结束下标): 表示从起始下标位置开始截取到结束下标位置为止, 包含起始下标的字符不包含结束下标的字符

        console.log(str.slice(2,4)); // kd
        
      • \1. 结束下标小于起始下标, 返回空字符

        console.log(str.slice(5, 1));
        
      • \2. 结束下标是负数的时候, 从右往左数几位截取(后面几位不要)

        console.log(str.slice(0, -3)); // sjkdkjadkjd
        
      • \3. 只传一位且起始下标为负数, 表示后面截取几位

        console.log(str.slice(-3)); // aka
        
    3. 字符串.substr(起始下标, 截取的长度)

      var str = 'dskjdksjkd';
      console.log(str.substr(3, 4)); // jdks
      console.log(str.substr(3, 40)); // jdksjk
      
  3. 转大小写

    字符串.toLowerCase(); 将字母全部转成小写

    字符串.toUpperCase(); 将字母全部转成大写

    console.log(str.toLowerCase()); // bdkkxdkjsaklklj
    console.log(str.toUpperCase()); // BDKKXDKJSAKLKLJ
    

    =========================================================================

day 09

字符串方法

  1. split: 将字符串按照分割符分割数组,返回结果是个数组

    字符串.split(‘分割符’); 分割符可以是一切字符

    var str = '123451234512345';
    var arr = str.split('12');
    // var arr = str.split(''); // 每两个字符中间都有一个空字符
    // var arr = str.split(); // 整个作为一项
    console.log(arr);
    
  2. join: 将数组的每一项按照连接符连接成字符串,返回结果是个字符串

    数组.join(‘连接符’); 连接符可以是一切字符

    var str1 = arr.join('-');
    var str1 = arr.join('abcd'); // abcd345abcd345abcd345
    var str1 = arr.join(''); // 345345345
    var str1 = arr.join(); // ,345,345,345
    console.log(str1);
    
  3. 字符串.replace(要替换的字符, 替换的新字符); 一次只能替换一项

    var str = '12345123123';
    var str1 = str.replace('12', 'abc');
    console.log(str1, str1.replace('12', 'abc'));
    
  4. trim: 字符串.trim(); 去除字符串的左右空格

    var str = '      12345  12345     ';
    console.log(str);
    console.log(str.trim());
    

数组

对象的分类
  1. 原生对象: Sting\Number\Boolean Object\Array\Function Error\RegExp\Date
  2. 内置对象: Global(全局, window, document) Math
  3. 宿主对象: DOM BOM
  4. 全局对象: window
数组概念
  1. 数组: 是值得有序的集合; 用于存储不定数量不定类型的数据。
  2. 索引: 下标 元素: 下标对应的值
数组的声明方式
  1. 字面量声明法: var 变量名 = [];

  2. 构造函数声明: var 变量名 = new Array()

    var arr = new Array(); // 空数组
    console.log(arr);
    var arr = new Array(1, 2, 3); // 多个元素之间用,隔开
    console.log(arr);
    var arr = new Array(4); // 只写了一个值,并且还是数字的时候, 这个数字表示数组的长度, 存对应个数的empty
    console.log(arr);
    console.log(arr[1]); // undefined
    
数组的栈方法
  1. push: 从后面往数组中添加项,返回新数组的长度

    // 数组.push(项, 项1,...项n)
    var l = arr.push('a', 'b', 'v');
    console.log(l, arr);
    
  2. pop: 从数组的后面删除一项, 返回被删除的项

    var a = arr.pop();
    console.log(a, arr);
    
  3. unshift: 从前面往数组中添加项,返回新数组的长度

    // 数组.unshift(项, 项1,...项n);
    arr.unshift('a', 'b', 'v');
    console.log(arr);
    
  4. shift: 从数组的前面删除一项, 返回被删除的项

    var b = arr.shift();
    console.log(b, arr);
    
查找方法
  1. indexOf: 从左往右, 字符串/数组.indexOf(要查找的字符, 起始下标);

  2. lastIndexOf: 从右往左, 字符串/数组.lastIndexOf(要查找的字符, 起始下标);

    如果找到返回对应的下标,如果找不到返回-1

    数组查找的时候, 数组中的项必须和查找内容完全一致的情况下才能返回下标

    var arr = [1,2,3,4,1,2,3,4];
    console.log(arr.indexOf(3)); // 2
    console.log(arr.indexOf('3')); // -1
    
    console.log(arr.indexOf(3, 3)); // 6
    console.log(arr.lastIndexOf(3)); // 6
    console.log(arr.lastIndexOf(3, 5)); // 2
    
万能的splice方法
  1. 删除: 数组.splice(起始下标, 删除几个); 被删除的项组成一个新数组返回回来

    var arr = ['亚索', '盖伦', '波尔'];
    var a = arr.splice(1, 1);
    console.log(a, arr);
    
  2. 添加: 数组.splice(起始下标, 删除几个, 要添加的值, 要添加的在值1…要添加的值n);

    var b = arr.splice(1, 0, '凯瑟琳', '提莫');
    console.log(b, arr); //  ["亚索", "凯瑟琳", "提莫", "波尔"]
    
  3. 修改: 数组.splice(起始下标, 删除几个, 要添加的值, 要添加的在值1…要添加的值n);

    arr.splice(2, 2, '亚瑟', '庄周');
    console.log(arr); //  ["亚索", "凯瑟琳", "亚瑟", "庄周"]
    
算法排序
  1. 选择排序: 每次取出来一个值和它后面的每一个值进行比较, 前面的比后面的大就互换位置

    for(var i = 0; i < arr.length; i++){
        // 要比较的每一次的大项
        for(var j = i + 1;j < arr.length; j++){
            if(arr[i] > arr[j]){
                // 位置互换
                var temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }
    }
    console.log(arr);
    
  2. 冒泡排序: 每次用相邻的两个值去进行比较, 如果说前面的比后面的大就互换位置, 每次排出最大的

    for(var i = 0; i < arr.length; i++){
        for(var j = 0; j < arr.length - i; j++){
            if(arr[j] >arr[j+1]){
                var temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
    }
    console.log(arr);
    
sort

数组.sort(); 操作是原数组

​ 如果是两位以上的数字进行比较,按照字符串的比较方式,比较ASCII码值,从左往右依次比较

​ 数组.sort(函数);

​ 函数中有2个参数:

​ return 第一个 - 第二个参数; 返回从小到大的排序

​ return 第二个 - 第一个参数; 返回从大到小的排序

var arr = [14, 2, 3, 25, 26, 7, 1];
arr.sort();
console.log(arr); // [1, 14, 2, 25, 26, 3, 7]

arr.sort(function(x, y){
    console.log('x----' +x, y);
    return y - x;
    return x - y;
});
console.log(arr); // 
数组其他方法
  1. join: 将数组用连接符链接起来

    var arr = [1,2,3,'a'];
    var str = arr.join('abc');
    console.log(str); // 1abc2abc3abca
    
  2. reverse: 翻转数组, 改变的是原数组

    arr.reverse();
    console.log(arr);
    
  3. concat: 将两个数组连接起来,返回一个连接后的新数组, 原数组不改变

    数组1.concat(数组2, 数组3, …, 数组n);

    var arr2 = [3,4,5];
    var arr3 = [5,6,7];
    var arrnew = arr.concat(arr2, arr3);
    console.log(arrnew, arr, arr2);
    
  4. 数组.slice(起始下标, 结束下标): 返回包含起始下标不包含结束下标的项的数组, 与字符串完全一样

    console.log(arrnew.slice(2,5)); // [2, 1, 3]
    console.log(arrnew.slice(1)); // [3, 2, 1, 3, 4, 5, 5, 6, 7]
    console.log(arrnew.slice()); // 全部
    console.log(arrnew.slice(5, 3)); // []
    console.log(arrnew.slice(2, -1)); // 后面几个不要 [2, 1, 3, 4, 5, 5, 6]
    
  5. Array.isArray(要判断的数据): 返回true, false ie8及以上使用

    console.log(Array.isArray([])); // true
    console.log(Array.isArray({})); // false
    console.log(Array.isArray('a')); // false
    
迭代方法 ie8及以下不支持
  1. every: 对数组的每一项进行一些判断,如果每一个判断结果都为true,则最后返回结果为true &&

    // 数组.every(function(value, index, array){})  
    // index--下标 value---值  array--原数组
    var arr = [1,2,3,4,5];
    var res = arr.every(function(value, index, array){
        console.log(index, value, array);
        return value > 0;
    });
    console.log(res);
    
  2. some: 对数组的每一项进行一些判断,如果有一个判断结果为true,则最后返回结果为true, 所有的都是false, 才是返回false ||

    var res1 = arr.some(function(value, index, array){
        console.log(index, value, array);
        return value > 5;
    });
    console.log(res1);
    
  3. filter: 对数组进行一个过滤, 将满足条件的数组的项拿出来,组成一个新数组返回回来

    //  数组.filter(function(value, index, array){})  
    var res2 = arr.filter(function(value, index, array){
        console.log(index, value, array);
        return value > 1;
    });
    console.log(res2);
    
  4. map: 对数组进行一次循环, map有返回值, 循环执行的函数返回的值所组成的数组

    // 数组.map(function(value, index, array){})
    var arr = [1,2,3,4,5];
    var arr1 = arr.map(function(value){
        console.log(value);
        return value * value;
    });
    console.log(arr1);
    
  5. forEach: 对数组一个简单的循环

    var arr2 = arr.forEach(function(value, index){
        console.log(value, index);
        return value * value;
    });
    console.log(arr2); // undefined
    
中文排序

中文排序: 对比数据.localeCompare(要对比的数据, ‘zh’);

var arr = [
    {'name': 'z亚索', 'tips': 60},
    {'name': '提莫', 'tips': 70},
    {'name': '盲僧', 'tips': 80},
    {'name': 'f亚瑟', 'tips': 80},
    {'name': '发条', 'tips': 90},
    {'name': '狗头', 'tips': 35}
];
arr.sort(function(a,b){
    console.log(a.name.localeCompare(b.name, 'zh'));
    // return a.name - b.name;
    return a.name.localeCompare(b.name, 'zh');
});
console.log(arr);

============================================================================

day 10

DOM

节点
  1. DOM: Document Object Model 文档对象模型

    w3c规定的用来处理页面的标准接口

  2. 节点类型: nodeType 1—标签 2—属性 3–文本 9–文档document

  3. 节点名称: nodeName LI #text #comment

  4. 节点内容: 文本节点才有节点内容 nodeValue

    var ul = document.getElementsByTagName('ul')[0];
    console.log(ul.children);
    var lis = document.getElementsByTagName('li');
    console.log(lis);
    for(var i = 0; i < lis.length; i++){
        console.log(lis[i]);
        console.log(lis[i].nodeType);
    }
    for(var j = 0; j < ul.children.length; j++){
        console.log(ul.children[j].childNodes); // NodeList
        console.log(ul.children[j].childNodes[0].nodeName); // #text
        console.log(ul.children[j].childNodes[0].nodeValue); // 004
        console.log(ul.children[j].nodeName);
        console.log(ul.children[j].nodeValue); // null
    }
    
获取子节点
  1. 节点.children: 非标准属性, 标准浏览器中获取到所有的标签节点(ie8以下包含注释节点)

  2. 节点.childNodes: 标准属性, 标准浏览器中会获取到包含的文本节点

    for(var j = 0; j < ul.children.length; j++){
        console.log(ul.children[j].childNodes); // NodeList
        console.log(ul.children[j].childNodes[0].nodeName); // #text
        console.log(ul.children[j].childNodes[0].nodeValue); // 004
        console.log(ul.children[j].nodeName);
        console.log(ul.children[j].nodeValue); // null
    }
    
获取父节点
  1. 节点.parentNode: 获取到直接父节点

  2. 节点.offsetParent: 获取到具有定位属性的父节点, 如果没有具有定位属性的父节点,返回body

    var li = document.getElementsByTagName('li')[2];
    console.log(li.parentNode);
    console.log(li.offsetParent);
    
    <div>
        <ul>
            <li>001</li>
            <li>002</li>
            <li>003</li>
            <li>004</li>
            <li>005</li>
        </ul>
    </div>
    
获取其他节点
  1. 获取第一个子节点

    父节点.firstChild: 标准浏览器中文本、换行节点, ie8及以下标签节点

    父节点.firstElementChild: 标准浏览器获取标签节点 ie8 — undefined

    兼容: 父节点.firstElementChild || 父节点.firstChild

    首先获取左边条件,如果左边有,直接用左边的; 如果左边没有用右边的

    var ul = document.getElementsByTagName('ul')[0];
    var li = document.getElementsByTagName('li')[2];
    console.log(ul.firstChild);
    console.log(ul.firstElementChild);
    // 兼容
    console.log(ul.firstElementChild || ul.firstChild);
    
  2. 获取最后一个子节点

    父节点.lastChild: 标准浏览器中文本、换行节点, ie8及以下标签节点

    父节点.lastElementChild: 标准浏览器获取标签节点 ie8 — undefined

    兼容: 父节点.lastElementChild || 父节点.lastChild

    console.log(ul.lastElementChild || ul.lastChild);
    
  3. 获取上一个兄弟元素

    节点.previousSibling: 标准浏览器中拿到文本、换行节点, ie8及以下标签节点

    节点.previousElementSibling: 标准浏览器获取标签节点

    兼容: 节点.previousElementSibling || 节点.previousSibling

    console.log(li.previousSibling);
    console.log(li.previousElementSibling);
    console.log(li.previousElementSibling || li.previousSibling);
    
  4. 获取下一个兄弟元素

    节点.nextSibling: 标准浏览器中拿到文本、换行节点, ie8及以下标签节点

    节点.nextElementSibling: 标准浏览器获取标签节点

    兼容: 节点.nextElementSibling || 节点.nextSibling

    console.log(li.nextElementSibling || li.nextSibling);
    
创建节点
  1. 创建标签节点

    var 变量 = document.createElement(‘标签名’);

        var li = document.createElement('li');
    
  2. 创建文本节点

    var 变量 = document.createTextNode(‘要添加的内容’);

    var txt = document.createTextNode('这是通过节点创建的文本内容');
    
  3. 文本节点追加到标签节点中

    标签节点.appendChild(文本节点);

    li.appendChild(txt);
    
添加节点
  1. 在父元素末尾追加节点

    父节点.appendChild(子节点);

    var li = document.createElement('li');
    var txt = document.createTextNode('这是通过节点创建的文本内容');
    li.appendChild(txt);
    console.log(li);
    var ul = document.getElementsByTagName('ul')[0];
    ul.appendChild(li);
    
  2. 追加到某个节点之前

    父节点.insertBefore(新节点, 参考节点);

    var lis = document.getElementsByTagName('li');
    console.log(lis);
    ul[0].insertBefore(li, lis[2]);
    
  3. 注意: 追加的元素已经存在与页面中,不会再去添加一个元素,而是发生物理位移

    var li = document.createElement('li');
    var txt = document.createTextNode('这是通过节点创建的文本内容');
    li.appendChild(txt);
    var ul = document.getElementsByTagName('ul');
    ul[0].appendChild(li);
    ul[1].appendChild(li);
    
    var lis = document.getElementsByTagName('li');
    console.log(lis);
    ul[0].insertBefore(li, lis[2]);
    
删除节点
  1. 删除自身及子节点:

    节点.remove();

    var removeUl = ul[1].remove();
    console.log(removeUl); // undefined
    
  2. 删除某个子节点:

    父节点.removeChild(子节点);

    返回被删除的子节点

    var removLi = ul[0].removeChild(lis[1]);
    console.log(removLi);
    
克隆节点
  1. 节点.cloneNode(boolean); boolean表示是否复制节点中的内容

    false/不传, 不克隆其中的内容

    true, 克隆

    克隆出来的节点需要追加后才能在页面中显示出来

    var cUl = ul[0].cloneNode(true);
    console.log(cUl);
    document.body.appendChild(cUl);
    
替换节点

父节点.replaceChild(新节点, 被替换的节点);

var li = document.createElement('li');
var txt = document.createTextNode('这是通过节点创建的文本内容');
li.appendChild(txt);
console.log(li);

var ul = document.getElementsByTagName('ul');
var lis = document.getElementsByTagName('li');
ul[0].replaceChild(li, lis[2]);
获取元素的其他方式
  1. 获取到符合选择器的第一个元素:document.querySelector(‘选择器’)

    ​ 获取到直接元素

  2. 获取到符合选择器的所有元素: document.querySelectorAll(‘选择器’) 获取到集合

  3. 注意: 不具有动态性, 获取的时候有就是有

    var bo = document.querySelector('*');
    console.log(bo);
    console.log(document.querySelector('ul'));
    console.log(document.querySelector('#box'));
    console.log(document.querySelector('.a.b'));
    console.log(document.querySelector('.a, .b'));
    
    var all = document.querySelectorAll('.a, .b')
    console.log(all); // NodeList(2) [li.a.b, li.a]
    console.log(document.querySelectorAll('ul li:nth-child(3)'));
    
    document.querySelector('ul').innerHTML += '<li class="a">1234</li>';
    console.log(all);
    
操作元素属性
  1. 元素.属性名 = 属性值

  2. 元素[‘属性名’] = 属性值

    1.2 不能操作自定义属性

  3. 获取属性: 元素.getAttribute(‘属性名’);

  4. 设置属性: 元素.setAttribute(‘属性名’, ‘属性值’);

  5. 移除属性: 元素.removeAttribute(‘属性名’); 彻底将属性删除掉

    既可以操作固有属性, 也可以操作自定义属性

    var box = document.getElementById('box');
    console.log(box.tag); // undefined
    console.log(box['tag']);
    box.flag = 1;
    console.log(box.flag); // 1
    
    console.log(box.getAttribute('tag')); // false
    console.log(box.setAttribute('tit', '这是头'));
    
    console.log(box.removeAttribute('id'));
    
操作表格

快速获取表格

var table = document.getElementsByTagName('table')[0];
console.log(table.tHead); // 表格头
console.log(table.tBodies); // 表格体 HTMLCollection [tbody]
console.log(table.tFoot); // 表格脚
console.log(table.rows); // 表格行 HTMLCollection(6) [tr, tr, tr, tr, tr, tr]
console.log(table.tHead.rows); // HTMLCollection [tr]
console.log(table.tBodies[0].rows); // 获取第一个表格体中的所有的行

// 表格默认不是由单元格组成, 只能由行获取
console.log(table.cells); // undefined
console.log(table.rows[1].cells); // HTMLCollection(4) [td, td, td, td]
var r = table.tBodies[0].rows;
table.tBodies[0].innerHTML += '<tr><td>1111</td><td>1111</td><td>1111</td><td>1111</td></tr>';
console.log(r);

===================================================================

day 11

BOM

对话框
  1. 警告框

    alert(1);

  2. 带有确定按钮的对话框: confirm(‘要提示的内容’); 具有返回值: true–确定 false—取消

    var back = confirm('弹出了吗?');
    console.log(back);
    
  3. 带有输入框的对话框: prompt(‘提示语’, ‘默认值’); 具有返回值, 确定—返回输入框的内容 取消—null

    var back = prompt('弹出了吗?', '是的');
    console.log(back); // 如果字符串中没有内容,返回空字符串
    
open和close
  1. open(‘网址’, ‘打开方式’, ‘特殊值’, 是否替代原先的浏览历史)

    ​ 网址: 要跳转网页地址

    ​ 打开方式: _self _blank

    ​ 特殊值: 宽高, _self下不起作用, width=80,height=80

    ​ 是否浏览历史: true

    ​ 具有返回值, 返回新窗口的window

    setTimeout(function(){
        var win = open('./05test.html', '_blank', 'width=500,height=300', true);
        console.log(win);
        setTimeout(function(){
            win.close(); // 新打开的页面被关闭
        },3000);
    }, 3000);
    
  2. close: close(); 关掉当前页面 重新打开页面

    document.onclick = function(){
        close();
    }
    
    <!-- 默认window, window不能省略 -->
    <button onclick="window.close()">关闭</button>
    
location

location: 最有用的对象之一, 存储当前的网页相关的信息,提供了一些导航功能, 既是window也是document的对象

console.log(location);
console.log(location.protocol); // 服务器协议 file http https
console.log(location.host); // 服务器名称+端口号
console.log(location.hostname); // 服务器名称
console.log(location.port); // 端口号
console.log(location.href); // 完整地址  http://127.0.0.1:5500/day11/06%20loaction.html
console.log(location.hash); // #号后面的无序的列表内容  #123
console.log(location.search); // 搜索内容 ?及后面的内容  ?a=1&b=2

// 改变页面地址---->页面跳转
location.href = 'https://www.baidu.com';
history

实现页面之间的导航功能

​ history.back(); // 向后回退一个页面

​ history.forward(); // 向前前进一个页面

​ history.go(数字); // 跳转到第几个页面 负数–向后后退几个页面 正数—向前前进几个页面 0—刷新

history.html

<button>
    跳转到a页面
</button>
<button>
    刷新
</button>
var btn = document.getElementsByTagName('button');
btn[0].onclick = function(){
    // location.href = './a.html';
    // setTimeout(function(){
        // history.forward();
        history.go(1); // 替换forward
    // }, 1000);
} 
btn[1].onclick = function(){
    history.go(0);
}

a.html

<button>
    点击回退到上一个页面
</button>
var btn = document.getElementsByTagName('button')[0];
btn.onclick = function(){
    // history.back();
    history.go(-1);
} 
// setTimeout(function () {
//     history.back();
// }, 1000);
navigator

appCodeName 浏览器的名称。通常都是Mozilla,即使在非Mozilla浏览器中也是如此
appMinorVersion 次版本信息
appName 完整的浏览器名称
appVersion 浏览器的版本。一般不与实际的浏览器版本对应
buildID 浏览器编译版本
cookieEnabled 表示cookie是否启用
cpuClass 客户端计算机中使用的CPU类型(x86、68K、Alpha、PPC或Other)
javaEnabled() 表示当前浏览器中是否启用了Java
language 浏览器的主语言
mimeTypes 在浏览器中注册的MIME类型数组
onLine 表示浏览器是否连接到了因特网
opsProfile 似乎早就不用了。查不到相关文档
oscpu 客户端计算机的操作系统或使用的CPU
platform 浏览器所在的系统平台
plugins 浏览器中安装的插件信息的数组
preference() 设置用户的首选项
product 产品名称(如 Gecko)
productSub 关于产品的次要信息(如Gecko的版本)

systemLanguage 操作系统的语言
taintEnabled() 已经废弃。表示是否允许变量被修改(taint)。为了与Netscape Navigator 3向后兼容而保留下来
userAgent 浏览器的用户代理字符串
userLanguage 操作系统的默认语言
userProfile 借以访问用户个人信息的对象
vendor 浏览器的品牌
vendorSub 有关供应商的次要信息

元素三大宽高
  1. client: 元素的可视宽高 内容 + padding

    1. 元素的宽高:元素.clientWidth/clientHeight

    2. 元素上边距的宽度: 元素.clientTop

    3. 元素左边框的宽度: 元素.clientLeft

      <div class="box">
      12345
      </div>
      
      .box {
          width: 200px;
          height: 200px;
          padding: 40px;
          background: pink;
          border: 1px solid #000;
          margin: 40px;
          border-left-width: 10px;
      }
      
      var box = document.getElementsByTagName('div')[0];
      console.log(box.clientHeight); // 280
      console.log(box.clientWidth); // 280
      console.log(box.clientTop, box.clientLeft); // 1  10
      
  2. offset: 元素的占位宽高 内容 + padding + border

    元素的宽高: 元素.offsetWidth/offsetHeight

    元素距离定位父元素距离:元素.offsetTop/offsetLeft

    元素距离具有定位属性的父元素的顶部/左边距离, 如果父元素没有定位属性,则根据body进行定位

    var box = document.getElementsByTagName('div')[1];
    console.log(box.offsetHeight); // 200 + 40 + 40 + 1 + 1
    console.log(box.offsetWidth); // 200 + 40 + 40 + 10 + 1
    console.log(box.offsetTop, box.offsetLeft); // 30 50
    
  3. scroll: 元素滚动的距离

    ​ 元素宽高: 元素.scrollWidth/元素.scrollHeight

    ​ 元素被卷去的距离: 元素.scrollLeft/scrollTop

    onscroll: window.onscroll: 页面的滚动

    页面的滚动距离:

    ​ document.documentElement.scrollTop/scrollLeft

    ​ document.body.scrollTop/scrollLeft

    var box = document.getElementsByTagName('div')[1];
    console.log(box.scrollWidth);
    console.log(box.scrollHeight);
    
    window.onscroll = function(){
        console.log(document.documentElement.scrollTop);
        console.log(document.body.scrollTop);
    }
    
    box.onscroll = function(){
        console.log(this.scrollTop);
    }
    

    表单元素

    获取

    form.name值—获取到当前form中name为name值得元素

    <form action="">
        用户名: <input type="text" name="userName" value="小可爱">
        密码: <input type="text" name="password">
        性别: <input type="radio" name="sex" id="" value="nan"><input type="radio" name="sex" id="" checked value="nv">女
        城市: <select name="city" id="">
            <option value="北京">北京</option>
            <option value="上海111" selected>上海</option>
            <option value="广州">广州</option>
        </select>
        爱好: <input type="checkbox" name="hobby" id=""><input type="checkbox" name="hobby" id=""><input type="checkbox" name="hobby" id="" checked value="rap">rap
        <input type="checkbox" name="hobby" id="">王者
        <input type="checkbox" name="hobby" id="" checked value="tt">烫头
    </form>
    
    // 1. 获取form表单
    var form = document.getElementsByTagName('form')[0];
    // 2. 获取表单中的元素: form.name值
    console.log(form.userName);
    console.log(form.userName.value);
    console.log(form.password);
    console.log(form.sex); // 集合 RadioNodeList(2) [input, input, value: ""]
    console.log(form.sex.value);
    console.log(form.city);
    console.log(form.city.value);
    console.log(form.hobby); // RadioNodeList(5) [input, input, input, input, input, value: ""]
    
    表单事件

提交事件: onsubmit return true—表示可以提交表单 return false—表示不可以提交表单 加给form表单

form.onsubmit = function(){
    // 看密码有没有输入
    if(form.password.value == ''){
        // 不能提交
        alert('密码不能为空');
        return false;
    } else {
        return true;
    }
}

重置事件: onreset return true—表示可以重置表单 return false—表示不可以重置表单 加给form表单

form.onreset = function(){
    if(form.userName.value != '小可爱'){
        return true;
    } else {
        alert('当前内容不需要重置');
        return false;
    }
}

聚焦事件: onfocus 当前input输入框光标被置于其中时触发的事件

form.userName.onfocus = function(){
    this.value = '';
}

失焦事件: onblur 当输入框失去焦点的时候触发的事件 加给表单元素input

form.userName.onblur = function(){
    if(this.value == ''){
        this.value = '小可爱';
    }
}

内容改变事件: onchange: 当输入框失去焦点并且内容发生改变的时候触发

form.userName.onchange = function(){
    console.log(this.value);
}

边输入边改变: oninput(标准)/onpropertychange(ie): 在一边输入内容的时候一边触发的事件

form.password.oninput = function(){
    // console.log(this.value);
}
form.password.onpropertychange = function(){
    console.log(this.value);
}

=========================================================================

day 12

表单方法

  1. 提交: 表单.submit();

  2. 重置: 表单.reset();

  3. 对应元素的聚焦: 表单元素.focus();

  4. 对应元素的失焦: 表单元素.blur();

  5. 自动选择: 表单元素.select();

    var form = document.getElementsByTagName('form')[0];
    var btn = document.getElementsByTagName('button')[0];
    btn.onclick = function(){
        // form.submit();
        if(form.userName.value != ''){
            form.reset();
            form.userName.blur();
            // form.userName.focus();
            setTimeout(function(){
                // form.userName.blur();
                form.userName.select(); // 填写信息不完整的时候
            }, 5000);
        }
    }
    

事件

  1. 事件处理函数: 当事件发生时,执行的函数就叫做事件处理函数

    下方fn\function(){console.log(1);} 都是事件处理函数

    // 获取元素
    var div = document.getElementsByTagName('div')[0];
    // 加事件
    // div.onclick = function(){
    //     console.log(1);
    // }
    
    function fn(ev){
        console.log(event); // MouseEvent
    }
    div.onclick = fn;
    
  2. 事件对象: 事件在发生的时候, 浏览器会将相关的一些信息(事件类型, 鼠标的位置, 相关元素的信息…)都存储在一个对象中, 这个对象就是事件对象

    ​ 标准/ie: 全局的event

    ​ 低版本ff: 以事件处理函数的第一个参数传入进来

    ​ 兼容: window.event || ev

    function fn(ev){
        console.log(event); // MouseEvent
        console.log(window.event); // MouseEvent
        console.log(ev);
        var evs = window.event || ev;
        console.log(evs);
    }
    
  3. 事件对象的属性:

    function fn(ev){
        console.log(event); // MouseEvent
        console.log(window.event); // MouseEvent
        console.log(ev);
        var evs = window.event || ev;
        console.log(evs);
        console.log(evs.type); // 事件类型
        console.log(evs.target); // 事件源
        console.log(evs.srcElement); // 事件源
        console.log(evs.target || evs.srcElement);
        console.log(evs.clientX, evs.clientY); // 当前鼠标距离屏幕可视区域左边和上边的距离
        console.log(evs.pageX, evs.pageY); // 当前鼠标距离页面的左边和上边的距离
        console.log(evs.screenX, evs.screenY);// 当前鼠标距离屏幕左上角的距离
        console.log(evs.ctrlKey, evs.altKey, evs.shiftKey); // 当前键是否被按下  按下--true  没有---false
    }
    div.onclick = fn;
    
    document.onkeydown = function(ev){
        var evs = event || evs;
        console.log(evs.key); // 对应键的值  ie上无法获取
        console.log(evs.keyCode); // 对应键的ASCII码值
    }
    
  4. 事件绑定:

    • 元素.事件 这种方式给同一个元素添加多个同一事件的处理函数的时候, 后面的会覆盖前面的

      // 获取元素
      var div = document.getElementsByTagName('div')[0];
      // 加事件
      // div.onclick = function(){
      //     alert(1);
      // }
      // div.onclick = function(){
      //     alert(2);
      // }
      
    • 事件监听

      • 标准: 元素.addEventListener(‘事件类型’, 事件处理函数, 是否捕获)

        function a(){
            alert(2);
        }
        div.addEventListener('click', function(){
            alert(1);
            console.log(this); // 触发源
        }, false);
        div.addEventListener('click', a, false);
        
      • ie: 元素.attachEvent(‘on+事件类型’, 事件处理函数)

        div.attachEvent('onclick', function(){
            alert(1);
            console.log(this); // window
        });
        div.attachEvent('onclick', a);
        
      • 事件机制的区别:

        • 标准: 事件类型不加on ie: 加on
        • 标准有捕获事件, ie中没有
        • 标准是正序执行, ie中是倒叙执行
        • 标准this指向触发源, ie中指向window
  5. 事件移除

    • 元素.事件 元素.事件 = null

    • addEventListener removeEventListener(‘事件类型’, 函数, 是否捕获)

    • attachEvent detachEvent(‘on+事件类型’, 函数)

      function a() {
          alert(2);
      }
      ujiuye.addEvent(div, 'click', a);
      // div.onclick = null;
      
      // div.removeEventListener('click', a, false);
      // div.detachEvent('onclick', a);
      
      removeEvent(div, 'click', a);
      
      
      function removeEvent(elem, type, fn) {
          // elem: 元素
          // type: 事件类型
          // fn: 事件处理函数
          if (elem.detachEvent) {
              // ie
              elem.detachEvent('on' + type, fn);
          } else {
              // 标准
              elem.removeEventListener(type, fn, false);
          }
      }
      
事件流
  1. 事件流:当事件发生的时候, 事件在元素之间的固定的传递过程

  2. 事件流发生的过程

    • 捕获阶段: 当事件发生的时候, 事件从window开始一层层往子元素传递
    • 确定目标: 确定事件目标
    • 冒泡阶段: 目标源接收到事件并开始处理事件, 处理完成后, 从子元素一层层往出传递, 知道window
  3. 事件类型: 捕获型, 冒泡型

  4. addEventListener(事件类型, 事件处理函数, 是否捕获)

    ​ false—不是捕获, 就是冒泡

    ​ true—是捕获

    var divs = document.getElementsByTagName('div');
    function a(){
       console.log(this); // 触发源
    }
    divs[0].addEventListener('click', a, true); // 捕获
    divs[1].addEventListener('click', a, false); // 冒泡
    divs[2].addEventListener('click', a, true); // 捕获
    divs[3].addEventListener('click', a, false); 
    
阻止冒泡

标准: evs.stopPropagation();

ie: evs.cancelBubble = true;

兼容: 一个(), 一个没有(), 用方法做判断

evs.stopPropagation ? evs.stopPropagation() : evs.cancelBubble = true;

// 点击显示按钮,让div显示, 点击空白页面部分让div隐藏
// 获取元素 div button
var btn = document.getElementsByTagName('button')[0];
var div = document.getElementsByTagName('div')[0];
// 添加事件
btn.onclick = function(ev){
    var evs = event || ev;
    // console.log(evs.stopPropagation);
    // evs.stopPropagation();
    // evs.cancelBubble = true;
    evs.stopPropagation ? evs.stopPropagation() : evs.cancelBubble = true;
    div.style.display = 'block';
}
阻止默认事件

默认事件: a跳转 图片拖拽保存 右键默认菜单

​ 元素.事件 return false

​ 元素.addEventListener evs.preventDefault();

​ 元素.attachEvent(‘on+事件类型’, 函数) evs.returnValue = false;

兼容:

evs.preventDefault ? evs.preventDefault() : evs.returnValue = false;

var as = document.getElementsByTagName('a')[0];
// as.onclick = function () {
//     return false;
// }

// as.addEventListener('click', function(ev){
//     var evs = event || ev;
//     evs.preventDefault();
// }, false);

as.attachEvent('onclick', function(ev){
    var evs = event || ev;
    evs.returnValue = false;
});
滚轮事件
  1. ie/chrome: onmousewheel 当滚轮滚动的时候触发 向下— -120 向上— 120

  2. 火狐: 事件监听 元素.addEventListener(‘DOMMouseScroll’, 事件处理函数) 向上— -3 向下— 3

    function mouseS(ev){
        var evs = event || ev;
        // console.log(evs); // WheelEvent 
        if(evs.wheelDelta){
            // ie/chrome
            console.log(evs.wheelDelta); // WheelEvent  ff--undefined
        } else {
            // ff
            console.log(evs.detail); // WheelEvent  ff--undefined
        }
    }
    document.onmousewheel = mouseS;
    document.addEventListener('DOMMouseScroll', mouseS);
    
事件委托(事件代理)
  1. 事件委托(事件代理): 将子元素要做的事情交给父元素来处理, 父元素的事件再去触发的过程中, 他可以找到触发源

  2. 元素可以发生在未来

    var ul = document.getElementsByTagName('ul')[0];
    ul.onclick = function(ev){
        var evs = event || ev;
        console.log(evs.target, evs.srcElement);
        var target = evs.target || evs.srcElement;
        if(target.nodeName == 'LI'){
            target.style.background = 'red';
        }
    }
    ul.innerHTML += '<li>123456</li>';
    
    键盘事件
    1. onkeydown: 键盘按下 得不到特殊符号的编码 不可以区分大小写

      document.onkeydown = function(ev){
          var evs = event || ev;
          console.log(evs.key); // 键
          console.log(evs.keyCode); // 键的ASCI码值
      }
      
    2. onkeypress: 键盘按下 特殊键 + 数字 —> 特殊符号 特殊键不会触发 可以区分大小写编码

      document.onkeypress = function(ev){
          var evs = event || ev;
          console.log(evs.key); // 键
          console.log(evs.keyCode); // 键的ASCI码值
      }
      
    3. onkeyup: 键盘抬起

      document.onkeyup = function(){
          console.log(1);
      }
      

=========================================================================

day 14

面向对象

编程模式
  1. 面向过程: 注重过程
  2. 面向对象: 注重结果
  3. 面向对象的特点:封装 继承 多态
  4. 面向对象:
    1. 属性: 动态的后面要使用的变量
    2. 方法: 行为—函数–事件
面向对象的创建
  1. 字面量创建

    // 创建一个对象
    var obj = {};
    // 添加属性
    obj.name = '张s三';
    obj.age = 18;
    // 添加方法
    obj.tip = function(){
        console.log('会吃会喝会玩会挣钱');
    }
    // 适用于单一对象的创建
    
  2. 实例化创建

    var obj1 = new Object();
    obj1.name = '张三';
    obj1.age = 18;
    
    obj1.tip = function(){
        console.log('会吃会喝会玩会挣钱');
    }
    
    console.log(obj1);
    // 代码会比较冗余 
    
  3. 工厂模式

    function createObj(name, age) {
        // 1. 创建一个空对象
        var obj1 = new Object();
        // 2. 添加属性
        obj1.name = name;
        obj1.age = age;
        // 3. 添加方法
        obj1.tip = function () {
            console.log('会吃会喝会玩会挣钱');
        }
        console.log(obj1);
        // 4. 创建好的对象给他返回出去
        return obj1;
    }
    
    var obj1 = createObj('张三', 18);
    var obj2 = createObj('张三', 25);
    
    console.log(obj1, obj2);
    console.log(typeof obj1); // object
    
    // 对象 instanceof 要验证的构造函数
    console.log(obj1 instanceof createObj); // false
    console.log(obj1 instanceof Object); // true
    // 识别不清
    
  4. 构造函数创建

    • 构造函数的特点
      • 函数名首字母大写的函数(约定), 为了和普通函数区分开
      • 构造函数在使用的时候必须加new来调用,否则就和普通函数一样
      • 构造函数的方法和属性都直接加在this上,不需要设置返回值
    • new的作用
      • 创建出来一个空对象
      • 将空对象的prototype指向构造函数的prototype
      • 将this指向空对象, 添加属性和方法, 隐式返回
    // 构造函数
    function CreateObj(name, age) {
        // 1. 创建一个空对象
        // var obj1 = new Object();
        // 2. 添加属性
        this.name = name;
        this.age = age;
        // 3. 添加方法
        this.tip = function () {
            console.log('会吃会喝会玩会挣钱');
        }
        // console.log(obj1);
        // 4. 创建好的对象给他返回出去
        // return obj1;
    }
    // 实例化对象
    var obj1 = new CreateObj('张三', 28);
    console.log(obj1); // CreateObj
    
    var obj2 = new CreateObj('张三', 28);
    console.log(obj2); // CreateObj
    
    console.log(obj1 instanceof CreateObj); // true
    console.log(obj1 instanceof Object); // true
    
    console.log(obj1.tip == obj2.tip); // false  引用数据类型如果地址一致用双等返回true, 如果地址不一致,返回false
    
    // 内存浪费
    
  5. 原型创建

    • 原型: 每个对象被创建出来的时候用来保存最顶层的共享的方法和属性的就是原型

    • 原型:__ proto__ 原型属性: prototype

      var arr = new Array(1,2,3);
      console.log(arr);
      console.log(arr.__proto__);
      console.log(Array.prototype);
      console.log(arr.__proto__ == Array.prototype); // true
      
    • 原型创建

      function CreateObj(name, age) {}
      console.log(CreateObj.prototype);
      CreateObj.prototype.name = '张三';
      CreateObj.prototype.age = 30;
      CreateObj.prototype.tip = function(){
          console.log('会吃会喝会玩会挣钱');
      }
      
      // 实例化对象
      var obj1 = new CreateObj();
      var obj2 = new CreateObj();
      console.log(obj1, obj2);
      console.log(obj1.name, obj2.name);
      console.log(obj1.tip == obj2.tip); // true 地址相同
      
      // 不能传参
      
  6. 混合创建 构造函数(可变) + 原型创建(不变)

    1. 可变的属性和方法作为参数传递 不变的属性和方法用原型来存储
    // 构造函数
    function CreateObj(name, age) {
        // 2. 添加属性
        this.name = name;
        this.age = age;
    }
    // 原型创建
    CreateObj.prototype.tip = function(){
        console.log('会吃会喝会玩会挣钱');
    }
    // 实例化对象
    var obj1 = new CreateObj('张思', 29);
    var obj2 = new CreateObj('李五', 39);
    console.log(obj1, obj2);
    obj1.tip();
    obj2.tip();
    console.log(obj1.tip == obj2.tip);
    
命名空间

命名单词不足/项目很大的时候使用命名空间

var wrap = {};
// 顶部导航栏
wrap.nav = {};
wrap.nav.menu = 'abc';
wrap.nav.height = 40;

// 主要内容
wrap.main = {};
wrap.main.menu = '这是主要内容的菜单';

console.log(wrap);
改变this指向
  1. this指向

    this:存在于全页面的任何位置

    普通函数: window

    全局: window

    事件函数: 触发源

    对象方法: 指向对象

    构造函数: M对象

  2. 改变this指向的方法

    • call: 函数.call(新的指向, 参数1, …, 参数n)

    • apply: 函数.apply(新的指向, [参数1, … ,参数n])

    • bind: 函数.bind(新的指向) 具有返回值,创建出来一个新的函数并将这个新的函数返回

    • 1.2 改变函数的this指向并且调用函数,3需要接收新的函数并且重新调用

      function sum(a, b){
          console.log(this, a + b);
      }
      sum(); // window
      sum.call(1); // 1
      sum.apply(1); // 1
      
      sum.call(1, 10, 20);
      sum.apply(1, [10, 20]);
      
      var obj = {
          name:'张三',
          say: function(){
              console.log(this.name);
          }
      }
      obj.say(); // 张三
      var obj1 = {
          name: '李四',
          say: function(){
              console.log(this.name);
          }
      }
      obj1.say(); // 李四
      
      obj.say.call(obj1); // 李四
      
      var obj2 = {
          name:'王五'
      }
      obj.say.call(obj2); // 王五
      
      var s = obj.say.bind(obj2);
      console.log(s);
      s();
      
继承
原型链继承
  1. 原型: 对象在被创建的时候用来存储最顶层的共享的属性和方法的属性

  2. 原型链: 原型之间形成的查找的继承链, 由于原型之间的嵌套形成的链表关系

  3. 原型链查找:

    1. 先从自身查找,找得到就用自身的
    2. 找自己的原型属性, 父类构造函数的实例化对象
    3. 父类构造函数的原型对象
  4. 原型链继承的核心:

    将子类构造函数的原型对象(prototype) = 父类构造函数的实例化对象(new)

    // 父类构造函数
    function Parent(name, sex, age){
        this.name = name;
        this.sex = sex;
        this.age = age;
    }
    Parent.prototype.tip = function(){
        console.log('吃饭睡觉打豆豆');
    }
    Parent.prototype.array = [1,2,3];
    
    // 子类构造函数
    function Son(){}
    Son.prototype.tip = function(){
        console.log('游戏打闹加睡觉');
    }
    
    // 将子类构造函数的原型对象(prototype) = 父类构造函数的实例化对象(new)
    Son.prototype = new Parent('小可爱', 2, 18);
    
    // 由子类构造函数创建实例化对象
    var obj = new Son();
    console.log(obj);
    console.log(obj.name);
    console.log(obj.array);
    
    var obj1 = new Son();
    console.log(obj1.array);
    obj1.array.push(4);
    
    console.log(obj.array); // 4 [1, 2, 3, 4]
    
    /* 
        1. 不能传参
        2. 如果原型中是用了引用类型,那么就会一改全改
    */
    
对象冒充继承

核心: 对象冒充继承: 在子类构造函数中调用父类构造函数, 并且将父类构造函数的this指向当前子类构造函数的this

// 父类构造函数
function Parent(name, sex, age){
    this.name = name;
    this.sex = sex;
    this.age = age;
}
Parent.prototype.tip = function(){
    console.log('吃饭睡觉打豆豆');
}
Parent.prototype.array = [1,2,3];

// 子类构造函数
function Son(name, sex, age){
    // 在子类构造函数中调用父类构造函数, 并且将父类构造函数的this指向当前子类构造函数的this
    Parent.call(this, name, sex, age);
}
// Son.prototype.tip = function(){
//     console.log('游戏打闹加睡觉');
// }

// 由子类构造函数创建实例化对象
var obj = new Son('张三', 1, 30);
console.log(obj);
console.log(obj.name);
// console.log(obj.array);

var obj1 = new Son('李四', 2, 25);
console.log(obj1);
console.log(obj.array); // undefined

/* 
    1. 不能继承父类构造函数的原型对象的属性和方法
*/
组合继承

对象冒充继承+原型链继承

// 父类构造函数
function Parent(name, sex, age){
    this.name = name;
    this.sex = sex;
    this.age = age;
    this.array = [1,2,3];
}
Parent.prototype.tip = function(){
    console.log('吃饭睡觉打豆豆');
}

// 子类构造函数
function Son(name, sex, age){
    // 2. 对象冒充继承: 在子类构造函数中调用父类构造函数, 并且将父类构造函数的this指向当前子类构造函数的this
    Parent.call(this, name, sex, age);
}

// 3. 原型链继承
Son.prototype = new Parent();

// 由子类构造函数创建实例化对象
var obj = new Son('张三', 1, 30);
console.log(obj);
console.log(obj.name);
// console.log(obj.array);

var obj1 = new Son('李四', 2, 25);
console.log(obj1);
console.log(obj.array); // undefined

day 15

正则

  1. 正则:就是对字符串操作的一种逻辑公式。其实就是用提前事先定义好的一些特殊的代表字符来组成规律性的字符串, 来对字符串进行一些查找替换的操作

    创建正则
    1. 字面量 var reg = /规则字符串/修饰符;

      var reg = /web/ig;
      console.log(reg);
      
    2. 构造函数 var reg = new RegExp(‘规则字符串’, ‘修饰符’);

      var reg1 = new RegExp('web', 'ig');
      console.log(reg1);
      
    修饰符
    1. i: ignore case 忽略大小写情况

    2. g: global 全局匹配

      var str = 'web123WEB456web789web000';
      var reg = /web/gi;
      var s = str.replace(reg, 'python');
      console.log(s);
      
    字符串方法
    1. 字符串.replace(正则, 新字符); 返回新字符串, 原字符串不改变

      var str = 'web123WEB456web789web000';
      var reg = /web/gi;
      var s = str.replace(reg, 'python');
      console.log(s);
      
    2. 字符串.split(正则); 返回新数组

      var str = 'web123Web456web789web000';
      var reg = /web/gi;
      var arr = str.split(reg);
      console.log(arr)
      
    3. 字符串.match(正则); 挑选符合条件的字符,组成新的数组后返回回来

      var reg = /\d/ig; // 匹配数字
      var arr2 = str.match(reg);
      console.log(arr2);
      
    4. 字符串.search(正则); 从下标为0的位置开始匹配,匹配到符合正则的字符后就返回下标

      console.log(str.search(reg));
      console.log(str.search(reg));
      
      
检索方法
  1. exec: 正则.exec(要匹配的字符串); 每次会返回符合条件的字符组成的数组

  2. test: 正则.test(要匹配符的字符串); 返回是否匹配成功, 匹配成功返回true, 失败返回false

  3. 如果不加修饰符g,每次都是从0开始查找或者匹配, 如果加了g, 表示从上一次匹配到的位置的下一位开始匹配, 匹配结果返回null或者false之后,下一次匹配从0 开始重新匹配

  4. reg.lastIndex 获取到当前开始匹配正则的位置

    var str = 'web123web456';
    var reg = /\d\d\d/g;
    
    console.log(reg.lastIndex); // 0
    console.log(reg.exec(str)); // ["1", index: 3, input: "web123web456", groups: undefined]
    console.log(reg.lastIndex); // 4
    console.log(reg.exec(str)); // 2
    console.log(reg.lastIndex); // 5
    console.log(reg.exec(str)); // 3
    
    // console.log(reg.lastIndex); // 0
    // console.log(reg.test(str)); // true
    // console.log(reg.lastIndex); // 6
    // console.log(reg.test(str)); // true
    // console.log(reg.lastIndex); // 12
    // console.log(reg.test(str)); // false
    // console.log(reg.lastIndex); // 0
    // console.log(reg.test(str)); // true
    
元字符
  1. 点. : 匹配除换行以外的所有字符

    var str = '\n 123';
    var reg = /./;
    console.log(reg.exec(str));
    
  2. []: 字符集, 要匹配的字符的字符集合, 在字符集中不需要加,分隔,也不需要加引号 [^]: 字符集, 不要匹配的字符的字符集合

    var str = 'web123web456';
    var reg = /[413]/ig;
    console.log(reg.exec(str)); // 1
    console.log(reg.exec(str)); // 3
    
    var reg = /[^w43]/ig; // 不匹配w43
    console.log(reg.exec(str)); // e
    console.log(reg.exec(str)); // b
    
  3. \d: 匹配数字 在字符集中 0-9==\d \D:匹配非数字

    var str = 'web123';
    var reg = /\d\d\d/ig;
    console.log(reg.exec(str)); // 123
    var reg = /\D/ig;
    console.log(reg.exec(str)); // w
    
    // 银行卡密码 6位数字
    var reg = /\d\d\d\d\d\d/;
    var str = 'a12345';
    console.log(reg.test(str));
    
  4. \s: 匹配空格 \S: 匹配非空格

    var str = 'web 123';
    var reg = /\s/ig;
    console.log(reg.exec(str)); // 3
    var reg = /\S/ig;
    console.log(reg.exec(str)); // 0
    
  5. \w: 匹配数字、字母、_ \W: 匹配非数字、字母、_

    var str = '_w1.23*';
    var reg = /\w/ig;
    console.log(reg.exec(str)); // _
    var reg = /\W/ig;
    console.log(reg.exec(str)); // .
    
  6. \b: 匹配单词边界 \B: 匹配非单词边界

    var str = 'you are a beautiful boy';
    var reg = /\ba/ig; // 匹配a左边是边界的a
    console.log(reg.exec(str)); // 4
    var reg = /a\B/ig; // 匹配a右边不是单词边界
    console.log(reg.exec(str)); // 4
    
  7. ^: 以什么为开头 $: 以什么为结尾

    var str = '912345';
    var reg = /^\d\d\d\d\d\d$/;
    // console.log(reg.test(str)); 
    console.log(reg.exec(str)); 
    
多个字符
  1. a?: 表示一个或0个

    var str = '1web123';
    var reg = /\d?/ig;
    console.log(reg.exec(str));
    
  2. a*: 表示匹配0个或者连续的多个字符,尽可能多的去匹配

    var str = '123456web33333';
    var reg = /\d*/;
    console.log(reg.exec(str));
    
  3. a+: 表示匹配至少一个以上的连续的字符,尽可能多的去匹配

    var str = 'webweb3444';
    var reg = /\d+/;
    console.log(reg.exec(str));
    
  4. a{n,m}: 表示至少匹配n次,最多匹配m次

    • a{n}: 表示只匹配n次

      var str = 'web1234567890';
      var reg = /\d{3}/;
      console.log(reg.exec(str)); // 123
      
    • a{n,}: 至少匹配n次

      var reg = /\d{3,}/;
      console.log(reg.exec(str)); // 1234567890
      
    • a{n,m}: 表示至少匹配n次,最多匹配m次

      var reg = /^web\d{3,6}/;
      console.log(reg.exec(str)); // web123456
      
其他字符
  1. |: 或

  2. (): 分组 获取分组的匹配值: RegExp.$1 RegExp.$2

    var str = 'web1zweb2web3';
    var reg = /web(1|5)(w|z)/;
    console.log(reg.exec(str)); // web1
    console.log(RegExp.$1);
    console.log(RegExp.$2);
    
  3. (?😃: 非获取匹配

    var reg = /web(?:5|2)/; // web后面是5或者是2的web
    console.log(reg.exec(str));
    
  4. (?=): 正向肯定预查

    var str = 'web123webdffff';
    var reg = /web(?=\d+)/; // web后面必须跟数字
    console.log(reg.exec(str));
    
  5. (?!): 正向否定预查

    var reg = /web(?!\d+)/; // web后面不跟数字的
    console.log(reg.exec(str));
    
  6. (?<=): 反向肯定预查

    var reg = /(?<=\d+)web/; // web的前面是跟数字的web
    console.log(reg.exec(str)); // 6
    
  7. (?<!): 反向否定预查

    var reg = /(?<!\d+)web/;
    console.log(reg.exec(str)); // 0
    
    // 不能全是数字的组合
    var str = '124456';
    var reg = /(?!^\d+$)^[0-9a-zA-Z]+$/;
    console.log(reg.test(str)); // false
    
    // 必须是数字和字母的组合 不能全是数字、不能全是字母
    var reg = /(?!^\d+$)(?!^[a-zA-Z]+$)^[0-9a-zA-Z]+$/;
    var str = '1223a3344';
    console.log(reg.test(str)); // false
    

闭包

匿名函数
  1. 普通函数 function 函数名(){}

  2. 事件处理函数 元素.onclick = function(){}

  3. 构造函数: function Create(){}

  4. 表达式函数 var 变量名 = function(){}

  5. 匿名函数: 没有名字的函数 function (){}

    (function (){
        alert(1);
    });
    
立即执行函数

立即执行函数: IIFE函数 Imdiately Invoked Function Expression

// (function(){
//     alert(1);
// })();

// (function(){
//     alert(2);
// }());
  1. 有参数 形参: function后面的() 实参: 调用的()

    (function(a, b){
        console.log(a,b);
    }(20, 30));
    
  2. 有返回值

    var sum = (function(a, b){
        return a*b;
    })(40, 50);
    console.log(sum);
    
闭包

闭包: 就是可以访问其他函数内部变量的函数(函数里面套函数, 内部函数访问外部函数的变量), 闭包本质上是将函数内外连接起来的桥梁

作用:解决全局i带来的影响 可以模拟私有变量

var sn = (function (){
    var s = 10;
    return function (){
        s++;
        console.log(s);
    }
})();
console.log(sn); // return 后面的函数
sn(); // 11
sn(); // 12

function a(){
    var m = 10;
    return function(){
        console.log(m++);
    }
}
// var mn = a();
// console.log(mn); // return 后面的function
// mn(); // 10
// mn(); // 11
// mn(); // 12

a()(); // 10
a()(); // 10
a()(); // 10

day 16

AJAX

ajax: asynchronous javascript and xml 异步交互设计 用于创建快速交互式网页, 通过和后台少量的数据交换, 可以使网页实现异步更新

同步: 当请求发生的时候, 如果请求没有结束, 后面所有的内容都不执行

异步: 当请求发生的时候, 请求没有完成的时候,后面的内容不需要等待直接执行

创建ajax
  1. 创建ajax对象 var ajax = new XMLHttpRequest();

  2. 建立连接 ajax.open(请求方式, 请求地址+请求数据, 是否异步); ajax.open(‘get’, ‘a.txt’, true);

  3. 发送请求: ajax.send();

  4. 监听: onreadystatechange

    var ajax = new XMLHttpRequest();
    console.log(ajax);
    
    ajax.open('get', 'a.txt', true);
    
    ajax.send();
    
    ajax.onreadystatechange = function(){
        console.log(ajax.readyState);
        if(ajax.readyState == 4 && ajax.status == 200){
            console.log(ajax.response);
        }
    }
    
readyState

0–创建了ajax对象 1—建立连接 2----发送请求 3—请求发送成功 4–请求处理完成

status

​ 网络状态码:

​ 1XX: 消息系列

​ 2XX: 成功 200

​ 3XX: 重定向 300 304

​ 4XX: 页面错误 400 404 405

​ 5XX: 服务器错误

post

​ 1. 创建ajax对象

​ 2. 建立连接 ajax.open(请求方式, 请求地址, 是否异步);

​ 请求方式: get post

​ 是否异步: async: true–异步 false–同步

​ 请求地址: 相对于引入了js的html文件来做的

​ 3. 设置头请求: ajax.setRequestHeader(‘Content-type’, ‘application/x-www-form-urlencoded;charset=utf-8’);

​ 4. 发送请求: ajax.send(请求数据);

​ 请求数据: a=1&b=2

  1. 监听: onreadystatechange

    var ajax = new XMLHttpRequest();
    console.log(ajax);
    
    ajax.open('post', 'b.txt', true);
    
    ajax.setRequestHeader('Content-type', 'application/x-www-form-urlencoded;charset=utf-8');
    
    ajax.send('a=1&b=3');
    
    ajax.onreadystatechange = function(){
        console.log(ajax.readyState);
        if(ajax.readyState == 4 && ajax.status == 200){
            console.log(ajax.response);
        }
    }
    
Content-type:

​ application/x-www-form-urlencoded 表单

​ text/plain: 文本

​ multipart/form-data: 上传文件的时候

转换数据方式
  1. 将字符串计算: eval(要转的数据)

    console.log(eval('3+2')); 
    // 在js中{}中的默认就是完整的代码块
    console.log(eval('(' + res + ')'));
    
  2. 转成js数据: JSON.parse(要转换的数据)

    console.log(JSON.parse(res));
    
  3. 转成json数据: JSON.stringify(要转换的数据)

    var r = JSON.parse(res);
    console.log(JSON.stringify(r));
    
  4. json数据的格式:

    • [] {} 常用数组和对象
    • 所有的属性名和字符全部加上双引号
    • 多余的符号不要加
    • 文件名以.json结尾

Ajax封装

function ajax(json) {
     // console.log(json.success);
     json.type = json.type ? json.type : 'get';
     json.async = json.async == false ? false : true;
     json.contentType = json.contentType ? json.contentType : 'application/x-www-form-urlencoded';
     json.data = json.data ? json.data : '';
     var ajax = new XMLHttpRequest();
     // 判断是get还是post请求
     if (json.type.toLowerCase() == 'post') {
        ajax.open('post', json.url, json.async);
        ajax.setRequestHeader('Content-type', json.contentType + ';charset=utf-8');
        ajax.send(json.data);
      } else {
        ajax.open('get', json.url + '?' + json.data, json.async);
        ajax.send();
      }
      ajax.onreadystatechange = function () {
          if (ajax.readyState == 4 && ajax.status == 200) {
              json.success(ajax.response);
           }
      }
  }

面试题

// 1. 有这样一个url:http://item.taobo.com/item.html?a=1&b=2&c=&d=xxx&e, 请写一段js程序提取url中各个get参数(参数名和参数个数不确定),将其key-value形式返回到一个json结构中,如{a:“1”,b:“2”,c:“”,d:“xxx”,e:undefined}
var str = 'http://item.taobo.com/item.html?a=1&b=2&c=&d=xxx&e';
var arr = str.split('?')[1].split('&');
console.log(arr);
var obj = {};
for (var i = 0; i < arr.length; i++) {
    console.log(arr[i]);
    var objArr = arr[i].split('=');
    console.log(objArr);
    obj[objArr[0]] = objArr[1];
}
console.log(obj);
// 2. 把下面的字符串去重,并去除掉特殊字符按照数字在前字母在后的顺序排序字符串下:“1233fddfd&3434fdsaff&454545&4545444rfdsfds&545gdsgs”
var str = '1233fddfd&3434fdsaff&454545&4545444rfdsfds&545gdsgs';
var newStr = '';
for (var i = 0; i < str.length; i++) {
// 判断newStr中有没有当前字符,如果有,不添加,如果没有,添加
if (newStr.indexOf(str[i]) == -1) {
     newStr += str[i];
    }
  }
   console.log(newStr); // 123fd&4sa5rg
   var numStr = '',
   codeStr = '';
   for (var j = 0; j < newStr.length; j++) {
     // a----97 z---122
     if (isNaN(Number(newStr[j]))) {
       // 不是数字 
       if (newStr.charCodeAt(j) >= 97 && newStr.charCodeAt(j) <= 122) {
         codeStr += newStr[j]
       }
     } else {
      // 是数字
       numStr += newStr[j];
      }
    }
   console.log(codeStr, numStr);
    console.log(numStr + codeStr);

day 20

移动端事件

常用事件

注意:所有的移动端事件都用事件监听的方式添加

  1. touchstart: 在手指按下的时候触发

    div.addEventListener('touchstart', function (ev) {
        console.log(ev); // TouchEvent 
    });
    
  2. touchmove: 在手指移动的时候触发

    div.addEventListener('touchmove', function () {
        console.log(3);
    });
    
  3. touchend: 在手指抬起的时候触发

    div.addEventListener('touchend', function () {
        console.log(4);
    });
    
事件对象

事件处理函数的第一个参数

div.addEventListener('touchstart', function (ev) {
    console.log(ev); // TouchEvent 
    console.log(ev.touches); // 当前屏幕上的所有的手指列表
    console.log(ev.changedTouches); // 触发事件的手指列表
    console.log(ev.targetTouches); // 在触发源上的手指列表

    var touch = ev.changedTouches[0]; // 取出触发事件的手指
    console.log(touch);
    console.log(touch.identifier); // 标识
    console.log(touch.target); // 目标源
    console.log(touch.screenX, touch.screenY); // 距离屏幕左上角的距离
    console.log(touch.clientX, touch.clientY); // 距离屏幕可视区域的左上角距离
    console.log(touch.pageX, touch.pageY); // 距离页面左上角的距离
    console.log(touch.radiusX, touch.radiusY); // 圆的半径
    console.log(touch.force); // 压力值大小
    console.log(touch.rotationAngle); // 旋转角度
});

day 21

jQuery

关于jQuery

jQuery是一个优秀的JavaScript库,强调的理念是写得少,做得多(write less, do more)

jQuery的优势

● 轻量级。

● 强大的选择器。

● 出色的DOM操作的封装。

● 可靠的事件处理机制。

● 完善的ajax。

● 不污染顶级变量。

● 出色的浏览器兼容性。

Jq: 1版本兼容ie 2版本及以上就不兼容ie了

● 链式操作方式。

● 隐式迭代。

● 行为层和结构层分离。

● 丰富的插件支持。

● 完善的文档。

● 开源。

jQuery的版本区别
  1. jquery.js: 未压缩版本 学习

    jquery.min.js: 压缩版本 工作开发

  2. 1xx版本: 兼容ie

    2xx版本以上: 不兼容ie

$与jQuery的关系

$ 相当于jquery的别名

console.log(jQuery == window.jQuery);
console.log($ == window.$);
console.log(jQuery == $);
$.ready
  1. 等待页面加载完成后执行代码

    $(document).ready(function(){
        console.log(4);
    });
    
  2. 与window.onload的区别

    • window.onload: 等待页面及资源加载完成后再去执行, 写多个的时候,后面的会覆盖前面的

    • ready:等待页面结构加载完成, 后面的不会覆盖前面的, 会叠加执行, 有简写模式

      window.onload = function(){
          console.log(1);
      }
      window.onload = function(){
          console.log(3);
      }
      
      $(document).ready(function(){
          console.log(4);
      });
      
      $(document).ready(function(){
          console.log(5);
      });
      
      $().ready(function(){
          console.log(6);
      });
      
      $(function(){
          console.log(7);
      });
      
对象互转
  1. 为什么要互转

    jquery方法只能给jquery对象用 js的方法只能给js对象用

    lis[0].style.background = 'red';
    console.log(lis[0]);
    
  2. jquery对象转成js对象

    • jquery对象[下标]

    • jquery对象.get(下标);

      // jquery对象[下标]
      console.log(lis1[0]);
      // jquery对象.get(下标);
      console.log(lis1.get(0));
      
  3. js对象转成jquery对象

    • $(js对象)

      var li = lis[0];
      console.log(li);
      // js对象转成jquery对象  $(js对象)
      console.log($(li)); // jQuery.fn.init [li]
      
  4. 获取指定下标的jquery对象

    console.log(lis1.eq(0));
    
冲突解决
jQuery.noConflict(); // 将$的控制权交给其他的库
(function($){
    console.log($, '1---');
})(jQuery);

选择器

基本选择器
  1. 标签: $(‘标签名’)

  2. 类名: $(’.类名’)

  3. id: $(’#id’)

  4. 组合: $(‘标签名, .class, #id’)

    $('li').css('background', 'red');
    // 隐式迭代: 在设置的时候,会遍历所有符合条件的元素,然后设置上样式或者方法
    $('.a').css('background', 'blue');
    $('#box').css('background', 'orange');
    $('.a, .b, .c').css('background', 'pink');
    
层级选择器
后代选择器: $(‘父元素 子元素’)$(‘ul li’).css(‘background’, ‘pink’);
直接子元素选择器: $(‘父元素>子元素’)$(‘ul>li’).css(‘background’, ‘green’);
紧邻下一个: $(‘元素+兄弟元素’)$(‘li+span’).css(‘background’, ‘orange’);
后面兄弟: $(‘元素~兄弟’)$(‘li~span’).css(‘background’, ‘blue’);
过滤选择器
基本过滤选择器
选择器实例
选择第一个li$(‘li:first’).css(‘background’, ‘red’);
选择最后一个li$(‘li:last’).css(‘background’, ‘red’);
类名不为box的li$(‘li:not(.box)’).css(‘background’, ‘red’);
下标为偶数的时候$(‘li:even’).css(‘background’, ‘green’);
下标为奇数的时候$(‘li:odd’).css(‘background’, ‘blue’);
下标为5的li$(‘li:eq(5)’).css(‘background’, ‘pink’);
下标小于5的li$(‘li:lt(5)’).css(‘background’, ‘red’);
下标大于5的li$(‘li:gt(5)’).css(‘background’, ‘orange’);
属性过滤选择器
选择器实例
获取有id属性的元素$(‘li[id]’).css(‘background’, ‘red’);
类名值为b的元素$(‘li[class=b]’).css(‘background’, ‘red’);
类名不等于b的元素$(‘li[class!=b]’).css(‘background’, ‘#f000dd’);
类名以a为开头的元素$(‘li[class^=a]’).css(‘background’, ‘#f0df55’);
类名以b为结尾的元素 ( ′ l i [ c l a s s ('li[class (li[class=b]’).css(‘background’, ‘#0f0eee’);
类名中包含b的元素$(‘li[class*=b]’).css(‘background’, ‘#876f0a’);
表单过滤选择器
选择器实例
获取被选中的表单元素console.log($(’:checked’));
获取所有的input类表单console.log($(’:input’));
所有的文本输入框console.log($(’:text’));
所有的密码输入框console.log($(’:password’));
所有的单选按钮console.log($(’:radio’));
所有的复选按钮console.log($(’:checkbox’));
获取所有的按钮console.log($(’:button’));
获取重置的按钮console.log($(’:reset’));
获取提交的按钮console.log($(’:submit’));
获取图片按钮console.log($(’:image’));
获取文本域console.log($(‘textarea’));
遍历节点

以下所有的方法均可以接收一个选择器作为筛选条件

选择器实例
获取ul中所有的子节点(直接)console.log($(‘ul.a’).children());
获取ul中所有的子节点(直接)中的div节点console.log($(‘ul.a’).children(‘div’));
紧邻的下一个节点$(’.box’).next().css(‘background’, ‘red’);
紧邻的下一个liconsole.log($(’.box’).next(‘li’));
获取后面所有的兄弟节点console.log($(’.box’).nextAll());
获取后面所有的兄弟节点中的ulconsole.log($(’.box’).nextAll(‘ul’));
紧邻的上一个节点console.log($(’.box’).prev());
前面所有的兄弟节点console.log($(’.box’).prevAll());
所有的兄弟节点console.log($(’.box’).prevAll(’.b’));
直接父元素console.log($(‘span’).parent());
获取所有的父元素console.log($(‘span’).parents());
获取父节点中的liconsole.log($(‘span’).parents(‘li’));
过滤节点
选择器实例
从父节点ul中查找子节点li$(‘ul’).find(‘li’).css(‘background’, ‘#091fff’);
从所有的li中挑选出类名为box的元素$(‘li’).filter(’.box’).css(‘background’, ‘pink’);
从所有的li中挑选出类名不为box的元素$(‘li’).not(’.box’).css(‘background’, ‘red’);

链式调用

  1. 原理: 每次会将使用的jquery对象或者是处理以后的jquery对象返回回来

    var a = $('ul').find('li').css('background', '#091fff');
    console.log(a);
    a.css('background', 'green');
    

操作属性

  1. attr

    1. jq对象.attr(‘属性名’, [‘属性值’]); 没有属性值时,为获取值, 获取第一个的值; 有属性值时,为设置, 遍历设置(隐式迭代)

      var a = $('div').attr('id');
      console.log(a);
      $('div').attr('id', 'b2);
      
  2. prop

    1. jq对象.prop(‘属性名’, [‘属性值’]); 没有属性值时,为获取值, 获取第一个的值; 有属性值时,为设置, 遍历设置(隐式迭代)

      console.log($(':radio').prop('checked')); // false
      
  3. 区别:

    1. 固有属性使用prop,prop不能设置操作自定义属性, attr可以

    2. 如果设置属性名就起作用的情况下就用prop, 表单类操作使用prop

      console.log($(':radio').attr('checked')); // undefined
      console.log($(':radio').prop('checked')); // false
      
      console.log($('.a').attr('tag', '1234'));
      console.log($('.a').prop('tag1', '1234'));
      

操作类名class

  1. 添加类名: jq对象.addClass(要添加的类名)

    $('.a').addClass('b c');
    
  2. 删除: jq对象.removeClass(要删除的类名)

    $('button').click(function(){
        $('div').removeClass('a b');
    });
    
  3. 有就删除没有就添加: jq对象.toggleClass(要操作的类名)

    $('button').click(function(){
        $('div').toggleClass('a b');
    });
    
  4. 是否有某个类名: jq对象.hasClass(要判断的类名) 返回true–false(true代表有,false代表没有)

    $('button').click(function(){
        // $('div').removeClass('a b');
        $('div').toggleClass('a b');
        console.log($('div').hasClass('a'));
    });
    
  5. 判断当前的元素是不是某个选择器: jq对象.is(‘选择器’) true–是,false-不是

    $('button').click(function(){
        // $('div').removeClass('a b');
        $('div').toggleClass('a b');
        console.log($('div').hasClass('a'));
        console.log($('div').is('.a'));
    });
    

操作样式

jq对象.css(‘属性名’, ‘属性值’);

  1. 获取: jq对象.css(‘属性名’);

  2. 设置: jq对象.css(‘属性名’, ‘属性值’);

  3. 设置: jq对象.css({

    ​ ‘属性名’: ‘属性值’,

    ​ ‘属性名1’: ‘属性值1’

    ​ });

  4. 注意: 加引号时,连字符可以不转驼峰命名法,不加引号,必转驼峰命名法 直接写数值会自动加上单位

    console.log($('div').css('width'));
    console.log($('div').css('height'));
    console.log($('div').css('background'));
    
    // $('div').css('width', '200px');
    // $('div').css('height', 200);
    // $('div').css('background', 'red');
    // $('div').css('fontSize', 30);
    
    $('div').css({
        'width': 200,
        'height': 200,
        'fontSize': 50
    });
    

操作内容

html

取值: jq对象.html();

设置: jq对象.html(要设置的内容)

获取第一个选择器标签的内容,设置的时候遍历设置, 后面的会覆盖前面的, 可以识别标签

console.log($('div').html()); // 获取第一个
$('div').html('这是新设置的内容'); // 设置的时候遍历设置, 后面的会覆盖前面的, 可以识别标签
$('div').html('这是新新新的内容');
$('div').html('<em>这是新新新的内容</em>');
text

取值: jq对象.text();

设置: jq对象.text(要设置的内容)

获取所有符合选择器的内容, 遍历设置, 后面的会覆盖前面的, 不能识别标签

console.log($('div').text()); // 获取所有符合选择器的内容
console.log($('div').text('这是一个文本内容')); // 遍历设置, 后面的会覆盖前面的, 不能识别标签
$('div').text('这是最新的文本内容');
$('div').text('<em>这是最新的文本内容</em>');
value
  1. 获取表单的值: jq对象.val(); 获取第一个

    console.log($(':input').val());
    
  2. 设置表单的值: jq对象.val(要设置的值); 遍历设置

    $(':text').val('这是新的文本内容');
    
  3. 设置单选框: jq对象.val([要设置的值])

    console.log($(':radio').val());
    $(':radio').val(['man']);
    
  4. 设置复选框: jq对象.val([要设置的值, 要设置的值2])

    $(':checkbox').val(['LOL', 'DNF']);
    
  5. 获取、设置select的值

    console.log($('select').val());
    $('select').val('Chengdu');
    

循环

each

$.each(要遍历的对象, callback);

$.each(要遍历的对象, function(index, value){}); index–下标 value-值

  1. 遍历数组

    var arr = [1,2,3,4,5,6,7];
    var b = $.each(arr, function(index, value){
        console.log(index, value);
        return value * value;
    });
    
  2. 遍历集合

    $.each($('li'), function(index, value){
        console.log(index, value);
        $(value).click(function(){
            console.log(this, index);
        });
    });
    
  3. 遍历对象

    var obj = {
        'name': '彭于晏',
        'height': 180,
        'weight': 150
    };
    // $.each(要遍历的对象, function(key, value){}); key--键 value-值
    var a = $.each(obj, function(key, val){
        console.log(key, val);
        return key + 1;
    });
    console.log(a);
    console.log(b);
    

    注意: each: 没有返回值, 没有办法通过return设置返回值

day 22

元素宽高

获取元素宽高
  1. jq对象.width(): 元素的宽 内容

  2. jq对象.height(): 元素的高 内容

  3. jq对象.position(); 元素的距离具有定位属性的父元素的距离, 如果没有定位属性的父元素, 就是距离body的距离

    console.log($('div').css('width'));
    console.log($('div').width());
    console.log($('div').height());
    console.log($('div').position()); // {top: 0, left: 8}
    console.log($('div').position().left);
    
client系列

client: width + padding

  1. innerWidth/ innerHeight(): 可视宽高

  2. $(window).innerWidth(): 屏幕可视宽

  3. $(document).innerWidth(): 页面的可视宽高

    console.log($('div').innerWidth()); // 240
    console.log($(window).innerWidth());
    console.log($(document).innerHeight());
    
offset系列

offset: width + padding + border

  1. outerWidth/Height(boolean): 元素的占位宽高

    默认值是false, 如果设置成true: 表示计算margin

  2. jq对象.offset(): 获取距离body的距离

    console.log($('div').outerWidth()); // 255
    console.log($('div').outerWidth(false)); // 255 
    console.log($('div').outerWidth(true)); // 295
    console.log($('div').offset());
    console.log($('div').offset().left);
    
scroll系列
  1. $(window).scrollTop(); 获取页面的滚动距离

    $(window).scroll(function(){
        console.log($(window).scrollTop());
    });
    
设置
$('div').width(300);
$('div').innerHeight(400); // height + padding
$('div').outerWidth(500); // width + padding + border
$('div').outerWidth(500, true); // width + paading + border + margin

$('button').click(function(){
    $(window).scrollTop(0);
});

DOM

创建节点

var 变量 = $(’

  • ’);

    var li = $('<li>12345</li>');
    console.log(li);
    
    添加节点
    1. 追加到父元素中

      $(父).append(子);

      $(子).appendTo(父);

      注意: 如果追加一个已存在的节点(已经在页面中渲染的), 会发生物理位移;

      // $('ul').append(li);
      // li.appendTo($('ul'));
      li.appendTo('ul');
      // li.appendTo('div');
      
    2. 添加到父元素的头部

      $(父).prepend(子);

      $(子).prependTo(父);

      var li1 = $('<li>这是一个新的</li>');
      // $('ul').prepend(li1);
      li1.prependTo('ul');
      
    3. 添加到某个元素之前

      $(参考节点).before(新节点);

      $(新节点).insertBefore(参考节点);

      var li2 = $('<li>这是中简元素</li>');
      // $('ul li:eq(3)').before(li2);
      li2.insertBefore('ul li:eq(3)');
      
    4. 添加到某个元素之后:

      $(参考节点).after(新节点);

      $(新节点).insertAfter(参考节点);

      var li3 = $('<li>这是节点之后的节点</li>');
      // $('ul li:eq(2)').after(li3);
      li3.insertAfter('ul li:eq(2)');
      
    删除节点
    1. remove(); 删除自身及子元素,返回被删除的元素,方便下次使用 不保存原来的行为

    2. detach(); 删除自身及子元素,返回被删除的元素,方便下次使用 保存原来的行为

    3. empty(); 清空子节点

      $('button').click(function(){
          var m = $('li').eq(0).remove();
          console.log(m);
          m.appendTo('ul');
      
          var b = $('li').eq(1).detach();
          console.log(b);
          b.appendTo('ul');
      
          $('ul').empty();
      });
      
    克隆节点

    jq对象.clone(boolean); 返回克隆的节点

    不传/false的时候,不克隆行为 传true表示克隆之前的行为

    $('li').click(function(){
        $(this).css({'background': 'red'});
    });
    var m = $('li:eq(0)').clone();
    console.log(m);
    m.appendTo('ul');
    
    var b = $('li:eq(1)').clone(true);
    console.log(b);
    b.appendTo('ul');
    
    替换节点
    1. $(参考节点).replaceWith(新节点);

    2. $(新节点).replaceAll(参考节点);

      var li = $('<li>12132</li>');
      // $('li').replaceWith(li);
      li.replaceAll('li');
      

    事件对象

    1. 事件对象以事件处理函数的第一个参数存在

    2. 常用属性:

      $('div').click(function(ev){
          console.log(ev); // jQuery.Event  jq的事件对象
          console.log(ev.originalEvent); // 原生的事件对象
          console.log(ev.pageX,ev.pageY);  // 鼠标相对于页面的距离
          console.log(ev.clientX, ev.clientY); // 鼠标距离可视区域的距离
          console.log(ev.screenX, ev.screenY); // 鼠标相对于屏幕的距离
          console.log(ev.offsetX, ev.offsetY); // 鼠标相对于触发元素左上角的距离   点击边框会出现负值
          console.log(ev.which); // 相当于是keyCode, 比keyCode更强大, 保存了鼠标的键, 123(左中右)
          console.log(ev.target); // 事件的触发源
          console.log(ev.delegateTarget); // 事件的绑定对象
          console.log(ev.type); // 事件类型
          console.log(ev.ctrlKey, ev.shiftKey, ev.altKey); // 相对应的键是否被按下
      
          // 阻止冒泡: ev.stopPropagation ? ev.stopPropagation() : ev.cancelBubble = true;
          ev.stopPropagation(); // 阻止冒泡
          // 阻止默认事件: ev.preventDefault ? ev.preventDefault() : ev.returnValue = false;
          ev.preventDefault(); // 阻止默认事件
          return false; // 阻止冒泡+默认事件
      });
      
    事件绑定与移除
    1. on: jq对象.on();

      1. 给同一个事件添加不同的处理函数

        function f1(){
            alert(1);
        }
        function f2(){
            console.log(2);
        }
        // $('div').on('click', f1);
        // $('div').on('click', f2);
        
      2. 给不同的事件添加同一个处理函数

        $('div').on('click mouseover', f2);
        
      3. 给不同的事件添加不同的处理函数

        $('div').on({
            'click': f1,
            'mouseover': f2,
            'mouseout': function(){
                console.log(3);
            }
        });
        
      4. 添加自定义事件

        $('div').on({
            'eat': function(){
                console.log('你吃饱了吗?');
            }
        });
        
        $('button').click(function(){
            $('div').trigger('eat'); // 触发自定义事件
        });
        
      5. 事件委托

        $(父).on(事件类型, 子元素, 事件处理函数)

        $('ul').on('click', 'li,div', function(){
            console.log(this);
            $(this).css('background', 'red');
        });
        
      6. 命名空间

        $('ul').on('click.a', function(){
            console.log(123);
        });
        
        $('ul').on('click', function(){
            console.log(1);
        });
        
    2. 事件移除

      jq对象.off(事件类型, 事件处理函数);

      $('ul').on('click.a', function(){
          console.log(123);
      });
      
      $('ul').on('click', function(){
          console.log(1);
      });
      
      function f1(){
          console.log(3);
      }
      $('ul').on('click', f1);
      
      // removeEventListener detachEvent
      // $('ul').off('click'); // 移除所有的点击事件
      // $('ul').off('click.a'); // 移除click下的a处理函数
      $('ul').off('click', f1); // 移除点击下的f1处理函数
      
    3. 一次性事件 one

      one与on的用法完全一致, one是一次性事件

      $('ul').one('click', function(){
          console.log(1);
      });
      
      $('ul').on('click', function(){
          console.log(2);
          $('ul').off('click');
      });
      
    4. 合成事件

      $().hover(滑入事件, 滑出事件);

      注意: 如果只写一个函数表示滑入滑出同一个处理函数,避免这么写

      $('div').hover(function(){
          console.log(1);
      }, function(){
          console.log(2);
      });
      

    深浅拷贝

    1. 浅拷贝 $.extend(dest, src1, src2…) dest:要拷贝的对象 src: 被拷贝的数据 会改变拷贝对象

      浅拷贝: 在拷贝的时候,如果属性名重复,那么就用后面的覆盖前面的

      var obj = {
          a: {
              e:1
          },
          b: 2
      };
      var obj1 = {
          b:3,
          e: 'f'
      };
      var obj2 = {
          c: 3
      };
      // var m = $.extend(obj, obj1, obj2);
      // console.log(obj);
      // console.log(m);
      
      var n = $.extend({}, obj, obj1, obj2);
      console.log(n); // 不改变原数据
      
    2. 深拷贝: $.extend(true, dest, src1, src2, …) dest:要拷贝的对象 src: 被拷贝的数据 会改变拷贝对象

      深拷贝:第一个参数设置为true的时候,进行深拷贝(递归拷贝), 如果属性名重复并且是对象, 对比下一层级的属性,如果属性名相同就用后面的覆盖前面的,如果还是对象,继续对比下一层级.

      var mn = $.extend(true, {}, obj, obj1, obj2);
      console.log(mn);
      

    day 23

    动画

    show hide toggle
    1. show hide toggle: width + height + opacity

    2. 没有参数的时候, 没有动态效果

    3. 语法:show(speed, easing, callback);

      speed: 时间 ms

      easing: 运动曲线 linear swing

      callback: 动画执行结束之后的回调函数

      $('button').click(function(){
          // $('div:eq(0)').show(10000, 'linear', function(){
          //     console.log(1);
          // });
          // $('div:eq(1)').show(10000, 'swing', function(){
          //     console.log(2);
          // });
      
          // $('div:eq(0)').hide(10000, 'linear', function(){
          //     console.log(1);
          // });
          // $('div:eq(1)').hide(10000, 'swing', function(){
          //     console.log(2);
          // });
      
          $('div:eq(0)').toggle(1000);
          $('div:eq(1)').toggle(1000);
      });
      
    fade系列
    1. fadeIn fadeOut fadeToggle: speed, easing, callback

      speed: 时间 ms

      easing: 运动曲线 linear swing

      callback: 动画执行结束之后的回调函数

    2. fadeTo: jq.fadeTo(speed, to透明度, easing, callback)

      $('button').click(function(){
          // $('div').eq(0).fadeOut(5000, 'linear', function(){
          //     console.log(1);
          // });
          // $('div').eq(1).fadeOut(5000, 'swing');
      
          // $('div').fadeIn(1000, 'linear');
      
          // $('div').fadeToggle(400);
      
          $('div').fadeTo(1000, 1);
      });
      
    slide系列

    slideDown slideUp slideToggle: height

    slideDown(speed, easing, callback);

    speed: 时间 ms

    easing: 运动曲线 linear swing

    callback: 动画执行结束之后的回调函数

    $('button').click(function(){
        // $('div').eq(0).slideDown(10000, 'linear');
        // $('div').eq(1).slideDown(10000, 'swing');
        // $('div').slideUp(1000);
        $('div').slideToggle(1000);
    });
    
    animate
    1. jquery对象.animate(动画参数, speed, easing, callback)

      动画参数: 对象 属性名: 结束值

      $('button').click(function(){
          $('div').eq(0).animate({
              // 'width': 500,
              'width': '+=100',
              'height': '500px'
          }, 2000, 'linear', function(){
              console.log(1);
          });
      });
      
    2. jquery对象.animate(动画参数, 配置参数);

      配置参数:

      ​ duration: 运动时长, ms

      ​ step: 每一步动画执行之后的回调函数

      ​ complete:动画执行完成后的回调函数

      ​ easing: 运动曲线

      ​ queue: 是否队列\

      $('button').click(function(){
          $('div').eq(0).animate({
              'width': 500,
              'height': 500
          }, {
              'duration': 400,
              'step': function(){
                  console.log(1);
              },
              'complete': function(){
                  console.log(2);
              },
              'queue': true
          }).animate({
              'width': '+=100',
              'height': '+=100'
          }, {
              'duration': 2000,
              'step': function(){
                  console.log(1);
              },
              'complete': function(){
                  console.log(2);
              },
              'queue': true
          }).animate({
              // 'width': 100,
              // 'height': 100
              'opacity': 0.1
          }, {
              'duration': 400,
              'step': function(){
                  console.log(1);
              },
              'complete': function(){
                  console.log(2);
              },
              'queue': false
          });
      });
      
    3. 动画队列

      1. 动画连缀的时候,所有的动画都会自动加入队列

      2. 写动画参数的时候,show hide toggle可以直接用

      3. .css不是动画,不会进入队列, 动画开始的时候与动画一起执行

      4. 手动设置动画队列 .queue(callback)

        • 手动加入队列之后的动画均不再执行
        • 调用回调函数中的第一个参数(函数)后面的动画继续执行
        $('button').click(function () {
            // 1. 动画连缀的时候,所有的动画都会自动加入队列
            // $('div').eq(0).animate({width: '+=100'}).animate({'height': '+=100'}).slideUp();
        
            // 2. 写动画参数的时候,show hide toggle可以直接用
            // $('div').animate({'width': 'hide'}).animate({'width': 'show'});
        
            // 3. .css不是动画,不会进入队列, 动画开始的时候与动画一起执行
            // $('div').animate({ 'width': 500, 'marginTop': 100 }, 2000).css({ 'background': '#097ff2', 'width': 1000 });
        
            // 4. 手动设置动画队列 .queue(callback)
            $('div')
                .animate({ 'width': 500, 'marginTop': 100 }, 2000)
                .queue(function (next) {
                    $(this).css({ 'background': '#097ff2', 'width': 1000 });
                    console.log(next); // 存储后面队列中动画的函数
                    next();
                })
                // 手动加入队列之后的动画均不再执行
                .animate({'height': 500});
        });
        
    是否动画

    .is(’:animated’) 判断当前是不是在动画中 true–正在动画 false–没有动画

    $('button').click(function () {
        console.log($('div').is(':animated'));
        if (!$('div').is(':animated')) {
            $('div')
                .animate({ 'width': 500, 'marginTop': 100 }, 2000)
                .queue(function (next) {
                    $(this).css({ 'background': '#097ff2', 'width': 1000 });
                    console.log(next); // 存储后面队列中动画的函数
                    next();
                })
                .animate({ 'height': 500 });
        }
    });
    
    停止动画
    1. .stop(是否清除队列, 是否到达目标值)

      清除队列: true:当前往后的所有动画都清除 false/不传: 只是停止当前动画

      到达目标值: true: 当前动画是否直接到达目标值 false/不传: 不到达目标值

      $('a').click(function(){
          $('div').stop(true, true);
      });
      
    2. .finish(): 直接将所有动画结束并且到达目标值

      $('a').click(function(){
          $('div').finish();
      });
      
    延迟动画

    .delay(时间(ms)) 让动画延迟多久之后在执行

    $('button').click(function () {
        $('div')
            .animate({ 'width': 500, 'marginTop': 100 }, 10000)
            // .queue(function (next) {
            //     $(this).css({ 'background': '#097ff2'});
            //     next();
            // })
            .delay(5000) // 让动画延迟多久之后在执行
            .animate({ 'height': 500 }, 10000);
    });
    

    ajax

    优缺点
    优点
    • 不需要任何插件支持

      Ajax 不需要任何浏览器插件,就可以被绝大多数主流浏览器所支持,用户只需要允许javascript在浏览器上即可。

    • 优秀的用户体验

      这是Ajax技术的最大的优点,能在不刷新整个页面的前提下更新数据,这使得Web应用程序能更为迅速的回应用户操作。

    • 提高web程序的性能

      与传统模式相比,Ajax模式在性能上的最大区别就在于传输数据的方式上,在传统模式中,数据提交是通过表单(form)来实现的,而数据获取是靠全页面刷新来重新获取整夜内容。Ajax模式只是通过XMLHttpRequest对象向服务器端提交希望提交的数据,即按需发送。

    • 减轻服务器和带宽的压力

      Ajax的工作原理相当于在用户和服务器之间加了一个中间层,使用户操作与服务器响应异步化。它在客户端创建Ajax引擎,把传统方式的下的一些服务器负担的工作转移到客户端,便于客户端资源来处理,减轻服务器和带宽的负担。

    缺点
    • 破坏浏览器前进,后退,按钮的正常功能

      在传统的网页中,用户经常会习惯性的使用浏览器自带的“前进”,“后退”按钮,然而Ajax改变了此Web浏览习惯。在Ajax中 前进,后退按钮都会失效。 虽然通过一定的方法(添加锚点) 来使得用户可以使用“前进”,“后退”按钮,但相对于传统方法却麻烦很多。

    • 对搜索引擎的支持不足

      对于搜索引擎也是支持Ajax的一项缺憾。通常搜索引擎都是通过爬虫程序来对互联网上的数以万计的数据来进行,对Javascript望而生畏。

    $.ajax

    $.ajax({请求参数})

    参数说明
    url请求地址
    data请求数据 字符串、对象
    type请求数据类型
    success请求成功的回调函数
    error请求失败的回调函数
    complete请求完成的回调函数
    timeout超时时间(ms)
    dataType设置请求接受的数据类型: json, xml, html, script, text , jsonp
    global是否触发全局的ajax事件
    async是否异步
    cache是否走缓存
    var obj = {
       a: 3,
       d: 4
    }
    var arr = [1,2,3];
    $.ajax({
       'url': 'a.txt',
       'data': obj,
       'type': 'get',
       'success': function(res){
           console.log(res);
       },
       'error': function(res){
           console.log(res); // ajax对象
           $('body').html(res.responseText);
       },
       'complete': function(r){
           console.log(r); // ajax对象
       },
       'timeout': 1000, // 1毫秒内没有返回值则停止请求返回超时提示
       'dataType': 'html' 
    });
    
    $.get

    $.get(url, [data], callback)

    $.get('a.txt', function(res){
        console.log(res);
    });
    
    $.post

    $.post(url, [data], callback)

    $.post('a.txt', function(r){
        console.log(r);
    });
    
    优缺点
    1. get请求, 请求参数拼接在地址后面, 长度有限制, 2kb, 如果有中文字符需要自己去进行编码, 安全级别比较低, 从后台获取数据
    2. post请求, 请求参数在http请求体, 容量是没有限制, 对外数据不可见, 安全级别比较高, 提交数据
    jsonp
    跨域

    浏览器对JavaScript的同源策略的限制,会产生跨域的问题: by CORS policy

      1. 不同服务器
         2. 同一服务器,不同端口
    
      3. 协议不同
    
    跨域解决
    function showData(res){
        console.log(res);
    }
    $('body').append('<script src="https://p.3.cn/prices/mgets?skuIds=J_5089253&type=1&callback=showData"><\/script>');
    

    jsonp: json with padding 非标准传输方式

    原理: 通过动态的向页面中添加script标签,并且将src设置成请求地址的方式,来实现跨域请求

    var url = "https://p.3.cn/prices/mgets?skuIds=J_5089253&type=1";
    function a(res){
        console.log(res);
    }
    $.ajax({
        'url': url,
        'dataType': 'jsonp',
        'success': function(res){
            console.log(res);
        },
        'jsonpCallback': 'a'
    });
    

    jsonpCallback用来接收跨域请求的回调函数, 如果没有设置jsonpCallback, 由success的函数来充当回调函数

    ajax和jsonp的关系

    ​ ajax: 核心 XMLHttpRequest 对象

    ​ jsonp: 动态的向页面中添加script标签

    数据序列化

    1. form.serialize(): name=value&name1=value1

    2. form.serializeArray(): [{name: name值, value: value值}]

      $('button').click(function(){
          var m = $('form').serialize();
          var n = $('form').serializeArray();
          console.log(m);
          console.log(n);
      });
      

    day 24

    插件拓展

    1. 插件分类

      • 对象级别插件: .css .attr
      • 类级别的插件: $.ajax $.extend $.each $.map
    2. 拓展插件

      1. 对象级别插件:

        ​ $.fn.extend({

        ​ ‘方法名’: 函数,

        ​ ‘方法名2’: 函数2

        ​ });

        // 获取父节点的第一个子节点:  1. 隐式迭代  2. 返回值
        $.fn.extend({
            'getFirst': function(){
                console.log(this);
                console.log($(this).children().eq(0));
                return $(this).children().eq(0);
            },
            'getLast': function(){
                return $(this).children().eq($(this).children().length - 1);
            }
        });
        $('ul').getFirst().css('background', 'red');
        $('ul').getLast().css('background', 'red');
        
      2. 类级别插件

        ​ $.extend({

        ​ ‘方法名’: 函数,

        ​ ‘方法名2’: 函数2

        ​ });

        // 给字符串去除左右空格
        var a = '       1234   567   ';
        console.log(a);
        $.extend({
            getTrim: function(str){
                var leftReg = /^\s*/;
                var rightReg = /\s*$/;
                console.log(str.replace(leftReg, '').replace(rightReg, ''));
                return str.replace(leftReg, '').replace(rightReg, '');
            } 
        });
        var mn = $.getTrim(a);
        console.log(mn);
        

      zepto

      zepto.js: 轻量级的jquery, 针对移动端使用的js库, 只支持ie10+, 顶级变量: $

      自带5个插件: zepto form ie ajax event

      1. zepto与jquery的区别

        • width() height:

          zepto: width + padding + border

          jquery: width

          console.log($('div').width()); // 246
          (function ($) {
             console.log($('div').width()); // 200
          })(jQuery);
          
        • 定位距离: offset()

          zepto: width height left top

          jquery: left top

          console.log($('div').offset());
          (function ($) {
              console.log($('div').offset());
          })(jQuery);
          
        • outerWidth innerWidth: 在zepto中没有

      2. zepto手势事件:

        单机: tap 双击: doubleTap

        长按: longTap(>750ms)

        滑动: (滑动距离>30px触发, 不要求全部在元素内部滑动)

        ​ swipe swipeLeft swipeRight swipeUp swipeDown

        $('div').on('tap doubleTap longTap swipe swipeLeft swipeRight swipeUp swipeDown', function(ev){
            console.log(ev.type);
        });
        
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 非常感谢您对pink老师的javascript笔记的关注。这份笔记是一份非常实用的学习资料,适合初学者和进阶者使用。它包含了javascript的基础知识、语法、常用函数和DOM操作等内容,讲解详细、易懂。如果您想学习javascript,这份笔记是一个不错的选择。 ### 回答2: Pink老师的JavaScript笔记是关于前端开发学习过程中非常优秀的资料之一。这份笔记内容包括了JavaScript的基础知识、DOM、BOM、事件、Ajax等内容,非常全面地涵盖了前端开发所需要掌握的重要知识点。 在这份笔记中,Pink老师用通俗易懂的语言,将复杂的知识点进行了详细的解释和讲解。这不仅使得初学者能够轻松理解复杂的JavaScript语言,也让已经掌握一定JavaScript知识的开发者能够更深入地了解这门语言。此外,Pink老师还分享了大量实战案例,这些案例可以帮助学生们更好地掌握和运用大量的知识点。 笔记的布局设计非常清晰,内容及其丰富,并且与今天 Web 前端开发面临的实际问题有很大的联系,因而该笔记被包括许多开发者、爱好者和专家评为学习JavaScript的最佳资料之一。 综上所述,Pink老师的JavaScript笔记是一份非常优质的前端开发学习资料,它不仅可以帮助初学者建立完备的JavaScript知识体系,也可以让已经掌握一定JavaScript知识的开发者更深入地了解这门语言。它是前端开发者不可错过的优秀资料。 ### 回答3: Pink老师的JavaScript笔记覆盖了JavaScript语言的很多方面,包括数据类型、运算符、控制流、函数、数组、对象、DOM操作、事件处理等等。这份笔记相对来说比较简单易懂,很适合初学者入门学习。 首先,笔记中详细地介绍了JavaScript的数据类型,包括字符串、数字、布尔值、null、undefined和对象。这对于初学者来说是非常重要的基础,因为在JavaScript中一切皆为对象。 接着,笔记讲解了JavaScript中的运算符,包括算术运算符、比较运算符、逻辑运算符、赋值运算符等等。这些都是编程基础,也是JavaScript编程的必备知识点。 在控制流方面,笔记详细介绍了if语句、switch语句、for循环、while循环等等,让初学者能够清楚地了解JavaScript中的控制流程。 当然,函数也是JavaScript编程中非常重要的部分。笔记中对于函数的定义、参数、返回值以及作用域等方面都有详细的介绍,还有自定义函数和匿名函数的使用。 除此之外,JavaScript中的数组和对象也是非常重要的部分。笔记中讲解了如何创建数组和对象,以及如何使用它们的属性和方法。同时,笔记中也介绍了DOM操作和事件处理,让初学者能够掌握JavaScript中最常用的操作之一。 总的来说,Pink老师的JavaScript笔记比较适合初学者学习,它详细介绍了JavaScript的基本语法和常用操作,非常有利于帮助初学者建立起一个扎实的编程基础。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值