来自Pink老师的学习内容,对于常用Js操作整理归纳。
获取元素
先有元素才能获取
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 var myBox = document.getElementById("box"); //通过 id 获取单个元素 var boxArr = document.getElementsByClassName("box"); //通过 class 获取的是数组 var divArr = document.getElementsByTagName("div"); //通过标签获取的是数组 H5新增 // 1. getElementsByClassName 根据类名获得某些元素集合 var boxs = document.getElementsByClassName('box'); console.log(boxs); // 2. querySelector 返回指定选择器的第一个元素对象 切记 里面的选择器需要加符号 .box #nav var firstBox = document.querySelector('.box'); console.log(firstBox); var nav = document.querySelector('#nav'); console.log(nav); var li = document.querySelector('li'); console.log(li); // 3. querySelectorAll()返回指定选择器的所有元素对象集合 var allBox = document.querySelectorAll('.box'); console.log(allBox); var lis = document.querySelectorAll('li'); console.log(lis);
事件三要素
事件是有三部分组成 事件源 事件类型 事件处理程序 我们也称为事件三要素
1 2 3 4 5 6 7 8 9 10 // 执行事件步骤 // 点击div 控制台输出 我被选中了 // 1. 获取事件源 var div = document.querySelector('div'); // 2.绑定事件 注册事件 // div.onclick // 3.添加事件处理程序 div.onclick = function() { console.log('我被选中了'); }
元素操作
改变内容
div.innerHTML = ‘今天是: 2019’;
// innerText 和 innerHTML的区别 // 1. innerText 不识别html标签 非标准 去除空格和换行 // 2. innerHTML 识别html标签 W3C标准 保留空格和换行的
修改样式用.style 后面的属性用驼峰法
this.style.backgroundColor = ‘#6ec’;
box.style.display = ‘none’;
this.className = ‘first change’;//更改class样式
this.style.color = ‘#999’;
document.body.style.backgroundColor = ‘#fff’;
排他思想
先全部,在改单独的 css里面的简写属性也是这个概念
1 2 3 4 5 6 7 8 9 10 11 12 13 14 //1. 获取所有按钮元素 var btns = document.getElementsByTagName('button'); // btns得到的是伪数组 里面的每一个元素 btns[i] for (var i = 0; i < btns.length; i++) { btns[i].onclick = function() { // (1) 我们先把所有的按钮背景颜色去掉 干掉所有人 for (var i = 0; i < btns.length; i++) { btns[i].style.backgroundColor = ''; } // (2) 然后才让当前的元素背景颜色为pink 留下我自己 this.style.backgroundColor = 'pink'; }//大同特异 } //2. 首先先排除其他人,然后才设置自己的样式 这种排除其他人的思想我们成为排他思想
背景换图片
1 2 3 4 5 6 7 8 9 10 11 12 // 1. 获取元素 ,,链式 var imgs = document.querySelector('.baidu').querySelectorAll('img'); // console.log(imgs); // 2. 循环注册事件 for (var i = 0; i < imgs.length; i++) { imgs[i].onclick = function() { // this.src 就是我们点击图片的路径 images/2.jpg // console.log(this.src); // 把这个路径 this.src 给body 就可以了 document.body.style.backgroundImage = 'url(' + this.src + ')'; } }
常用功能
全选和反选
全选直接全部设置 判读是否全选,循环看看有没有不是选中的 反选,取反
tab栏切换节点操作
两次排他,一次样式,一次显示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 // 获取元素 var tab_list = document.querySelector('.tab_list'); var lis = tab_list.querySelectorAll('li'); var items = document.querySelectorAll('.item'); // for循环绑定点击事件 for (var i = 0; i < lis.length; i++) { // 开始给5个小li 设置索引号 lis[i].setAttribute('index', i); lis[i].onclick = function() { // 1. 上的模块选项卡,点击某一个,当前这一个底色会是红色,其余不变(排他思想) 修改类名的方式 // 干掉所有人 其余的li清除 class 这个类 for (var i = 0; i < lis.length; i++) { lis[i].className = ''; } // 留下我自己 this.className = 'current'; // 2. 下面的显示内容模块 var index = this.getAttribute('index'); console.log(index); // 干掉所有人 让其余的item 这些div 隐藏 排他 for (var i = 0; i < items.length; i++) { items[i].style.display = 'none'; } // 留下我自己 让对应的item 显示出来 items[index].style.display = 'block'; } }
节点操作
获取父节点
console.log(erweima.parentNode);
获取子节点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // 1. 子节点 childNodes 所有的子节点 包含 元素节点 文本节点等等 console.log(ul.childNodes); console.log(ul.childNodes[0].nodeType); console.log(ul.childNodes[1].nodeType); // 2. children 获取所有的子元素节点 也是我们实际开发常用的 console.log(ul.children); // 1. firstChild 第一个子节点 不管是文本节点还是元素节点 console.log(ol.firstChild); console.log(ol.lastChild); // 2. firstElementChild 返回第 一个子元素节点 ie9才支持 console.log(ol.firstElementChild); console.log(ol.lastElementChild); // 3. 实际开发的写法 既没有兼容性问题又返回第一个子元素 console.log(ol.children[0]); console.log(ol.children[ol.children.length - 1]);
获取兄弟节点
1 2 3 4 5 6 // 1.nextSibling 下一个兄弟节点 包含元素节点或者 文本节点等等 console.log(div.nextSibling); console.log(div.previousSibling); // 2. nextElementSibling 得到下一个兄弟元素节点 console.log(div.nextElementSibling); console.log(div.previousElementSibling);
创建节点
1 2 3 4 5 6 7 8 9 // 1. 创建节点元素节点 var li = document.createElement('li'); // 2. 添加节点 node.appendChild(child) node 父级 child 是子级 后面追加元素 类似于数组中的push var ul = document.querySelector('ul'); ul.appendChild(li); // 3. 添加节点 node.insertBefore(child, 指定元素); var lili = document.createElement('li'); ul.insertBefore(lili, ul.children[0]); // 4. 我们想要页面添加一个新的元素 : 1. 创建元素 2. 添加元素
删除节点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // 1.获取元素 var ul = document.querySelector('ul'); var btn = document.querySelector('button'); // 2. 删除元素 node.removeChild(child) // ul.removeChild(ul.children[0]); // 3. 点击按钮依次删除里面的孩子 btn.onclick = function() { if (ul.children.length == 0) { this.disabled = true; } else { ul.removeChild(ul.children[0]); } } 也可以从孩子找到父亲删除
节点克隆
1 2 3 4 5 var ul = document.querySelector('ul'); // 1. node.cloneNode(); 括号为空或者里面是false 浅拷贝 只复制标签不复制里面的内容 // 2. node.cloneNode(true); 括号为true 深拷贝 复制标签复制里面的内容 var lili = ul.children[0].cloneNode(true); ul.appendChild(lili);
动态生成表格
有了数据,写入数据…像是请求数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 // 1.先去准备好学生的数据 var datas = [{ name: '魏璎珞', subject: 'JavaScript', score: 100 }, { name: '弘历', subject: 'JavaScript', score: 98 }, { name: '傅恒', subject: 'JavaScript', score: 99 }, { name: '明玉', subject: 'JavaScript', score: 88 }, { name: '大猪蹄子', subject: 'JavaScript', score: 0 }]; // 2. 往tbody 里面创建行: 有几个人(通过数组的长度)我们就创建几行 var tbody = document.querySelector('tbody'); for (var i = 0; i < datas.length; i++) { // 外面的for循环管行 tr // 1. 创建 tr行 var tr = document.createElement('tr'); tbody.appendChild(tr); // 2. 行里面创建单元格(跟数据有关系的3个单元格) td 单元格的数量取决于每个对象里面的属性个数 for循环遍历对象 datas[i] for (var k in datas[i]) { // 里面的for循环管列 td // 创建单元格 var td = document.createElement('td'); // 把对象里面的属性值 datas[i][k] 给 td // console.log(datas[i][k]); td.innerHTML = datas[i][k]; tr.appendChild(td); } // 3. 创建有删除2个字的单元格 var td = document.createElement('td'); td.innerHTML = '<a href="javascript:;">删除 </a>'; tr.appendChild(td); } // 4. 删除操作 开始 var as = document.querySelectorAll('a'); for (var i = 0; i < as.length; i++) { as[i].onclick = function() { // 点击a 删除 当前a 所在的行(链接的爸爸的爸爸) node.removeChild(child) // 列 行 tbody.removeChild(this.parentNode.parentNode) } }
下拉菜单
显示与隐藏
三种创建元素区别
document.write() 创建元素 如果页面文档流加载完毕,再调用这句话会导致页面重绘
innerHTML 创建元素1 2 3 4 5 6 7 8 9 var inner = document.querySelector('.inner'); // for (var i = 0; i <= 100; i++) { // inner.innerHTML += '<a href="#">百度</a>' // } var arr = []; for (var i = 0; i <= 100; i++) { arr.push('<a href="#">百度</a>'); } inner.innerHTML = arr.join('');
document.createElement() 创建元素1 2 3 4 5 var create = document.querySelector('.create'); for (var i = 0; i <= 100; i++) { var a = document.createElement('a'); create.appendChild(a); }
事件对象
两种注册事件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 var btns = document.querySelectorAll('button'); // 1. 传统方式注册事件 btns[0].onclick = function() { alert('hi'); } btns[0].onclick = function() { alert('hao a u'); } // 2. 事件侦听注册事件 addEventListener // (1) 里面的事件类型是字符串 必定加引号 而且不带on // (2) 同一个元素 同一个事件可以添加多个侦听器(事件处理程序) btns[1].addEventListener('click', function() { alert(22); }) btns[1].addEventListener('click', function() { alert(33); }) // 3. attachEvent ie9以前的版本支持 btns[2].attachEvent('onclick', function() { alert(11); })
删除事件
重点: divs[1].addEventListener(‘click’, fn) // 里面的fn 不需要调用加小括号 function fn() { alert(22); divs[1].removeEventListener(‘click’, fn); }
还有把addEventListener换成attachEvent 注意里面的事件不一样,都是调用本身。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 var divs = document.querySelectorAll('div'); divs[0].onclick = function() { alert(11); // 1. 传统方式删除事件 divs[0].onclick = null; } // 2. removeEventListener 删除事件 divs[1].addEventListener('click', fn) // 里面的fn 不需要调用加小括号 function fn() { alert(22); divs[1].removeEventListener('click', fn); } // 3. detachEvent divs[2].attachEvent('onclick', fn1); function fn1() { alert(33); divs[2].detachEvent('onclick', fn1); }
事件对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 // 事件对象 var div = document.querySelector('div'); div.onclick = function(e) { // console.log(e); // console.log(window.event); // e = e || window.event; console.log(e); } // div.addEventListener('click', function(e) { // console.log(e); // }) // 1. event 就是一个事件对象 写到我们侦听函数的 小括号里面 当形参来看 // 2. 事件对象只有有了事件才会存在,它是系统给我们自动创建的,不需要我们传递参数 // 3. 事件对象 是 我们事件的一系列相关数据的集合 跟事件相关的 // 比如鼠标点击里面就包含了鼠标的相关信息,鼠标坐标啊, // 如果是键盘事件里面就包含的键盘事件的信息 比如 判断用户按下了那个键 // 4. 这个事件对象我们可以自己命名 比如 event 、 evt、 e // 5. 事件对象也有兼容性问题 ie678 通过 window.event 兼容性的写法 e = e || window.event;
常见事件对象的属性和方法
注意e.target 和this e.target指的是触发对象 this指的是绑定对象 e.currentarget和this相似
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 // 1. e.target 返回的是触发事件的对象(元素) this 返回的是绑定事件的对象(元素) // 区别 : e.target 点击了那个元素,就返回那个元素 this 那个元素绑定了这个点击事件,那么就返回谁 var div = document.querySelector('div'); div.addEventListener('click', function(e) { console.log(e.target); console.log(this); }) var ul = document.querySelector('ul'); ul.addEventListener('click', function(e) { // 我们给ul 绑定了事件 那么this 就指向ul console.log(this); console.log(e.currentTarget); // e.target 指向我们点击的那个对象 谁触发了这个事件 我们点击的是li e.target 指向的就是li console.log(e.target); }) // 了解兼容性 // div.onclick = function(e) { // e = e || window.event; // var target = e.target || e.srcElement; // console.log(target); // } // 2. 了解 跟 this 有个非常相似的属性 currentTarget ie678不认识
阻止事件默认行为
1 2 3 4 5 6 // 普通浏览器 e.preventDefault(); 方法 // e.preventDefault(); // 低版本浏览器 ie678 returnValue 属性 // e.returnValue; // 我们可以利用return false 也能阻止默认行为 没有兼容性问题 // 特点: return 后面的代码不执行了, 而且只限于传统的注册方式
阻止冒泡
1 2 3 阻止冒泡 dom 推荐的标准 stopPropagation() e.stopPropagation(); // stop 停止 Propagation 传播 e.cancelBubble = true; // 非标准 cancel 取消 bubble 泡泡
事件委托
利用冒泡的方法 事件委托的核心原理:给父节点添加侦听器, 利用事件冒泡影响每一个子节点 e.target用上了
1 2 3 4 5 6 var ul = document.querySelector('ul'); ul.addEventListener('click', function(e) { // alert('知否知否,点我应有弹框在手!'); // e.target 这个可以得到我们点击的对象 e.target.style.backgroundColor = 'pink'; })
鼠标事件对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 // 鼠标事件对象 MouseEvent document.addEventListener('click', function(e) { // 1. client 鼠标在可视区的x和y坐标 console.log(e.clientX); console.log(e.clientY); console.log('---------------------'); // 2. page 鼠标在页面文档的x和y坐标 console.log(e.pageX); console.log(e.pageY); console.log('---------------------'); // 3. screen 鼠标在电脑屏幕的x和y坐标 console.log(e.screenX); console.log(e.screenY); })
键盘事件
1 2 3 4 1. keyup 按键弹起的时候触发 2. keypress 按键按下的时候触发 不能识别功能键 比如 ctrl shift 左右箭头啊 3. keydown 按键按下的时候触发 能识别功能键 比如 ctrl shift 左右箭头啊 三个事件的执行顺序 keydown -- keypress -- keyup
// 键盘事件对象中的keyCode属性可以得到相应键的ASCII码值 // 1. 我们的keyup 和keydown事件不区分字母大小写 a 和 A 得到的都是65 // 2. 我们的keypress 事件 区分字母大小写 a 97 和 A 得到的是65
1 2 3 4 5 6 7 8 9 10 11 document.addEventListener('keyup', function(e) { // console.log(e); console.log('up:' + e.keyCode); // 我们可以利用keycode返回的ASCII码值来判断用户按下了那个键 if (e.keyCode === 65) { alert('您按下的a键'); } else { alert('您没有按下a键') } })
案例
定时器
setTimeout
执行一次,多少秒后执行
1 2 3 4 5 6 function callback() { console.log('爆炸了'); } var timer1 = setTimeout(callback, 3000); var timer2 = setTimeout(callback, 5000);
setTimeInterval
执行多次,按秒执行
1 2 3 setInterval(function() { console.log('继续输出'); }, 1000);
clearInterval
清除定时器
倒计时
定时器+字符串拼接
offset属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // offset 系列 var father = document.querySelector('.father'); var son = document.querySelector('.son'); // 1.可以得到元素的偏移 位置 返回的不带单位的数值 console.log(father.offsetTop); console.log(father.offsetLeft); // 它以带有定位的父亲为准 如果么有父亲或者父亲没有定位 则以 body 为准 console.log(son.offsetLeft); var w = document.querySelector('.w'); // 2.可以得到元素的大小 宽度和高度 是包含padding + border + width console.log(w.offsetWidth); console.log(w.offsetHeight); // 3. 返回带有定位的父亲 否则返回的是body console.log(son.offsetParent); // 返回带有定位的父亲 否则返回的是body console.log(son.parentNode); // 返回父亲 是最近一级的父亲 亲爸爸 不管父亲有没有定位
offset与style的区别
offset得到数字 style得到带px的值, 且获取方式不同 通常用offset来得到值,用style来设置 box.style.width = ‘300px’;
拖动的模态框
一个遮罩层 用offset + 鼠标事件 offset设置位置 鼠标设置操作
点击
移动
移出移动1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 // 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); }) })
client属性
client 宽度 和我们offsetWidth 最大的区别就是 不包含边框
scroll滚动事件当我们滚动条发生变化会触发的事件
动画原理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 // 动画原理 // 1. 获得盒子当前位置 // 2. 让盒子在当前位置加上1个移动距离 // 3. 利用定时器不断重复这个操作 // 4. 加一个结束定时器的条件 // 5. 注意此元素需要添加定位, 才能使用element.style.left var div = document.querySelector('div'); var timer = setInterval(function() { if (div.offsetLeft >= 400) { // 停止动画 本质是停止定时器 clearInterval(timer); } div.style.left = div.offsetLeft + 1 + 'px'; }, 30);
简单动画函数封装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 // 简单动画函数封装obj目标对象 target 目标位置 function animate(obj, target) { var timer = setInterval(function() { if (obj.offsetLeft >= target) { // 停止动画 本质是停止定时器 clearInterval(timer); } obj.style.left = obj.offsetLeft + 1 + 'px'; }, 30); } var div = document.querySelector('div'); var span = document.querySelector('span'); // 调用函数 animate(div, 300); animate(span, 200);
添加不同的定时器 每用一次都会有一个定时器 要用定时器,就要先清除定时器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 // 简单动画函数封装obj目标对象 target 目标位置 // 给不同的元素指定了不同的定时器 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); } var div = document.querySelector('div'); var span = document.querySelector('span'); var btn = document.querySelector('button'); // 调用函数 animate(div, 300); btn.addEventListener('click', function() { animate(span, 200); })
缓步动画
1 2 3 4 5 6 7 8 9 10 11 12 // 缓动动画函数封装obj目标对象 target 目标位置 // 思路: // 1. 让盒子每次移动的距离慢慢变小, 速度就会慢慢落下来。 // 2. 核心算法:(目标值 - 现在的位置) / 10 做为每次移动的距离 步长 // 3. 停止的条件是: 让当前盒子位置等于目标位置就停止定时器 // 匀速动画 就是 盒子是当前的位置 + 固定的值 10 // 缓动动画就是 盒子当前的位置 + 变化的值(目标值 - 现在的位置) / 10) 如果除的有小数,可以用Math 取整 来回移动:相减,大于0,+向左,小于0,-向右
classList使用
1 2 3 4 5 6 7 8 9 10 11 12 13 添加class类 // classList 返回元素的类名 var div = document.querySelector('div'); // console.log(div.classList[1]); // 1. 添加类名 是在后面追加类名不会覆盖以前的类名 注意前面不需要加. div.classList.add('three'); // 2. 删除类名 div.classList.remove('one'); // 3. 切换类 var btn = document.querySelector('button'); btn.addEventListener('click', function() { document.body.classList.toggle('bg'); })
本地存储
区别
sessionStorage 浏览器关闭时自动销毁
localStorage 存储在浏览器中,无期限
sessionStorage
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 console.log(localStorage.getItem('username')); var ipt = document.querySelector('input'); var set = document.querySelector('.set'); var get = document.querySelector('.get'); var remove = document.querySelector('.remove'); var del = document.querySelector('.del'); set.addEventListener('click', function() { // 当我们点击了之后,就可以把表单里面的值存储起来 var val = ipt.value; sessionStorage.setItem('uname', val); sessionStorage.setItem('pwd', val); }); get.addEventListener('click', function() { // 当我们点击了之后,就可以把表单里面的值获取过来 console.log(sessionStorage.getItem('uname')); }); remove.addEventListener('click', function() { // sessionStorage.removeItem('uname'); }); del.addEventListener('click', function() { // 当我们点击了之后,清除所有的 sessionStorage.clear(); });
localStorage
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <input type="text"> <button class="set">存储数据</button> <button class="get">获取数据</button> <button class="remove">删除数据</button> <button class="del">清空所有数据</button> <script> var ipt = document.querySelector('input'); var set = document.querySelector('.set'); var get = document.querySelector('.get'); var remove = document.querySelector('.remove'); var del = document.querySelector('.del'); set.addEventListener('click', function() { var val = ipt.value; localStorage.setItem('username', val); }) get.addEventListener('click', function() { console.log(localStorage.getItem('username' }) remove.addEventListener('click', function() { localStorage.removeItem('username }) del.addEventListener('click', function() { localStorage.clear })