DOMdom工作原理:1.代码从硬盘 读取到内存(代码)2.生成dom树*修改了dom树,最终渲染的页面也会改变3.渲染引擎开始渲染dom树(页面)查询页面元素1.获取单个元素 ： document.querySelector('选择器') * @description: 获取满足条件的第一个元素 * @param {string} 选择器字符串 * @return: dom对象 | null 2.获取多个元素 : document.querySelectorAll('选择器') * @description: 获取满足条件 所有元素 * @param {string} 选择器字符串 * @return: 一定是伪数组 （有三要素下标、元素、长度。 但是没有数组方法 ） 元素的内容操作(1)元素.innerText; 只能操作文本,不能解析html标签.(2)元素.innerHTML;可以解析html标签元素的属性操作(1)1.获取属性 元素.属性名(2)2.设置属性 元素.属性名 = 值dom事件分为两类鼠标事件:(1)鼠标单击事件:onclick(2)鼠标双击事件:ondblclick(3)鼠标移入事件:onmouseenter(4)鼠标移出事件:onmouseleave(5)鼠标移动事件:onmousemove键盘事件:(1)onfocus:键盘成为焦点(2)onblur:键盘失去焦点(3)oninput:键盘输入(实时获取输入框内容:字数统计+模糊查询)(4)onkeydown:键盘按下(监听enter键)(5)onkeyup:键盘松开input.addEventListener('keydown', function (e) { console.log('键盘按下'); e.key == 'Enter' }) 元素className和classLIst操作样式 (1)修改单个样式： (2)修改多个样式： (3)修改多个样式： //通过className操作类名:元素.className='类名' //先获取元素 let box = document.querySelector('.box') //1.获取类名 : //由于class是js中的关键字,所以要用className console.log(box.className) //2.设置类名 : //box.className='类名' className会覆盖以前的类名 // box.className = 'one' //通过classList操作类名 // 新增类名 // 元素.classList.add('类名') box.classList.add('two') //删除类名 // 元素.classList.remove('类名') box.classList.remove('one') //切换类名 有则移除,无则新曾 // 元素.classList.toggle('类名') box.classList.toggle('two') //判断类名 // 元素.classList.contains('类名') // true:有类名 false:没有 box.classList.contains('two') 事件及注册事件/* 1.交互功能 : 什么元素 在什么时刻 做什么事情 2.事件三要素 事件源 : 什么元素 事件类型 : 什么时刻 事件处理函数 : 做什么事 3.注册事件 ： 给元素添加交互 事件源.事件类型 = 事件处理函数 4.事件原理及注意点 (1)事件处理函数在注册的时候不会执行. (函数在声明的时候不会执行) (2)事件处理函数只有两种情况可以执行 第一种： 用户主动触发交互， 浏览器会捕捉交互，底层会自动帮我们调用对象的方法 第二种： 手动调用对象事件处理函数 */ let box = document.querySelector('.box') box.addEventListener('click', function () { box.style.backgroundColor = 'blue' }) 排他思想 1.排他思想场景 ： 多个元素,只能选中一个 2.排他思想流程 ：两种思路 循环排他(万能的) :(1)循环干掉所有兄弟 (2)复活自己 类名排他(一定要有类名):(1)使用类名选择器干掉选中的兄弟 (2)复活自己 总结:元素有类名就用类名排他,没有类就用循环排他 .切记两者不可混用 类名排他:通过classList类名修改样式 循环排他 通过style修改样式1.事件源 ： 输入框 2.事件类型： onfouces: 成为焦点。 点击输入框出现光标的时候（此时用户可以输入文字） onblur: 失去焦点。 点击空白区域输入框光标消失的时候（此时用户不可以输入文字）开关思想2.开关思想 ： 判断数组中是否所有元素都满足条件 (1)声明开关变量 : 默认都满足 (2)检测开关变量 : 遍历数组,找不满足 (3)获取开关变量 开关思想应用场景举例： (1)检测购物车是否所有商品都选中 (2)检测注册是否每一个表单都填写数据 //需求1： 判断数组中是否所有元素都大于0 //都大于0 ： 打印true 不是都大于0： false let arr1 = [20,66,0,80,90,100] //(1)声明开关变量 let flag = true //(2)检测开关变量的值是否正确 for(let i = 0;i<arr1.length;i++){ if( arr1[i] <= 0 ){ flag = false break } } //(3)开关结果 console.log( flag ) attribute语法学习自定义属性 : html本身没有的属性 属性作用 ： 存储数据 1.获取自定义属性 ： 元素.getAttribute('属性名') 2.设置自定义属性 ： 元素.setAttribute('属性名',属性值) 3.移除自定义属性 ： 元素.removeAttribute('属性名') let box = document.querySelector('#box') //1.获取自定义属性(有返回值) console.log( box.getAttribute('aaa') ) //2.设置 自定义属性 box.setAttribute('aaa','1111')//覆盖 box.setAttribute('bbb','2222')//新增 //3. 移除 自定义属性 box.removeAttribute('bbb','2222')DOM节点节点增删改查 1.查节点 : 查子元素: 元素.children 查兄弟元素: 上一个元素： 元素.previousElementSibling 下一个元素： 元素.nextElementSibling 查父元素 : 元素.parentNode 2.增 ： document.createElement() (1)内存创建空节点： document.createElement('标签名') (2)设置标签内容 (3)添加到页面dom 新增到最后面 ： 父元素.appendChild(元素) 新增到元素前面 ： 父元素.insertBefore(要加的元素,哪一个元素前面)[ document.write('') 开发中几乎不用 元素.innerHTML = '' 新增100以内的元素的时候可以用 覆盖操作： 元素.innerHTML = ' 标题 ' 新增操作： 元素.innerHTML += ' 标题 '] 3.删 ： 父元素.removeChild(子元素)克隆节点 ： 复制节点 元素.cloneNode(true) 默认false : 浅克隆，只克隆元素自身 true : 深克隆，克隆元素自身 + 所有后代元素 定时器: 1.定时器作用 ： 一段代码 间隔时间 重复执行回调函数:如果一个函数的参数也是函数,那么这个函数就叫做回调函数 2.定时器语法 ： * @description:开启定时器 * @param {function} *回调函数:如果一个函数的参数也是函数,那么这个函数就叫做回调函数 * @param {number}间隔时间 单位 毫秒 1s=1000 * @return: 定时器ID * 一个浏览器可以开启很多个不同的定时器,浏览器伪类便于管理,会给每一个定时器一个编号,我们称之为ID 2.1.永久定时器:一旦开启,自动永久执行,只能手动清除 (1)开启定时器 setInterval(function(){},间隔时间) (2)清除定时器:clearInterval(timeID) 2.2 一次定时器:间隔时间只会执行一次,执行完毕后会自动清除 (1)开启定时器:let timeID=setTimeout(function(){},间隔时间) 间隔时间为毫秒数 (2)清除定时器:clearInterval(timeID) 事件监听:1.点语法注册事件: 事件源.事件类型 = 事件处理函数 * 特点：不能注册‘同名事件’， 否则会覆盖 2.事件源.addEventListener('事件类型',事件处理函数) * 特点：可以注册‘同名事件’，依次触发 移除事件监听:1.事件源.事件类型=null(传统)2.事件源.removeEventListener('事件类型',事件处理函数)阻止默认事件:html中有部分标签自带点击事件 ： form表单,a标签 2.如果给这些标签注册点击事件，会默认跳转 3. 阻止默认事件 ： 执行自己注册的事件 e.preventDefault()表单清空(重置表单):form对象.reser()事件冒泡与捕获 1.事件冒泡 : 当触发子元素的事件时候，所有的父级元素‘同名事件’会被依次触发 1.1 规则： 子元素->父元素->body->html->document->window 1.2 应用场景： 事件委托技术 事件委托:事件委托 : 给父元素注册事件,委托给子元素处理 2.1事件委托底层原理 :事件冒泡 2.2事件委托应用:给动态新增li元素注册事件 2.3事件委托注意点: 不能使用this:this代表事件源,指向父元素 需要使用e.target:事件目标(触发本次冒泡的子元素) 2.事件捕获 : 当触发子元素的事件时候，先从最顶级父元素，一级一级往里触发 1.1 规则： window->document->html->body->父元素->子元素 3.默认情况下，所有的注册事件都是冒泡事件。 只有唯一一种方式可以注册捕获事件： 元素.addEventListener('事件类型',事件处理函数,true) 4.事件流三个阶段： e.eventPhase 1-捕获阶段 2-目标阶段 3-冒泡阶段 5.阻止事件流动 ： e.stopPropagation() 写在哪个事件处理函数中,就从哪里开始阻止 三大家族offset家族 : 获取元素 ‘自身’ 的真实宽高 和 真实位置 offsetWidth / offsetHeight : 获取 width+padding+border offsetLeft / offsetTop : 获取 左/上 外边框 到定位父元素 左/上 内边框距离scroll家族 : 获取元素 ‘内容’ 的真实宽高 和 位置 scrollWidth / scrollHeight : 获取内容的宽高 scrollLeft / scrollTop : 内容的位置（就是滚动条滚动的距离） 获取网页滚动距离 1.给页面注册滚动事件 : window.onscroll 2.获取页面滚动距离 : document.documentElement.scrollTop 3.client家族 : 获取元素 ‘可视区域’ 宽高 和 位置 clientWidth / clientHeight : 可视区域大小 clientLeft / clientTop : 可视区域位置（就是左边框 和 上边框 宽度） (1)js中几乎所有的内置对象，都是通过new来创建的 new Date() new RegExp() new Array() new Object() (2)js中有三种内置对象有简写语法 数组: [] 对象: {} 正则: /正则/ npm上传连接npm命令:npm adduser这个命令需要输入四个信息以供连接上npmjs：● 用户名● 密码● 邮箱（是你在npmjs官网上注册时使用的信息）● 校验密码。它会向你的邮箱发邮件如果你已经不是第一次连接了，这一步是可以省略的 你也可以通过如下命令检查自己是否连接成功了。npm who am inpm logout把包上传到npm命令： npm publish 如果成功:----------------------------------- npm notice npm notice package: tool61@1.0.0 npm notice === Tarball Contents === npm notice 1.3kB index.js npm notice 220B package.json npm notice === Tarball Details === npm notice name: tool61 npm notice version: 1.0.0 npm notice package size: 855 B npm notice unpacked size: 1.5 kB npm notice shasum: 3bfba7bc92e242810a850ac39ded7ebe992a6d9c npm notice integrity: sha512-VoRuxxbcGzXen[...]v3tKWYUT1B1AQ== npm notice total files: 2 npm notice + tool61@1.0.0出错的可能是：● 这个包名被别人先用了。● 包的版本号不对：每次publish时，包的版本号都应该要大于之前的版本号。文件过大。你可能需要创建.npmignore文件来设置在打包时要忽略哪些文件。如下是一个demo.# .npmignore /node_modules npm-debug.log /src /examples /build如果没有报错，则表示一切ok，你可以用你的帐号密码登陆npm，去查看你名下的package是否有了myNpm下载使用通过npm install 包名即可来安装包。 然后，告诉你的小伙伴们去下载使用吧。删除包npm unpublish --force //强制删除如果你的包没有什么用处，建议删除掉，以节约公共资源。更新包修改代码，保存。更新版本号。可直接在package.json中修改：只能改大，不能改小。重新publish