尚硅谷JavaScript基础 笔记

目录


JS基础


1、编写位置

  • script标签内
  • onclick href 属性内
  • JS文件中
<a href="javascript: alert('hello');">你也点我一下</a>
<button onclick="javascript: alert('hello')">按钮</button>

2、基本语法

  • 严格区分大小写
  • ; 结尾
  • 会忽略多个空格和换行,利用空格和换行格式化代码

3、字面量和变量

  • 字面量
    • 一些不可改变的值,如 1 2 3 4
  • 变量
    • 可用来保存字面量,值可以改变

4、标识符命名规则

  • 可含有 字母、数字、_$
  • 不能以数字开头
  • 不能是ES关键字或保留字
  • 一般采用驼峰命名法

5、数据类型

5.1、五大基本类型

  • stringnumberbooleannullundefined

5.2、引用类型

  • object
  • 只要不是上述五大基本类型则均为 object 类型

5.3、nullundefined 区别

  • null 空对象,一个为空的对象
  • undefined 未定义,声明一个变量没有赋值或对象中的属性不存在

6、类型转换

6.1、转 string

  • .toString()
  • String()
var a = null;
console.log(a.toString()); // Uncaught TypeError: Cannot read property 'toString' of null
var a = null;
console.log(String(a)); // null

6.2、转 number

  • Number()
  • parseInt()
  • parseFloat()
var b = "123";
var b2 = "sss";
var b3 = "";
var b4 = " ";
var b5 = true;
var b6 = false;
var b7 = null;
var b8 = "123.56";
var b9 = "123.56px";
var b10 = "123.56876";
console.log(Number(b)); // 123
console.log(Number(b2)); // NaN
console.log(Number(b3)); // 0
console.log(Number(b4)); // 0
console.log(Number(b5)); // 1
console.log(Number(b6)); // 0
console.log(Number(b7)); // 0
console.log(parseInt(b8)); // 123
console.log(parseInt(b9)); // 123
console.log(parseFloat(b10)); // 123.56876

6.3、转 boolean

var c = 123;
var c2 = 0;
var c3 = NaN;
var c4 = Infinity
var c5 = "sss";
var c6 = "";
var c7 = " ";
var c8 = undefined;
var c9 = null;
var c10 = new Object();
console.log(Boolean(c)); // true
console.log(Boolean(c2)); // false
console.log(Boolean(c3)); // false 
console.log(Boolean(c4)); // true
console.log(Boolean(c5)); // true
console.log(Boolean(c6)); // false
console.log(Boolean(c7)); // true
console.log(Boolean(c8)); // false
console.log(Boolean(c9)); // false
console.log(Boolean(c10)); // true

7、break continue 用法

  • break
  • continue
label:
  for (let i = 0; i < 10; i++) {
     for (let j = 0; j < 10; j++) {
        if (i == 1) { break  label; }
        console.log("j: " + j)
      }
     console.log("i -- : " + i)
   }

8、对象

8.1、分类

  • 内建对象
    • ES标准中定义的对象
    • Math String Number Boolean Function Object
  • 宿主对象
    • 由Js运行环境提供的对象,目前来讲主要是由浏览器提供的对象
    • BOM DOM
  • 自定义对象

8.2、操作

  • 创建对象
  • 添加属性
  • 读取属性
  • 删除属性
// 创建对象
var obj = new Object();
// 使用对象字面量创建对象
var objc = {name : "周星驰"}; // 只有在特殊符号的情况下属性名需要加 ""
// 添加属性
obj.name = "孙悟空" //方法一
obj["name"] = "孙悟空" // 方法二 优点:属性名可以设置变量
// 举例
var a = "name";
obj[a] = "孙悟空";
console.log(obj.name);
结果: 孙悟空
// 读取属性
obj.name
// 删除属性
delete obj.name;

8.3、in

  • 运算符可以判断该属性是否属于该对象
console.log("name" in obj); // true;

8.4、易错点

var obj = new Object();
obj.name = "科比";
var obj2 = obj;
obj2.name = "韦德";
console.log(obj.name); // 韦德
obj2 = null;
console.log(obj.name); //韦德

9、函数

  • 函数也是一个对象

9.1、创建方式

  • 函数对象式
  • 函数声明式
  • 函数表达式

9.2、函数的调用格式

  • 格式:函数对象()
// 函数对象式
var function1 = new Function('console.log("hello")');
function1();
new Function('console.log("hello")')();
// 函数声明式
function fun() {
    console.log("fun");
}
fun();
// 函数表达式
var functionName = function () {
    console.log("functionName");
}
functionName();
// 匿名函数
(function () { console.log("functionName"); });

9.3、函数参数

  • 可以是任意数据类型
  • 形参就是在函数内部用 var 声明了一个变量没有赋值
  • 调用函数时,解析器不会检查实参类型、实参个数。多余实参不会被赋值,少则为 undefined
  • 注意:函数对象和调用函数的区别
function fun(a) { console.log("a: " + a); }
// 函数对象
fun(function () { console.log("匿名函数");} ); // a: function () { console.log("匿名函数"); }
// 调用函数
fun(function () { console.log("匿名函数");   return "匿名函数"; }() );// 匿名函数 a: 匿名函数

9.4、函数返回值

  • return 可返回任意数据类型

9.5、立即执行函数(匿名函数)

  • 函数声明完立即执行且只能调用一次
(function(a, b) { console.log(a + b); })(123, 456);

9.6、方法

  • 对象属性值为函数,即对象方法,方法和函数只是在名称上的区别
  • 遍历对象属性和值时,因为存在变量,因此不能用 .属性名
// 举例
var obj = new Object();
obj.name = "猪八戒";
obj.sayName = function () {
    console.log("哈哈");
}
obj.sayName(); // 哈哈
for( const n in obj) {
    console.log(obj[n]); // 猪八戒
}

10、作用域

10.1、定义

  • 定义:一个变量的作用范围

10.2、分类

  • 分类:全局作用域、局部作用域

10.3、全局作用域

  • 在全局作用域中创建的变量都会作为 window 对象属性保存
  • 在全局作用域中创建的函数都会作为 window 对象方法保存
var a = 20;
var b = 30;
console.log(b);
console.log(window.a);
console.log(window.c); // undefined
console.log(c); // Uncaught ReferenceError: c is not defined

10.4、变量的提前声明( varwindow 的区别)

  • var
    • 声明的变量会在所有代码执行前声明,仅声明不赋值
  • window
    • 不会提前声明
// 举例
console.log(a);
a = "window - a"; // Uncaught ReferenceError: a is not defined
console.log(b);
var b = "var - b"; // undefined

10.5、函数的提前声明

// 函数提前声明
fun();
function fun() { console.log("function - fun()"); }; // function - fun()
// 函数无法提前声明
console.log("fun2 " + fun2); // fun2 undefined 
fun2(); // Uncaught TypeError: fun2 is not a function
var fun2 = function () { console.log("function - fun2()"); };

10.6、函数作用域

  • 在函数作用域中可以访问全局变量,全局变量不能访问函数作用域变量
  • 在函数作用域中访问全局变量 window.
  • 在函数作用域中操作一个变量,由内到外寻找,如果没有,则会报错 Uncaught ReferenceError: a is not defined
  • 在函数作用域中不用 var 声明的变量都会变为全局变量
  • 形参就是在函数内部用 var 声明了一个变量没有赋值
function fun() {
    console.log(a);
}
fun(); // Uncaught ReferenceError: a is not defined
var a = "我是全局变量"
function fun2() {
    var a = "我是函数作用域变量"
    console.log(window.a);
}
fun2(); // 我是全局变量

10.7、作用域练习

var a = 123;
function fun() {
    console.log("a " + a);
}
fun(); // a 123

var b = 123;
function fun2() {
    console.log("b " + b); // b undefined
    var b = 345;
}
fun2();
console.log("b " + b); // b 123

var c = 123;
function fun3() {
    console.log("c " + c); // c 123
    c = 456;
}
fun3();
console.log("c " + c); // c 456

var d = 123;
function fun4(d) {
    console.log("d " + d); // d undefined
    d = 456;
}
fun4();
console.log("d " + d); // d 123

var e = 123;
function fun5(e) {
    console.log("e " + e); // e 789
    e = 456;
}
fun5(789);
console.log("e " + e); // e 123

11、this

  • 以函数形式调用,windowthis
  • 以方法形式调用,Objectthis
  • 在构造函数中新创建的对象,对象即 this
  • 使用call() apply(),第一个参数 即this

12、构造函数

12.1、类对象

  • 构造函数也称为一个类
  • 通过同一个构造函数创建出来的对象称为类对象

12.2、创建

  • 首字母大写
  • new 调用
  • instanceof 检查对象是否是一个类的实例,所有对象都是 Object 类的实例
function Person(name, age) {
    this.name = name;
    this.age = age;
}

var person = new Person("张三", 23);
console.log(person.age); // name 张三
if (person instanceof Person) {
    console.log("正确"); // 正确
}

12.3、执行流程

  • 立即创建一个对象
  • 将新创建的对象设置为函数中的 this,在构造函数中使用 this 引用新创建的对象。
  • 逐行执行函数中的代码
  • 将新创建的对象返回

13、原型对象

13.1、定义

  • 每创建一个函数,解析器都会向函数中添加一个 prototype 属性, 这个属性对应着一个对象,即原型对象

13.2、特点

  • 同一个类(构造函数)的实例都可以访问到这个原型对象,推荐将对象中共有的内容放入 prototype 属性中
  • 调用普通函数的 prototype 属性无作用
  • 调用构造函数, 他所创建的对象通过 .__proto__ 来访问构造函数的 prototype 对象
  • Object 对象没有原型对象为 null, 属性如果在Object中没有找到返回 undefined

13.3、hasOwnProperty()in 区别

  • hasOwnProperty()
    • 用于检查对象自身中是否含有该属性,是原型对象的原型对象中的方法
  • in
    • 检查对象和原型对象中是否函数该属性
function Person() { }
function Animal() { }
console.log(Person.prototype == Animal.prototype); // false
var person = new Person();
console.log(person.__proto__ == Person.prototype); // true
Person.prototype.a = "prototypeA";
//  in
console.log("a" in person); // true 
console.log("a" in Person); // false 
// hasOwnProperty()
console.log(person.hasOwnProperty("a")); // false
console.log(person.hasOwnProperty("hasOwnProperty")); // false
console.log(person.__proto__.hasOwnProperty("hasOwnProperty")); // false person对象的原型对象
console.log(person.__proto__.__proto__.hasOwnProperty("hasOwnProperty")); // true person对象的原型对象的原型对象
console.log(person.__proto__.__proto__.a);  // undefined
console.log(person.__proto__.__proto__.__proto__); // null  Object对象没有原型对象
console.log(person.__proto__.__proto__.__proto__.hasOwnProperty("hasOwnProperty")); // Uncaught TypeError: Cannot read property 'hasOwnProperty' of null

14、重写方法

  • toString() 方法属于 Object 对象的方法
  • 自定义 toString() 从原型中重写该方法即可

15、垃圾回收

  • 让对象等于 null 自动回收
var obj = new Person();
obj = null;

16、数组

16.1、创建数组

  • 构造函数式创建
  • 字面量式创建
// 构造函数式创建
var array = new Array();
// 字面量式创建
var array2 = [];
// 长度
var array3 = new Array(10);
// 数组内容
var array4 = new Array(10, 20, 30, 40);

16.2、遍历数组

  • 参数1 正在遍历的元素
  • 参数2 索引
  • 参数3 数组
array4.forEach(function (a, b, c) {
    console.log(a);
    console.log(b);
    console.log(c);
});

16.3、常用方法

  • push() 向末尾加,返回新长度
  • pop() 删除数组最后一个元素, 并返回被删除元素
  • unshift() 向开头加,返回新长度
  • shift() 删除第一个元素,并返回被删除元素
  • slice()splice() 的区别
    • slice(startIndex, endIndex)
      • 不影响原数组
      • 从某个已有数组返回指定元素到一个新数组
      • 含头不含尾
    • splice(startIndex, length, addInfo....)
      • 影响原数组
      • 删除下标从 startIndex 开始并往后推 length 位的元素,从 startIndex 开始插入 addInfo 元素,并返回被删除的元素
      • 含头不含尾
  • call() 函数对象方法
    • 使一个对象成为一个参数,此时这个对象将成为这个函数执行时的 this
    • 可以将实参在对象之后传递
  • apply() 函数对象方法
    • 使一个对象成为一个参数,此时这个对象将成为这个函数执行时的 this
    • 可以将实参在对象之后传递,需要将实参封装到一个数组中
var numbers = array4.splice(0, 2, 98);
numbers.forEach(function (a, b, c) { // 返回删除的元素
    console.log(a); // 10 20 
})
array4.forEach(function (a, b, c) { // 原数组
    console.log("y " + a); // 98 30 40 
})

17、正则表达式

17.1、创建方式

  • 构造函数式
    • 可传递两个参数
    • 第二个参数
      • i 忽略大小写模式
      • g 全局匹配模式
  • 字面量式
// 构造函数式
var regExp = new RegExp("a");
var b = regExp.test("a");
console.log(b); // true
// 字面量式
var reg = /a/i;
var b1 = reg.test("a");
console.log(b1); // true

17.2、常用符号

  • | []
    • a|b == [ab]
    • [a-z] 任意小写字母
    • [A-Z] 任意大写字母
    • [A-z] 任意字母
  • [^]
  • + 至少出现一次等同于 {1,}
  • * 0到无限次等同于 {0,}
  • ? 0到1次等同于 {0, 1}
  • . 匹配任意字符
  • \ 转义字符
  • \w 任意字母、数字、_
  • \W 除了任意字母、数字、_ 等同于 [^A-z0-9_]
  • \d 任意数字
  • \D 除了数字
  • \s 空格
  • \S 除了空格
  • \b 单词边界
  • \B 除了单词边界
  • ^ 开头
  • $ 结尾
  • 注意:同时使用 ^ $ 例如:/^a|a$/
  • {} 量词
    • 设置内容出现次数
    • {n} 正好出现n次
    • {m, n} 正好出现m~n次
    • {m,} m次以上
// b至少出现一次
/ab+c/
// ab 出现3次
/(ab){3}/
// b出现3次
/ab{3}/ 
// b 出现1~3次
/ab{1,3}/
// 含有\.
/\\./ 
// hello word word是单独的单词
/\bword\b/
// 去除开头结尾的空格
/^\s*|\s*$/g
// 邮件正则表达式 
// 任意字母数字下划线.任意字母下划线 
// @ 任意字母数字.任意字母(2-5位).任意字母(2-5位)
/^\w{3,}(\.\w)*@[A-z0-9]+(\.[A-z]{2,5}){1,2}

17.3、常用方法

  • test() 检查字符串是否符合正则表达式
  • split()
    • 根据任意字母进行拆分
  • serch()
    • 搜索字符串中是否含有指定内容,如果搜索到返回第一次出现的索引,如果没有找到返回-1
    • 全局匹配不生效
  • match()
    • 根据正则表达式从字符串中提取指定内容
    • 默认情况下只会找到第一个符合条件的内容
    • 开启全局模式,将匹配到的内容封装到一个数组中返回
  • replace()
    • 将字符串中指定内容替换为新内容
    • 默认只会替换第一个
    • 开启全局模式,可全匹配并替换
var str = "abcdefgabcdefgabcdefgabcdefgA"
var search = str.search(/a/ig);
console.log(search); // 0
var match = str.match(/A/g);
console.log(match[0]);// A

18. DOM 文档对象模型

18.1、什么是 DOM

  • JS通过 DOMHTML 文档进行操作

18.2、组成部分

  • 文档
    • 整个 HTML 网页文档是文档
  • 对象(节点)
    • 最基本组成部分
    • 分为:文档节点、元素节点、属性节点、文本节点
节点nodeNamenodeTypenodeValue
文档节点document9null
元素节点标签名1null
属性节点属性名2属性值
文本节点HTML标签中的文本内容3文本内容
  • 模型
    • 表示对象之间的关系,方便获取对象

18.3、事件

  • 用户和浏览器之间的交互行为

18.4、文档加载

  • window.onload 事件,页面全部加载完成后触发执行

18.5、DOM 查询

  • 对于自结束标签 innerHTML 这个属性没有意义
  • 读取元素属性值 元素对象.属性
    • 注意:class 属性的值通过 .className获取属性值
  • 注意: 元素 和 节点 的区别
    • 节点:文本节点、DOM 标签之间的空白
      • IE8及以下 不包含文本节点和 DOM 标签之间的空白
      • children 获取当前元素的所有子元素
      • childNodes 表示当前节点的所有子节点
  • getElementById() 通过 id 属性获取一个元素节点对象
  • getElementByTagName() 通过标签获取一组元素节点对象
  • getElementByName() 通过 name 属性获取一组元素节点对象
  • querySelector() 通过 CSS 一个选择器的字符串作为参数,查询一个元素节点对象,如果匹配上多个返回第一个
    • IE8 中没有 getElementsByClassName() 使用 querySelector()代替
  • querySelectorAll() 返回数组,即使只有一个值,也返回数组
document.querySelector(".edge-translate-notifier-center");

18.6、DOM 增删改查

  • 注意
    • appendChild()innerText() 区别
    • removeChild()
    • replaceChild()
    • 事件重新绑定
    • for 循环会在页面加载完成后立即执行,响应函数会在超链接点击时候执行,因此在 for 循环中绑定相应函数用 this

18.7、DOM 操作内联样式

  • 格式:元素.style.样式名 = 样式值;
  • 如果CSS样式中存在 -,去掉改成驼峰命名法即可
  • CSS 使用 !improtant会导致JS修改失效
  • 仅支持内联样式读取,样式表中的样式不支持

18.8、获取元素其它样式

  • currentStyle
    • 读取当前元素正在显示的样式,如果样式没有设置,会获得默认值 auto等,带单位
    • 只读样式,不支持修改,修改必须通过 style 属性
    • 仅支持IE
    • 格式:元素.currentStyle.样式名
  • getComputedStyle()
    • 读取当前元素正在显示的样式,如果样式没有设置,不会获得默认值,获取一个真实样式 1320px 等,带单位
    • 只读样式,不支持修改,修改必须通过 style 属性
    • 不支持IE8及以下版本
    • 格式:getComputedStyle(参数1, 参数2)
      • 参数1:需要获取样式的元素
      • 参数2:传递伪元素,一般为 NULL
      • 返回一个对象,对象中封装了当前元素对应的样式
/**
 * 兼容性处理
 * @param obj 元素
 * @param name 样式名
 */
function getStyle(obj, name) {
    if (window.getComputedStyle) {
        return getComputedStyle(obj, null)[name];
    } else {
        return obj.currentStyle[name];
    }
}
  • clientHeight
    • 只读样式,不支持修改,修改必须通过 style 属性
    • 返回元素的可见高度,例如 18 等,不带单位可直接计算
    • 包括内容区和内边距,不包含滚动条宽度,边距宽度
  • clientWidth
    • 只读样式,不支持修改,修改必须通过 style 属性
    • 返回元素的可见宽度,不带单位可直接计算
    • 包括内容区和内边距,不包含滚动条宽度,边距宽度
  • offsetHeight
    • 只读样式,不支持修改,修改必须通过 style 属性
    • 返回元素的高度,不带单位可直接计算
    • 包括内容区,内边距,边框
  • offsetWidth
    • 只读样式,不支持修改,修改必须通过 style 属性
    • 返回元素的宽度,不带单位可直接计算
    • 包括内容区,内边距,边框
  • offsetParent
    • 只读样式,不支持修改,修改必须通过 style 属性
    • 返回元素的偏移容器(定位父元素),如果没有开启定位的祖先元素,返回 body
  • offsetLeft
    • 只读样式,不支持修改,修改必须通过 style 属性
    • 返回元素的水平偏移位置
  • offsetTop
    • 只读样式,不支持修改,修改必须通过 style 属性
    • 返回元素的垂直偏移位置
  • scrollHeight
    • 只读样式,不支持修改,修改必须通过 style 属性
    • 返回元素的整个滚动区域的高度
  • scrollWidth
    • 只读样式,不支持修改,修改必须通过 style 属性
    • 返回元素的滚动区域的宽度
  • scrollLeft
    • 只读样式,不支持修改,修改必须通过 style 属性
    • 返回水平滚动条滚动的距离
    • 滚动条到底公式:scrollWidth - scrollLeft == clientWidth
  • scrollTop
    • 只读样式,不支持修改,修改必须通过 style 属性
    • 返回垂直滚动条滚动的距离
    • 谷歌浏览器认为滚动条是 body 的,获取高度时候 body.scrollTop
    • IE 和 火狐浏览器认为滚动条是 html 的,document.documentElement.scrollTop
      • 滚动条到底公式:scrollHeight - scrollTop == clientHeight
  • clientX
    • 可见窗口坐标
    • 原点永远在左上角(0, 0)点
  • clientY
    • 可见窗口坐标
    • 原点永远在左上角(0, 0)点
  • pageX
    • 不兼容IE8
    • 相对于页面的坐标
  • pageY
    • 不兼容IE8
    • 相对于页面的坐标

18.9、事件对象

  • 当事件的响应函数被触发时,浏览器每次都会将一个事件对象作为实参传递进响应函数,事件对象封装了当前事件的一切相关信息。比如:鼠标坐标、键盘按键、鼠标滚轮方向
  • 在IE8及以下,事件对象在window 对象中保存
  • 格式:
areaDiv.onmousemove = function(event) {
  event = event || window.event;
}
  • 鼠标跟随练习
window.onload = function () {
    var box1ClassElement = document.getElementsByClassName("box1")[0];
    document.documentElement.onmousemove = function (event) {
        event = event || window.event;
        // 谷歌浏览器
        // var left = event.pageX;
        // var top = event.pageY;

        // box1ClassElement.style.left = left + "px";
        // box1ClassElement.style.top = top + "px";

        // 适配所有浏览器
        var left = event.clientX;
        var top = event.clientY;

        var st = document.body.scrollTop || document.documentElement.scrollTop;
        var sl = document.body.scrollLeft || document.documentElement.scrollLeft;


        box1ClassElement.style.left = sl + left + "px";
        box1ClassElement.style.top = st + top + "px";

    }
}
body {
    height: 1000px;
    overflow: auto;
}
.box1 {
    width: 100px;
    height: 100px;
    background-color: #bbffaa;
    position: absolute;
}
<div class="box1"></div>

18.10、冒泡事件(Bubble)

  • 父子元素之间存在的事件向上传到问题,当子元素上的事件被触发时,其父元素的相同事件也会被触发
  • 大部分冒泡都是有用的,如果不需要可以通过事件对象取消冒泡
// 取消冒泡事件
event.cancelBubble = true;

18.11、事件的委派

  • 只绑定一次事件,即可应用到多个元素上,即使元素是后添加的,可以将事件绑定给元素的共同祖先元素
  • 利用冒泡,减少事件绑定次数,提高程序性能
  • target 获取触发特定事件的元素
window.onload = function () {
    var ulElement = document.getElementsByTagName("ul")[0];
    ulElement.onclick = function (event) {
             event = event || window.event;
             var className = event.target.className;
             if (event.target.className == "link") {
                 alert(" ul点击了 ");
             }
         }
}
<ul>
    <li>
        <div class="link">d1</div>
    </li>
    <li>
        <div class="link">d2</div>
    </li>
    <li>
        <div class="link">d3</div>
    </li>
</ul>

18.12、事件绑定 addEventListener()

  • 使一个元素同一个类型的事件都会被触发而不覆盖并按绑定顺序执行
  • addEventListener() 可以为元素绑定响应函数
    • 参数1 事件的字符串,把 on 去掉
    • 参数2 回调函数,当事件触发时该函数会被调用
    • 参数3 是否在捕获阶段触发事件,一般传 false
  • 不支持IE8及以下版本,使用attachEvent()
    • 参数1 事件的字符串含有 on
    • 参数2 回调函数
    • 执行顺序是后绑定先执行
    • this 指向 window 对象
 window.onload = function () {
     var btnElement = document.getElementsByTagName("button")[0];
     bind(btnElement, "click", function(){
         alert("this: " + this);
     });
 }
 
 function bind(obj, eventStr, callback) {
     if (obj.addEventListener) {
     obj.addEventListener(eventStr, callback, false);
     } else {
         obj.attachEvent("on" + eventStr, function () {
             callback.call(obj);
         });
     }
 }
<button type="button">点击我 </button>

18.13、事件的传播

  • 三个阶段
    • 捕获阶段
      • 从最外层的祖先元素,向目标元素进行事件捕获,默认不会触发事件。
    • 目标阶段
      • 事件捕获到目标元素,捕获结束,在目标元素触发事件
    • 冒泡阶段
      • 事件从目标元素向祖先元素传递,依次触发祖先元素事件
  • 如果希望在捕获阶段就触发事件,则将 addEventListener() 第三个参数改为 true

18.14、拖拽

* {
    margin: 0;
    border: 0;
}
.box1 {
    width: 100px;
    height: 100px;
    background-color: #bfa;
    position: absolute;
}
.box2 {
    width: 100px;
    height: 100px;
    background-color: red;
    position: absolute;
    left: 100px;
}
window.onload = function () {
    var boxElement = document.getElementById("box1");
    boxElement.onmousedown =  function (event) {
        boxElement.setCapture &&  boxElement.setCapture();
        event = event || window.event;
        var cx = event.clientX;
        var cy = event.clientY;
        var ol = this.offsetLeft;
        var ot = this.offsetTop;
        console.log("cx: " + cx + ",cy: " + cy + "ol: " + ol + "ot: " + ot);
        document.documentElement.onmousemove = function (event) {
            event = event || window.event;
            var pageX = getPage(event).pageX;
            var pageY = getPage(event).pageY;
            boxElement.style.left = pageX - (cx - ol) + "px";
            boxElement.style.top = pageY - (cy - ot) + "px";
        }
        document.documentElement.onmouseup = function () {
            document.documentElement.onmousemove = null;
            document.documentElement.onmouseup = null;
            boxElement.releaseCapture && boxElement.releaseCapture();
        }
        // 拖拽网页内容浏览器会默认去搜索引擎中搜索内容,导致拖拽功能异常,这是浏览器的默认行为,取消该默认行为 return false
        return false
    }
    // 获取页面滚动出去的距离
    function getScroll() {
        var scrollLeft = document.body.scrollLeft || document.documentElement.scrollLeft;
        var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
        return {
            scrollLeft: scrollLeft,
            scrollTop: scrollTop
        }
    }

    // 获取鼠标在页面的位置,处理浏览器兼容性
    function getPage(e) {
        var pageX = e.pageX || e.clientX + getScroll().scrollLeft;
        var pageY = e.pageY || e.clientY + getScroll().scrollTop;
        return {
            pageX: pageX,
            pageY: pageY
        }
    }
}
我是一段文字
<div class="box1" id="box1"></div>
<div class="box2"></div>

18.15、滚轮事件

  • onwheel 支持所有的 HTML5 浏览器(推荐)
  • onmousewheelfirebox 浏览器
  • DOMMouseScroll 仅支持 firebox 浏览器
var box1 = document.getElementById("box1");
box1.onwheel = function (event) {
  event = event || window.event;
  // alert(event.wheelDelta)
  // alert(event.detail)
  if (event.wheelDelta > 0) {
    box1.style.height = box1.clientHeight + 100 + "px";
  } else {
    box1.style.height = box1.clientHeight - 100 + "px";
  }
  /**
   * addEventListener() 方法绑定响应函数,取消默认行为不能使用 return false
   * 需要使用event来取消默认行为,但IE8不支持
   */
  event.preventDefault && event.preventDefault();

  /**
   * 当滚轮滚动时,浏览器有滚动条,滚动条会随之滚动,这是浏览器默认行为,如果不希望发生,则可以取消默认行为
   */
  return false
}

bind(box1, 'DOMMouseScroll', box1.onwheel)

function bind(obj, eventStr, callback) {
  if (obj.addEventListener) {
    obj.addEventListener(eventStr, callback, false);
  } else {
    obj.attachEvent("on" + eventStr, function () {
      callback.call(obj);
    });
  }
}
<body style="height: 2000px;">
<div id="box1"></div>
</body>
#box1 {
    width: 100px;
    height: 100px;
    background-color: #bfa;
}

18.16、键盘事件

  • onkeydown 当用户正在按下键时,发生此事件
  • onkeyup 当用户松开键时,发生此事件
  • event.altKeyevent.ctrlKeyevent.shiftKey 事件触发时是否按下相关按键
  • 在文本框中输入内容属于 onkeydown 默认行为,return false 取消默认行为
window.onload = function () {
  document.onkeydown = function (event) {
    event = event || window.event;
    console.log(event.keyCode);
    if (event.ctrlKey && event.keyCode == 67) {
      console.log("ctrl + c");
    }
  }
  var inputElement = document.getElementsByTagName('input')[0];
  inputElement.onkeydown = function () {
    return false
  }
}

18.17、div 跟随键盘移动事件

window.onload = function () {
    var box1 = document.getElementById("box1");
    // 键盘按下事件
    document.onkeydown = function (event) {
        var speed = 50;
        var step = 10;
        event = event || window.event;
        var keyCode = event.keyCode;
        if (event.ctrlKey) {
            step = speed;
        }
        switch (keyCode) {
            case 37:
                console.log("left");
                box1.style.left = box1.offsetLeft - step + "px";
                break;
            case 38:
                console.log("top");
                box1.style.top = box1.offsetTop - step + "px";
                break;
            case 39:
                console.log("right");
                box1.style.left = box1.offsetLeft + step + "px";
                break;
            case 40:
                console.log("bottom");
                box1.style.top = box1.offsetTop + step + "px";
                break;
        }
    }
    // 键盘抬起事件
    box1.onkeyup = function (event) {

    }
}

.box1 {
    width: 100px;
    height: 100px;
    background-color: #bfa;
    position: absolute;
}
<div id="box1" class="box1"></div>

19、BOM 浏览器对象模型

  • 通过JS操作浏览器,这些对象都是保存在 window 对象中,通过 window.属性 即可使用
  • window 代表整个浏览器的窗口
  • navigator 代表当前浏览器的信息,可以识别不同的浏览器
  • location 代表浏览器的地址栏信息,操作浏览器跳转页面
  • history 代表浏览器的历史记录,可以通过该对象来操作浏览器的历史记录,前进或者后退,仅对当此访问时有效(新开窗口无效,关闭窗口消失)
  • screen 代表用户屏幕信息

19.1、navigator

  • userAgent 属性是一个只读的字符串,声明了浏览器用于 HTTP 请求的用户代理头的值,判断浏览器类型
  • 也可以通过浏览器特有属性判断浏览器类型 attachEvent ActiveXObject
window.onload = function () {
    var userAgent = navigator.userAgent;
    console.log(userAgent);
    if (/firefox/i.test(userAgent)) {
        console.log("我是火狐浏览器");
    } else if (/chrome/i.test(userAgent)) {
        console.log("我是chrome");
    } else if (/msie/i.test(userAgent)) {
        console.log("我是IE浏览器");
    }
    if ("ActiveXObject" in window) {
        alert("我是IE")
    } else {
        alert("我不是IE")
    }
}

19.2、history

  • length 返回历史列表中的网址数
  • back() 加载 history 列表中的前一个 URL
  • forward() 加载 history 列表中的下一个 URL
  • go() 加载 history 列表中的某个具体页面
    • go(2) 向前跳转2个页面
    • go(-1) 向后跳转1个页面

19.3、location

  • location 直接打印返回地址栏信息,如果赋值则表示跳转,并生成历史记录
  • assign() 加载新的文档,存在历史记录,可以使用回退按钮
  • reload() 重新加载当前文档
    • 参数 true 强制清空缓存刷新
  • replace() 用新的文档替换当前文档,不会生成历史记录,不能使用回退按钮
window.onload = function () {
    var buttonElement = document.getElementsByTagName("button")[0];
    buttonElement.onclick = function () {
        // location = "http://www.baidu.com";
        // location.assign("http://www.baidu.com")
        // location.reload()
        location.replace("http://www.baidu.com")
    }
}
<button type="button">点击</button>

20、定时器

20.1、setInterval 定时调用

  • 将一个函数,每隔一段时间执行一次
  • 参数
    • 1、回调函数,该函数会每隔一段时间被调用一次
    • 2、每次调用间隔的时间,单位是毫秒
  • 返回值:返回一个 number 类型的数据,作为定时器的唯一标识
  • clearInterval() 关闭定时器
    • 参数如果是一个有效标识,则停止定时器,如果不是一个有效标识,什么都不做
window.onload = function () {
    var divELement = document.getElementById("div1");
    var number = 1;
    var interval = setInterval(function () {
        divELement.innerHTML = number++;
        if (number == 11) {
            clearInterval(interval);
        }
    }, 1000);
}
<div id="div1"></div>

20.2、setInterval 优化键盘移动div

window.onload = function () {
    var step = 10;
    var flag = 0;
    var box1 = document.getElementById("box1");
    
    setInterval(function () {
        switch (flag) {
            case 37:
                box1.style.left = box1.offsetLeft - step + "px";
                break;
            case 38:
                box1.style.top = box1.offsetTop - step + "px";
                break;
            case 39:
                box1.style.left = box1.offsetLeft + step + "px";
                break;
            case 40:
                box1.style.top = box1.offsetTop + step + "px";
                break;
        }
    }, 1000);
    
    document.onkeydown = function (event) {
        event = event || window.event;
        var keyCode = event.keyCode;
        if (event.ctrlKey) {
            step = 100;
        }
        flag = keyCode;
    }

    document.onkeyup = function (event) {
        flag = 0;
        step = 10;
    }
}
.box1 {
    width: 100px;
    height: 100px;
    position: absolute;
    background-color: #bfa;
}
<div id="box1" class="box1"></div>

20.3、setTimeout 延时调用

  • 将一个函数,延时后只会执行一次
  • clearTimeout() 关闭延时调用
window.onload = function () {
  var box1 = document.getElementById("box1");
  var timeout = setTimeout(function () {
    box1.innerHTML = 1;
  }, 1000);
  clearTimeout(timeout)
}

20.4、setInterval 应用

window.onload = function () {
    var box1 = document.getElementById("box1");
    var box2 = document.getElementById("box2");
    var btn1 = document.getElementById("btn1");
    var btn2 = document.getElementById("btn2");
    var btn3 = document.getElementById("btn3");
    var btn4 = document.getElementById("btn4");
    btn1.onclick = function () {
        move(box1, "left", 800, 120);
    }

    btn2.onclick = function () {
        move(box1, "left", 0, 120);
    }
    btn3.onclick = function () {
        move(box2, "left", 800, 120);
    }
    btn4.onclick = function () {
        move(box2, "width", 800, 120, function () {
            alert("动画执行完毕");
        });
    }

    function getStyle(obj, name) {
        if (window.getComputedStyle) {
            return getComputedStyle(obj, null)[name];
        } else {
            return obj.currentStyle[name];
        }
    }

    function move(obj, attr, target, speed, callback) {
        clearInterval(obj.interval);
        var current = parseInt(getStyle(obj, attr));
        if (current > target) {
            speed = -speed;
        }
        obj.interval = setInterval(function () {
            var oldOffsetLeft = parseInt(getStyle(obj, attr));
            var newOffsetLeft = oldOffsetLeft + speed;
            if ((speed > 0 && newOffsetLeft > target) || (speed < 0 && newOffsetLeft < target)) {
                newOffsetLeft = target;
            }
            obj.style[attr] = newOffsetLeft + "px";
            if (newOffsetLeft == target) {
                clearInterval(obj.interval)
                callback && callback();
            }
        }, 100);
    }
}
* {
    margin: 0;
    padding: 0;
}

#box1 {
    width: 100px;
    height: 100px;
    background-color: #bfa;
    position: absolute;
    left: 0px;
}
#box2 {
    width: 100px;
    height: 100px;
    background-color: red;
    position: absolute;
    left: 0px;
    top: 200px;
}
<button id="btn1" type="button">按钮1</button>
<button id="btn2" type="button">按钮2</button>
<button id="btn3" type="button">按钮3</button>
<button id="btn4" type="button">按钮4</button>
<div id="box1"></div>
<div id="box2"></div>
<div style="width: 0; height: 1000px; border: 1px solid black; position: absolute; left: 800px; top: 0;"></div>

21、类的操作

window.onload = function () {
    var btn1 = document.getElementById("btn1");
    var box1 = document.getElementById("box1");
    btn1.onclick = function () {
      toggleClass(box1, "b2")
    }

    function addClass(obj, cn) {
        obj.className += " " + cn;
    }

    function hasClass(obj, cn) {
      var regExp = new RegExp("\\b" + cn + "\\b");
      return regExp.test(obj.className);
    }

  function removeClass(obj, cn) {
    var regExp = new RegExp("\\b\\s" + cn + "\\b");
    obj.className = obj.className.replace(regExp, "");
  }

  function toggleClass(obj, cn) {
    if (!hasClass(obj, cn)) {
      addClass(obj, cn);
    } else {
      removeClass(obj, cn)
    }
  }

}
.b1 {
    width: 100px;
    height: 100px;
    background-color: red;
}

.b2 {
    width: 200px;
    height: 200px;
    background-color: yellow;
}
<button type="button" id="btn1">按钮1</button>
<div id="box1" class="b1"></div>

22、JSON

  • eval() 执行一段字符串形式的JS代码,并将执行结果返回。功能过于强大且不安全,不建议使用。
var str = "alert('hello')"
eval(str);
var str2 = '{"name": "孙悟空", "age": 13}'
eval("(" + str2 + ")"); // {name: '孙悟空', age: 13}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值