1.1. 元素偏移量 offset 系列1.1.1 offset 概述offset 翻译过来就是偏移量， 我们使用 offset系列相关属性可以动态的得到该元素的位置（偏移）、大小等。 获得元素距离带有定位父元素的位置 获得元素自身的大小（宽度高度） 注意：返回的数值都不带单位 1.1.2 offset 与 style 区别offset offset 可以得到任意样式表中的样式值 offset 系列获得的数值是没有单位的 offsetWidth 包含padding+border+width offsetWidth 等属性是只读属性，只能获取不能赋值 所以，我们想要获取元素大小位置，用offset更合适 style style 只能得到行内样式表中的样式值 style.width 获得的是带有单位的字符串 style.width 获得不包含padding和border 的值 style.width 是可读写属性，可以获取也可以赋值 所以，我们想要给元素更改值，则需要用style改变 因为平时我们都是给元素注册触摸事件，所以重点记住 targetTocuhes1.1.3 案例：获取鼠标在盒子内的坐标 我们在盒子内点击，想要得到鼠标距离盒子左右的距离。 首先得到鼠标在页面中的坐标（e.pageX, e.pageY） 其次得到盒子在页面中的距离 ( box.offsetLeft, box.offsetTop) 用鼠标距离页面的坐标减去盒子在页面中的距离，得到 鼠标在盒子内的坐标 如果想要移动一下鼠标，就要获取最新的坐标，使用鼠标移动 var box = document.querySelector('.box'); box.addEventListener('mousemove', function(e) { var x = e.pageX - this.offsetLeft; var y = e.pageY - this.offsetTop; this.innerHTML = 'x坐标是' + x + ' y坐标是' + y; }) 1.1.4 案例：模态框拖拽弹出框，我们也称为模态框。​ 1.点击弹出层，会弹出模态框， 并且显示灰色半透明的遮挡层。​ 2.点击关闭按钮，可以关闭模态框，并且同时关闭灰色半透明遮挡层。​ 3.鼠标放到模态框最上面一行，可以按住鼠标拖拽模态框在页面中移动。​ 4.鼠标松开，可以停止拖动模态框移动1.1.5. 案例分析: 点击弹出层， 模态框和遮挡层就会显示出来 display:block; 点击关闭按钮，模态框和遮挡层就会隐藏起来 display:none; 在页面中拖拽的原理：鼠标按下并且移动， 之后松开鼠标 触发事件是鼠标按下mousedown，鼠标移动mousemove 鼠标松开 mouseup 拖拽过程: 鼠标移动过程中，获得最新的值赋值给模态框的left和top值，这样模态框可以跟着鼠标走了 鼠标按下触发的事件源是最上面一行，就是 id 为 title 鼠标的坐标减去 鼠标在盒子内的坐标， 才是模态框真正的位置。 鼠标按下，我们要得到鼠标在盒子的坐标。 鼠标移动，就让模态框的坐标 设置为 ：鼠标坐标 减去盒子坐标即可，注意移动事件写到按下事件里面。 鼠标松开，就停止拖拽，就是可以让鼠标移动事件解除 // 1. 获取元素 var login = document.querySelector('.login'); var mask = document.querySelector('.login-bg'); var link = document.querySelector('#link'); var closeBtn = document.querySelector('#closeBtn'); var title = document.querySelector('#title'); // 2. 点击弹出层这个链接 link 让mask 和login 显示出来 link.addEventListener('click', function() { mask.style.display = 'block'; login.style.display = 'block'; }) // 3. 点击 closeBtn 就隐藏 mask 和 login closeBtn.addEventListener('click', function() { mask.style.display = 'none'; login.style.display = 'none'; }) // 4. 开始拖拽 // (1) 当我们鼠标按下， 就获得鼠标在盒子内的坐标 title.addEventListener('mousedown', function(e) { var x = e.pageX - login.offsetLeft; var y = e.pageY - login.offsetTop; // (2) 鼠标移动的时候，把鼠标在页面中的坐标，减去 鼠标在盒子内的坐标就是模态框的left和top值 document.addEventListener('mousemove', move) function move(e) { login.style.left = e.pageX - x + 'px'; login.style.top = e.pageY - y + 'px'; } // (3) 鼠标弹起，就让鼠标移动事件移除 document.addEventListener('mouseup', function() { document.removeEventListener('mousemove', move); }) }) 1.1.6 案例：仿京东放大镜 整个案例可以分为三个功能模块 鼠标经过小图片盒子， 黄色的遮挡层 和 大图片盒子显示，离开隐藏2个盒子功能 黄色的遮挡层跟随鼠标功能。 移动黄色遮挡层，大图片跟随移动功能。 1.1.7. 案例分析: 黄色的遮挡层跟随鼠标功能。 把鼠标坐标给遮挡层不合适。因为遮挡层坐标以父盒子为准。 首先是获得鼠标在盒子的坐标。 之后把数值给遮挡层做为left 和top值。 此时用到鼠标移动事件，但是还是在小图片盒子内移动。 发现，遮挡层位置不对，需要再减去盒子自身高度和宽度的一半。 遮挡层不能超出小图片盒子范围。 如果小于零，就把坐标设置为0 如果大于遮挡层最大的移动距离，就把坐标设置为最大的移动距离 遮挡层的最大移动距离：小图片盒子宽度 减去 遮挡层盒子宽度 window.addEventListener('load', function() { var preview_img = document.querySelector('.preview_img'); var mask = document.querySelector('.mask'); var big = document.querySelector('.big'); // 1. 当我们鼠标经过 preview_img 就显示和隐藏 mask 遮挡层 和 big 大盒子 preview_img.addEventListener('mouseover', function() { mask.style.display = 'block'; big.style.display = 'block'; }) preview_img.addEventListener('mouseout', function() { mask.style.display = 'none'; big.style.display = 'none'; }) // 2. 鼠标移动的时候，让黄色的盒子跟着鼠标来走 preview_img.addEventListener('mousemove', function(e) { // (1). 先计算出鼠标在盒子内的坐标 var x = e.pageX - this.offsetLeft; var y = e.pageY - this.offsetTop; // console.log(x, y); // (2) 减去盒子高度 300的一半 是 150 就是我们mask 的最终 left 和top值了 // (3) 我们mask 移动的距离 var maskX = x - mask.offsetWidth / 2; var maskY = y - mask.offsetHeight / 2; // (4) 如果x 坐标小于了0 就让他停在0 的位置 // 遮挡层的最大移动距离 var maskMax = preview_img.offsetWidth - mask.offsetWidth; if (maskX <= 0) { maskX = 0; } else if (maskX >= maskMax) { maskX = maskMax; } if (maskY <= 0) { maskY = 0; } else if (maskY >= maskMax) { maskY = maskMax; } mask.style.left = maskX + 'px'; mask.style.top = maskY + 'px'; // 3. 大图片的移动距离 = 遮挡层移动距离 * 大图片最大移动距离 / 遮挡层的最大移动距离 // 大图 var bigIMg = document.querySelector('.bigImg'); // 大图片最大移动距离 var bigMax = bigIMg.offsetWidth - big.offsetWidth; // 大图片的移动距离 X Y var bigX = maskX * bigMax / maskMax; var bigY = maskY * bigMax / maskMax; bigIMg.style.left = -bigX + 'px'; bigIMg.style.top = -bigY + 'px'; }) }) 1.2. 元素可视区 client 系列1.2.1 client概述client 翻译过来就是客户端，我们使用 client 系列的相关属性来获取元素可视区的相关信息。通过 client系列的相关属性可以动态的得到该元素的边框大小、元素大小等。1.2.2. 淘宝 flexible.js 源码分析立即执行函数 (function(){})() 或者 (function(){}())主要作用： 创建一个独立的作用域。 避免了命名冲突问题下面三种情况都会刷新页面都会触发 load 事件。1.a标签的超链接2.F5或者刷新按钮（强制刷新）3.前进后退按钮但是 火狐中，有个特点，有个“往返缓存”，这个缓存中不仅保存着页面数据，还保存了DOM和JavaScript的状态；实际上是将整个页面都保存在了内存里。所以此时后退按钮不能刷新页面。此时可以使用 pageshow事件来触发。，这个事件在页面显示时触发，无论页面是否来自缓存。在重新加载页面中，pageshow会在load事件触发后触发；根据事件对象中的persisted来判断是否是缓存中的页面触发的pageshow事件注意这个事件给window添加。1.3.元素滚动 scroll 系列1.3.1. scroll 概述scroll 翻译过来就是滚动的，我们使用 scroll 系列的相关属性可以动态的得到该元素的大小、滚动距离等。1.3.2. 页面被卷去的头部如果浏览器的高（或宽）度不足以显示整个页面时，会自动出现滚动条。当滚动条向下滚动时，页面上面被隐藏掉的高度，我们就称为页面被卷去的头部。滚动条在滚动时会触发 onscroll事件。1.3.3.案例：仿淘宝固定右侧侧边栏 原先侧边栏是绝对定位 当页面滚动到一定位置，侧边栏改为固定定位 页面继续滚动，会让 返回顶部显示出来 1.3.4.案例分析: 需要用到页面滚动事件 scroll 因为是页面滚动，所以事件源是document 滚动到某个位置，就是判断页面被卷去的上部值。 页面被卷去的头部：可以通过window.pageYOffset 获得 如果是被卷去的左侧window.pageXOffset 注意，元素被卷去的头部是element.scrollTop , 如果是页面被卷去的头部 则是 window.pageYOffset 其实这个值 可以通过盒子的 offsetTop可以得到，如果大于等于这个值，就可以让盒子固定定位了 //1. 获取元素 var sliderbar = document.querySelector('.slider-bar'); var banner = document.querySelector('.banner'); // banner.offestTop 就是被卷去头部的大小 一定要写到滚动的外面 var bannerTop = banner.offsetTop // 当我们侧边栏固定定位之后应该变化的数值 var sliderbarTop = sliderbar.offsetTop - bannerTop; // 获取main 主体元素 var main = document.querySelector('.main'); var goBack = document.querySelector('.goBack'); var mainTop = main.offsetTop; // 2. 页面滚动事件 scroll document.addEventListener('scroll', function() { // console.log(11); // window.pageYOffset 页面被卷去的头部 // console.log(window.pageYOffset); // 3 .当我们页面被卷去的头部大于等于了 172 此时 侧边栏就要改为固定定位 if (window.pageYOffset >= bannerTop) { sliderbar.style.position = 'fixed'; sliderbar.style.top = sliderbarTop + 'px'; } else { sliderbar.style.position = 'absolute'; sliderbar.style.top = '300px'; } // 4. 当我们页面滚动到main盒子，就显示 goback模块 if (window.pageYOffset >= mainTop) { goBack.style.display = 'block'; } else { goBack.style.display = 'none'; } }) 1.3.5.页面被卷去的头部兼容性解决方案需要注意的是，页面被卷去的头部，有兼容性问题，因此被卷去的头部通常有如下几种写法： 声明了 DTD，使用 document.documentElement.scrollTop 未声明 DTD，使用 document.body.scrollTop 新方法 window.pageYOffset和 window.pageXOffset，IE9 开始支持 function getScroll() { return { left: window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft||0, top: window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0 }; } 使用的时候 getScroll().left 1.4. 三大系列总结他们主要用法：1.offset系列 经常用于获得元素位置 offsetLeft offsetTop2.client经常用于获取元素大小 clientWidth clientHeight3.scroll 经常用于获取滚动距离 scrollTop scrollLeft 4.注意页面滚动的距离通过 window.pageXOffset 获得1.5. mouseenter 和mouseover的区别 当鼠标移动到元素上时就会触发mouseenter 事件 类似 mouseover，它们两者之间的差别是 mouseover 鼠标经过自身盒子会触发，经过子盒子还会触发。mouseenter 只会经过自身盒子触发 之所以这样，就是因为mouseenter不会冒泡 跟mouseenter搭配鼠标离开 mouseleave 同样不会冒泡 1.6. 动画函数封装1.6.1. 动画实现原理核心原理：通过定时器 setInterval() 不断移动盒子位置。实现步骤： 获得盒子当前位置 让盒子在当前位置加上1个移动距离 利用定时器不断重复这个操作 加一个结束定时器的条件 注意此元素需要添加定位，才能使用element.style.left 1.6.2. 动画函数给不同元素记录不同定时器如果多个元素都使用这个动画函数，每次都要var 声明定时器。我们可以给不同的元素使用不同的定时器（自己专门用自己的定时器）。核心原理：利用 JS 是一门动态语言，可以很方便的给当前对象添加属性。 function animate(obj, target) { // 当我们不断的点击按钮，这个元素的速度会越来越快，因为开启了太多的定时器 // 解决方案就是 让我们元素只有一个定时器执行 // 先清除以前的定时器，只保留当前的一个定时器执行 clearInterval(obj.timer); obj.timer = setInterval(function() { if (obj.offsetLeft >= target) { // 停止动画 本质是停止定时器 clearInterval(obj.timer); } obj.style.left = obj.offsetLeft + 1 + 'px'; }, 30); }
1.1. 常用的键盘事件1.1.1 键盘事件 1.1.2 键盘事件对象使用keyCode属性判断用户按下哪个键 1.1.3 案例：模拟京东按键输入内容当我们按下 s 键， 光标就定位到搜索框（文本框获得焦点）。注意：触发获得焦点事件，可以使用 元素对象.focus() 1.1.4 案例：模拟京东快递单号查询要求：当我们在文本框中输入内容时，文本框上面自动显示大字号的内容。 123 1.2. BOM1.2.1. 什么是BOM​ BOM（Browser Object Model）即浏览器对象模型，它提供了独立于内容而与浏览器窗口进行交互的对象，其核心对象是 window。​ BOM 由一系列相关的对象构成，并且每个对象都提供了很多方法与属性。​ BOM 缺乏标准，JavaScript 语法的标准化组织是 ECMA，DOM 的标准化组织是 W3C，BOM 最初是Netscape 浏览器标准的一部分。1.2.2. BOM的构成BOM 比 DOM 更大，它包含 DOM。1.2.3. 顶级对象window1.2.4. window对象的常见事件页面（窗口）加载事件（2种）第1种window.onload 是窗口 (页面）加载事件，当文档内容完全加载完成会触发该事件(包括图像、脚本文件、CSS 文件等), 就调用的处理函数。第2种​ DOMContentLoaded 事件触发时，仅当DOM加载完成，不包括样式表，图片，flash等等。​ IE9以上才支持！！！​ 如果页面的图片很多的话, 从用户访问到onload触发可能需要较长的时间, 交互效果就不能实现，必然影响用户的体验，此时用 DOMContentLoaded 事件比较合适。 调整窗口大小事件​ window.onresize 是调整窗口大小加载事件, 当触发时就调用的处理函数。注意： 只要窗口大小发生像素变化，就会触发这个事件。 我们经常利用这个事件完成响应式布局。 window.innerWidth 当前屏幕的宽度 1.2.5. 定时器（两种）window 对象给我们提供了 2 个非常好用的方法-定时器。 setTimeout() setInterval() setTimeout() 炸弹定时器开启定时器普通函数是按照代码顺序直接调用。 简单理解： 回调，就是回头调用的意思。上一件事干完，再回头再调用这个函数。 例如：定时器中的调用函数，事件处理函数，也是回调函数。 以前我们讲的 element.onclick = function(){} 或者 element.addEventListener(“click”, fn); 里面的 函数也是回调函数。 案例：5秒后关闭广告 停止定时器 点击停止定时器 setInterval() 闹钟定时器开启定时器 案例：倒计时 1 2 3 停止定时器案例：发送短信倒计时​ 点击按钮后，该按钮60秒之内不能再次点击，防止重复发送短信。 手机号码： 发送 1.2.6. this指向问题​ this的指向在函数定义的时候是确定不了的，只有函数执行的时候才能确定this到底指向谁，一般情况下this的最终指向的是那个调用它的对象。现阶段，我们先了解一下几个this指向 全局作用域或者普通函数中this指向全局对象window（注意定时器里面的this指向window） 方法调用中谁调用this指向谁 构造函数中this指向构造函数的实例 点击 1.2.7. location对象什么是 location 对象URLlocation 对象的属性案例：5分钟自动跳转页面 点击 案例：获取URL参数 location对象的常见方法 点击 1.2.8. navigator对象​ navigator 对象包含有关浏览器的信息，它有很多属性，我们最常用的是 userAgent，该属性可以返回由客户机发送服务器的 user-agent 头部的值。下面前端代码可以判断用户那个终端打开页面，实现跳转if((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))) { window.location.href = ""; //手机 } else { window.location.href = ""; //电脑 } 1.2.9 history对象​ window对象给我们提供了一个 history对象，与浏览器历史记录进行交互。该对象包含用户（在浏览器窗口中）访问过的URL。history对象一般在实际开发中比较少用，但是会在一些 OA 办公系统中见到。1.3. JS执行机制以下代码执行的结果是什么？ console.log(1); setTimeout(function () { console.log(3); }, 1000); console.log(2); 以下代码执行的结果是什么？ console.log(1); setTimeout(function () { console.log(3); }, 0); console.log(2); 1.3.1 JS 是单线程 单线程就意味着，所有任务需要排队，前一个任务结束，才会执行后一个任务。如果前一个任务耗时很长，后一个任务就不得不一直等着。 这样所导致的问题是： 如果 JS 执行的时间过长，这样就会造成页面的渲染不连贯，导致页面渲染加载阻塞的感觉。 1.3.2 同步任务和异步任务​ 单线程导致的问题就是后面的任务等待前面任务完成，如果前面任务很耗时（比如读取网络数据），后面任务不得不一直等待！！​ 为了解决这个问题，利用多核 CPU 的计算能力，HTML5 提出 Web Worker 标准，允许 JavaScript 脚本创建多个线程，但是子线程完全受主线程控制。于是，JS 中出现了同步任务和异步任务。同步​ 前一个任务结束后再执行后一个任务，程序的执行顺序与任务的排列顺序是一致的、同步的。比如做饭的同步做法：我们要烧水煮饭，等水开了（10分钟之后），再去切菜，炒菜。异步​ 你在做一件事情时，因为这件事情会花费很长时间，在做这件事的同时，你还可以去处理其他事情。比如做饭的异步做法，我们在烧水的同时，利用这10分钟，去切菜，炒菜。JS中所有任务可以分成两种，一种是同步任务（synchronous），另一种是异步任务（asynchronous）。 同步任务指的是： 在主线程上排队执行的任务，只有前一个任务执行完毕，才能执行后一个任务； 异步任务指的是： 不进入主线程、而进入”任务队列”的任务，当主线程中的任务运行完了，才会从”任务队列”取出异步任务放入主线程执行。 1.3.3 JS执行机制（事件循环）1.3.4 代码思考题 console.log(1); document.onclick = function() { console.log('click'); } setTimeout(function() { console.log(3) }, 3000) console.log(2);
1.1. 节点操作1.1.1 删除节点node.removeChild() 方法从 node节点中删除一个子节点，返回删除的节点。 删除 熊大 熊二 光头强 1.1.2 案例：删除留言 发布 1.1.3 复制（克隆）节点 1111 2 3 1.1.4 案例：动态生成表格 1.1.5 创建元素的三种方式 1.1.6 innerTHML和createElement效率对比innerHTML字符串拼接方式（效率低） createElement方式（效率一般） innerHTML数组方式（效率高） 1.2. DOM的核心总结关于dom操作，我们主要针对于元素的操作。主要有创建、增、删、改、查、属性操作、事件操作。1.2.1. 创建1.2.2. 增加1.2.3. 删1.2.4. 改1.2.5. 查1.2.6. 属性操作1.2.7. 事件操作（重点）1.3. 事件高级1.3.1. 注册事件（2种方式）1.3.2 事件监听addEventListener()事件监听（IE9以后支持）eventTarget.addEventListener()方法将指定的监听器注册到 eventTarget（目标对象）上，当该对象触发指定的事件时，就会执行事件处理函数。attacheEvent()事件监听（IE678支持）​ eventTarget.attachEvent()方法将指定的监听器注册到 eventTarget（目标对象） 上，当该对象触发指定的事件时，指定的回调函数就会被执行。 传统注册事件 方法监听注册事件 ie9 attachEvent 事件监听兼容性解决方案封装一个函数，函数中判断浏览器的类型：1.3.3. 删除事件（解绑事件） 1 2 3 **删除事件兼容性解决方案 **1.3.4. DOM事件流html中的标签都是相互嵌套的，我们可以将元素想象成一个盒子装一个盒子，document是最外面的大盒子。 当你单击一个div时，同时你也单击了div的父元素，甚至整个页面。 那么是先执行父元素的单击事件，还是先执行div的单击事件 ？？？ 比如：我们给页面中的一个div注册了单击事件，当你单击了div时，也就单击了body，单击了html，单击了document。当时的2大浏览器霸主谁也不服谁！ IE 提出从目标元素开始，然后一层一层向外接收事件并响应，也就是冒泡型事件流。 Netscape（网景公司）提出从最外层开始，然后一层一层向内接收事件并响应，也就是捕获型事件流。 江湖纷争，武林盟主也脑壳疼！！！ 最终，w3c 采用折中的方式，平息了战火，制定了统一的标准 —--— 先捕获再冒泡。 现代浏览器都遵循了此标准，所以当事件发生时，会经历3个阶段。 DOM 事件流会经历3个阶段： 捕获阶段 当前目标阶段 冒泡阶段 ​ 我们向水里面扔一块石头，首先它会有一个下降的过程，这个过程就可以理解为从最顶层向事件发生的最具体元素（目标点）的捕获过程；之后会产生泡泡，会在最低点（ 最具体元素）之后漂浮到水面上，这个过程相当于事件冒泡。事件冒泡 son盒子 事件捕获 son盒子 1.3.5. 事件对象什么是事件对象事件发生后，跟事件相关的一系列信息数据的集合都放到这个对象里面，这个对象就是事件对象。比如： 谁绑定了这个事件。 鼠标触发事件的话，会得到鼠标的相关信息，如鼠标位置。 键盘触发事件的话，会得到键盘的相关信息，如按了哪个键。 事件对象的使用事件触发发生时就会产生事件对象，并且系统会以实参的形式传给事件处理函数。所以，在事件处理函数中声明1个形参用来接收事件对象。事件对象的兼容性处理事件对象本身的获取存在兼容问题： 标准浏览器中是浏览器给方法传递的参数，只需要定义形参 e 就可以获取到。 在 IE6~8 中，浏览器不会给方法传递参数，如果需要的话，需要到 window.event 中获取查找。 只要“||”前面为false, 不管“||”后面是true 还是 false，都返回 “||” 后面的值。 只要“||”前面为true, 不管“||”后面是true 还是 false，都返回 “||” 前面的值。 123 事件对象的属性和方法e.target 和 this 的区别 this 是事件绑定的元素（绑定这个事件处理函数的元素） 。 e.target 是事件触发的元素。 常情况下terget 和 this是一致的， 但有一种情况不同，那就是在事件冒泡时（父子元素有相同事件，单击子元素，父元素的事件处理函数也会被触发执行）， 这时候this指向的是父元素，因为它是绑定事件的元素对象， 而target指向的是子元素，因为他是触发事件的那个具体元素对象。 123 事件冒泡下的e.target和this abc abc abc 1.3.6 阻止默认行为html中一些标签有默认行为，例如a标签被单击后，默认会进行页面跳转。 百度 1.3.7 阻止事件冒泡事件冒泡本身的特性，会带来的坏处，也会带来的好处。 son儿子 阻止事件冒泡的兼容性处理1.3.8 事件委托事件冒泡本身的特性，会带来的坏处，也会带来的好处。什么是事件委托把事情委托给别人，代为处理。 事件委托也称为事件代理，在 jQuery 里面称为事件委派。说白了就是，不给子元素注册事件，给父元素注册事件，把处理代码在父元素的事件中执行。生活中的代理：js事件中的代理：事件委托的原理​ 给父元素注册事件，利用事件冒泡，当子元素的事件触发，会冒泡到父元素，然后去控制相应的子元素。事件委托的作用 我们只操作了一次 DOM ，提高了程序的性能。 动态新创建的子元素，也拥有事件。 知否知否，点我应有弹框在手！ 知否知否，点我应有弹框在手！ 知否知否，点我应有弹框在手！ 知否知否，点我应有弹框在手！ 知否知否，点我应有弹框在手！ 1.4. 常用鼠标事件1.4.1 案例：禁止选中文字和禁止右键菜单 我是一段不愿意分享的文字 1.4.2 鼠标事件对象1.4.3 获取鼠标在页面的坐标 1.4.4 案例：跟随鼠标的天使
1.1. 排他操作1.1.1 排他思想如果有同一组元素，我们想要某一个元素实现某种样式， 需要用到循环的排他思想算法： 所有元素全部清除样式（干掉其他人） 给当前元素设置样式 （留下我自己） 注意顺序不能颠倒，首先干掉其他人，再设置自己 按钮1 按钮2 按钮3 按钮4 按钮5 1.2 案例：百度换肤 1.3 案例：表格隔行变色 1.4 案例：全选 1.5. 自定义属性操作1.5.1 获取属性值 1.5.2. 设置属性值 // 2. 设置元素属性值 // (1) element.属性= '值' div.id = 'test'; div.className = 'navs'; // (2) element.setAttribute('属性', '值'); 主要针对于自定义属性 div.setAttribute('index', 2); div.setAttribute('class', 'footer'); // class 特殊 这里面写的就是 1.5.3. 移出属性 // class 不是className // 3 移除属性 removeAttribute(属性) div.removeAttribute('index'); 1.5.4. 案例：tab栏 1.5.5. H5自定义属性自定义属性目的：是为了保存并使用数据。有些数据可以保存到页面中而不用保存到数据库中。自定义属性获取是通过getAttribute(‘属性’) 获取。但是有些自定义属性很容易引起歧义，不容易判断是元素的内置属性还是自定义属性。H5给我们新增了自定义属性： 1.6. 节点操作1.6.1. 节点概述​ 网页中的所有内容都是节点（标签、属性、文本、注释等），在DOM 中，节点使用 node 来表示。​ HTML DOM 树中的所有节点均可通过 JavaScript 进行访问，所有 HTML 元素（节点）均可被修改，也可以创建或删除。​ 一般地，节点至少拥有nodeType（节点类型）、nodeName（节点名称）和nodeValue（节点值）这三个基本属性。1.6.2. 节点层级​ 利用 DOM 树可以把节点划分为不同的层级关系，常见的是父子兄层级关系。​ 1.6.3. 父级节点 × 1.6.4. 子节点所有子节点子元素节点 我是li 我是li 我是li 我是li 第1个子节点最后1个子节点第1个子元素节点最后1个子元素节点​ 实际开发中，firstChild 和 lastChild 包含其他节点，操作不方便，而 firstElementChild 和 lastElementChild 又有兼容性问题，那么我们如何获取第一个子元素节点或最后一个子元素节点呢？ 我是li1 我是li2 我是li3 我是li4 我是li5 1.6.5. 案例：新浪下拉菜单 1.6.6. 兄弟节点下一个兄弟节点上一个兄弟节点 我是div 我是span 下一个兄弟元素节点（有兼容性问题）上一个兄弟元素节点（有兼容性问题） function getNextElementSibling(element) { var el = element; while (el = el.nextSibling) { if (el.nodeType === 1) { return el; } } return null; } 1.6.7. 创建节点1.6.8. 添加节点 123 1.6.9. 案例：简单版发布留言 发布
1.1. Web API介绍1.1.1 API的概念API（Application Programming Interface，应用程序编程接口）是一些预先定义的函数，目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力，而又无需访问源码，无需理解其内部工作机制细节，只需直接调用使用即可。举例解释什么是API。例如，​ C语言中有一个函数 fopen()可以打开硬盘上的文件，这个函数对于我们来说，就是一个C语言提供的打开文件的工具。​ javascript中有一个函数alert()可以在页面弹一个提示框，这个函数就是js提供的一个弹框工具。这些工具（函数）由编程语言提供，内部的实现已经封装好了，我们只要学会灵活的使用这些工具即可。1.1.2 Web API的概念​ Web API 是浏览器提供的一套操作浏览器功能和页面元素的 API ( BOM 和 DOM )。​ 现阶段我们主要针对于浏览器讲解常用的 API , 主要针对浏览器做交互效果。比如我们想要浏览器弹出一个警示框， 直接使用 alert(‘弹出’)​ MDN 详细 API : https://developer.mozilla.org/zh-CN/docs/Web/API​ 因为 Web API 很多，所以我们将这个阶段称为 Web APIs。​ 此处的 Web API 特指浏览器提供的一系列API(很多函数或对象方法)，即操作网页的一系列工具。例如：操作html标签、操作页面地址的方法。1.1.3 API 和 Web API 总结 API 是为我们程序员提供的一个接口，帮助我们实现某种功能，我们会使用就可以了，不必纠结内部如何实现 Web API 主要是针对于浏览器提供的接口，主要针对于浏览器做交互效果。 Web API 一般都有输入和输出（函数的传参和返回值），Web API 很多都是方法（函数） 学习 Web API 可以结合前面学习内置对象方法的思路学习 1.2. DOM 介绍1.2.1 什么是DOM​ 文档对象模型（Document Object Model，简称DOM），是 W3C 组织推荐的处理可扩展标记语言（html或者xhtml）的标准编程接口。​ W3C 已经定义了一系列的 DOM 接口，通过这些 DOM 接口可以改变网页的内容、结构和样式。DOM是W3C组织制定的一套处理 html和xml文档的规范，所有的浏览器都遵循了这套标准。1.2.2. DOM树DOM树 又称为文档树模型，把文档映射成树形结构，通过节点对象对其处理，处理的结果可以加入到当前的页面。 文档：一个页面就是一个文档，DOM中使用document表示 节点：网页中的所有内容，在文档树中都是节点（标签、属性、文本、注释等），使用node表示 标签节点：网页中的所有标签，通常称为元素节点，又简称为“元素”，使用element表示 1.3. 获取元素为什么要获取页面元素？例如：我们想要操作页面上的某部分(显示/隐藏，动画)，需要先获取到该部分对应的元素，再对其进行操作。1.3.1. 根据ID获取语法：document.getElementById(id) 作用：根据ID获取元素对象 参数：id值，区分大小写的字符串 返回值：元素对象 或 null 案例代码 2019-9-9 1.3.2. 根据标签名获取元素语法：document.getElementsByTagName('标签名') 或者 element.getElementsByTagName('标签名') 作用：根据标签名获取元素对象 参数：标签名 返回值：元素对象集合（伪数组，数组元素是元素对象） 案例代码 知否知否，应是等你好久11 知否知否，应是等你好久22 知否知否，应是等你好久33 知否知否，应是等你好久44 知否知否，应是等你好久55 生僻字 生僻字 生僻字 生僻字 生僻字 注意：getElementsByTagName()获取到是动态集合，即：当页面增加了标签，这个集合中也就增加了元素。1.3.3. H5新增获取元素方式案例代码 盒子1 盒子2 首页 产品 1.3.4 获取特殊元素（body，html）1.4. 事件基础1.4.1. 事件概述JavaScript 使我们有能力创建动态页面，而事件是可以被 JavaScript 侦测到的行为。简单理解： 触发--- 响应机制。​ 网页中的每个元素都可以产生某些可以触发 JavaScript 的事件，例如，我们可以在用户点击某按钮时产生一个 事件，然后去执行某些操作。1.4.2. 事件三要素 事件源（谁）：触发事件的元素 事件类型（什么事件）： 例如 click 点击事件 事件处理程序（做啥）：事件触发后要执行的代码(函数形式)，事件处理函数 案例代码 唐伯虎 1.4.3. 执行事件的步骤案例代码 123 1.4.4. 常见的鼠标事件1.4.5. 分析事件三要素 下拉菜单三要素 关闭广告三要素 1.5. 操作元素​ JavaScript的 DOM 操作可以改变网页内容、结构和样式，我们可以利用 DOM 操作元素来改变元素里面的内容、属性等。（注意：这些操作都是通过元素对象的属性实现的）1.5.1. 改变元素内容（获取或设置）innerText改变元素内容 显示当前系统时间 某个时间 1123 innerText和innerHTML的区别 获取内容时的区别： ​ innerText会去除空格和换行，而innerHTML会保留空格和换行 设置内容时的区别： ​ innerText不会识别html，而innerHTML会识别案例代码 我是文字 123 1.5.2. 常用元素的属性操作获取属性的值元素对象.属性名设置属性的值元素对象.属性名 = 值案例代码 刘德华 张学友 1.5.3. 案例：分时问候1.5.4. 表单元素的属性操作获取属性的值元素对象.属性名设置属性的值元素对象.属性名 = 值表单元素中有一些属性如：disabled、checked、selected，元素对象的这些属性的值是布尔型。案例代码 按钮 1.5.5. 案例：仿京东显示密码1.5.6. 样式属性操作我们可以通过 JS 修改元素的大小、颜色、位置等样式。常用方式方式1：通过操作style属性元素对象的style属性也是一个对象！元素对象.style.样式属性 = 值;案例代码 案例：淘宝点击关闭二维码案例：循环精灵图背景案例：显示隐藏文本框内容方式2：通过操作className属性元素对象.className = 值;因为class是关键字，所有使用className。案例代码 文本 案例：密码框格式提示错误信息1.6. 今日总结