首页
前端面试题
前端报错总结
电子书
更多
插件下载
Search
1
JavaScript基础(二)操作符 流程控制
42 阅读
2
HTML基础
20 阅读
3
Vue基础
17 阅读
4
wctype.h
14 阅读
5
Vue2(知识点)
13 阅读
默认分类
HTML CSS
HTML基础
CSS
HTML5 CSS3
javaScript
javaScript基础
javaScript高级
Web APIs
jQuery
js小总结
WEB开发布局
Vue
PS切图
数据可视化
Git使用
Uniapp
c语言入门
标准库
嵌入式
登录
Search
liuxiaobai
累计撰写
108
篇文章
累计收到
12
条评论
首页
栏目
默认分类
HTML CSS
HTML基础
CSS
HTML5 CSS3
javaScript
javaScript基础
javaScript高级
Web APIs
jQuery
js小总结
WEB开发布局
Vue
PS切图
数据可视化
Git使用
Uniapp
c语言入门
标准库
嵌入式
页面
前端面试题
前端报错总结
电子书
插件下载
搜索到
7
篇与
的结果
2021-09-28
Web APIs(四)
1.1. 常用的键盘事件1.1.1 键盘事件 <script> // 常用的键盘事件 //1. keyup 按键弹起的时候触发 document.addEventListener('keyup', function() { console.log('我弹起了'); }) //3. keypress 按键按下的时候触发 不能识别功能键 比如 ctrl shift 左右箭头啊 document.addEventListener('keypress', function() { console.log('我按下了press'); }) //2. keydown 按键按下的时候触发 能识别功能键 比如 ctrl shift 左右箭头啊 document.addEventListener('keydown', function() { console.log('我按下了down'); }) // 4. 三个事件的执行顺序 keydown -- keypress -- keyup </script>1.1.2 键盘事件对象使用keyCode属性判断用户按下哪个键 <script> // 键盘事件对象中的keyCode属性可以得到相应键的ASCII码值 document.addEventListener('keyup', function(e) { console.log('up:' + e.keyCode); // 我们可以利用keycode返回的ASCII码值来判断用户按下了那个键 if (e.keyCode === 65) { alert('您按下的a键'); } else { alert('您没有按下a键') } }) document.addEventListener('keypress', function(e) { // console.log(e); console.log('press:' + e.keyCode); }) </script>1.1.3 案例:模拟京东按键输入内容当我们按下 s 键, 光标就定位到搜索框(文本框获得焦点)。注意:触发获得焦点事件,可以使用 元素对象.focus() <input type="text"> <script> // 获取输入框 var search = document.querySelector('input'); // 给document注册keyup事件 document.addEventListener('keyup', function(e) { // 判断keyCode的值 if (e.keyCode === 83) { // 触发输入框的获得焦点事件 search.focus(); } }) </script>1.1.4 案例:模拟京东快递单号查询要求:当我们在文本框中输入内容时,文本框上面自动显示大字号的内容。 <div class="search"> <div class="con">123</div> <input type="text" placeholder="请输入您的快递单号" class="jd"> </div> <script> // 获取要操作的元素 var con = document.querySelector('.con'); var jd_input = document.querySelector('.jd'); // 给输入框注册keyup事件 jd_input.addEventListener('keyup', function() { // 判断输入框内容是否为空 if (this.value == '') { // 为空,隐藏放大提示盒子 con.style.display = 'none'; } else { // 不为空,显示放大提示盒子,设置盒子的内容 con.style.display = 'block'; con.innerText = this.value; } }) // 给输入框注册失去焦点事件,隐藏放大提示盒子 jd_input.addEventListener('blur', function() { con.style.display = 'none'; }) // 给输入框注册获得焦点事件 jd_input.addEventListener('focus', function() { // 判断输入框内容是否为空 if (this.value !== '') { // 不为空则显示提示盒子 con.style.display = 'block'; } }) </script>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 事件比较合适。 <script> window.addEventListener('load', function() { var btn = document.querySelector('button'); btn.addEventListener('click', function() { alert('点击我'); }) }) window.addEventListener('load', function() { alert(22); }) document.addEventListener('DOMContentLoaded', function() { alert(33); }) </script>调整窗口大小事件 window.onresize 是调整窗口大小加载事件, 当触发时就调用的处理函数。注意:只要窗口大小发生像素变化,就会触发这个事件。我们经常利用这个事件完成响应式布局。 window.innerWidth 当前屏幕的宽度 <script> // 注册页面加载事件 window.addEventListener('load', function() { var div = document.querySelector('div'); // 注册调整窗口大小事件 window.addEventListener('resize', function() { // window.innerWidth 获取窗口大小 console.log('变化了'); if (window.innerWidth <= 800) { div.style.display = 'none'; } else { div.style.display = 'block'; } }) }) </script> <div></div>1.2.5. 定时器(两种)window 对象给我们提供了 2 个非常好用的方法-定时器。setTimeout()setInterval()setTimeout() 炸弹定时器开启定时器普通函数是按照代码顺序直接调用。 简单理解: 回调,就是回头调用的意思。上一件事干完,再回头再调用这个函数。 例如:定时器中的调用函数,事件处理函数,也是回调函数。 以前我们讲的 element.onclick = function(){} 或者 element.addEventListener(“click”, fn); 里面的 函数也是回调函数。 <script> // 回调函数是一个匿名函数 setTimeout(function() { console.log('时间到了'); }, 2000); function callback() { console.log('爆炸了'); } // 回调函数是一个有名函数 var timer1 = setTimeout(callback, 3000); var timer2 = setTimeout(callback, 5000); </script>案例:5秒后关闭广告<body> <img src="images/ad.jpg" alt="" class="ad"> <script> // 获取要操作的元素 var ad = document.querySelector('.ad'); // 开启定时器 setTimeout(function() { ad.style.display = 'none'; }, 5000); </script> </body>停止定时器 <button>点击停止定时器</button> <script> var btn = document.querySelector('button'); // 开启定时器 var timer = setTimeout(function() { console.log('爆炸了'); }, 5000); // 给按钮注册单击事件 btn.addEventListener('click', function() { // 停止定时器 clearTimeout(timer); }) </script>setInterval() 闹钟定时器开启定时器 <script> // 1. setInterval setInterval(function() { console.log('继续输出'); }, 1000); </script>案例:倒计时 <div> <span class="hour">1</span> <span class="minute">2</span> <span class="second">3</span> </div> <script> // 1. 获取元素(时分秒盒子) var hour = document.querySelector('.hour'); // 小时的黑色盒子 var minute = document.querySelector('.minute'); // 分钟的黑色盒子 var second = document.querySelector('.second'); // 秒数的黑色盒子 var inputTime = +new Date('2019-5-1 18:00:00'); // 返回的是用户输入时间总的毫秒数 countDown(); // 我们先调用一次这个函数,防止第一次刷新页面有空白 // 2. 开启定时器 setInterval(countDown, 1000); function countDown() { var nowTime = +new Date(); // 返回的是当前时间总的毫秒数 var times = (inputTime - nowTime) / 1000; // times是剩余时间总的秒数 var h = parseInt(times / 60 / 60 % 24); //时 h = h < 10 ? '0' + h : h; hour.innerHTML = h; // 把剩余的小时给 小时黑色盒子 var m = parseInt(times / 60 % 60); // 分 m = m < 10 ? '0' + m : m; minute.innerHTML = m; var s = parseInt(times % 60); // 当前的秒 s = s < 10 ? '0' + s : s; second.innerHTML = s; } </script>停止定时器案例:发送短信倒计时 点击按钮后,该按钮60秒之内不能再次点击,防止重复发送短信。 手机号码: <input type="number"> <button>发送</button> <script> var btn = document.querySelector('button'); // 全局变量,定义剩下的秒数 var time = 3; // 注册单击事件 btn.addEventListener('click', function() { // 禁用按钮 btn.disabled = true; // 开启定时器 var timer = setInterval(function() { // 判断剩余秒数 if (time == 0) { // 清除定时器和复原按钮 clearInterval(timer); btn.disabled = false; btn.innerHTML = '发送'; } else { btn.innerHTML = '还剩下' + time + '秒'; time--; } }, 1000); }); </script>1.2.6. this指向问题 this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,一般情况下this的最终指向的是那个调用它的对象。现阶段,我们先了解一下几个this指向全局作用域或者普通函数中this指向全局对象window(注意定时器里面的this指向window)方法调用中谁调用this指向谁构造函数中this指向构造函数的实例 <button>点击</button> <script> // this 指向问题 一般情况下this的最终指向的是那个调用它的对象 // 1. 全局作用域或者普通函数中this指向全局对象window( 注意定时器里面的this指向window) console.log(this); function fn() { console.log(this); } window.fn(); window.setTimeout(function() { console.log(this); }, 1000); // 2. 方法调用中谁调用this指向谁 var o = { sayHi: function() { console.log(this); // this指向的是 o 这个对象 } } o.sayHi(); var btn = document.querySelector('button'); btn.addEventListener('click', function() { console.log(this); // 事件处理函数中的this指向的是btn这个按钮对象 }) // 3. 构造函数中this指向构造函数的实例 function Fun() { console.log(this); // this 指向的是fun 实例对象 } var fun = new Fun(); </script>1.2.7. location对象什么是 location 对象URLlocation 对象的属性案例:5分钟自动跳转页面 <button>点击</button> <div></div> <script> var btn = document.querySelector('button'); var div = document.querySelector('div'); btn.addEventListener('click', function() { // console.log(location.href); location.href = 'http://www.itcast.cn'; }) var timer = 5; setInterval(function() { if (timer == 0) { location.href = 'http://www.itcast.cn'; } else { div.innerHTML = '您将在' + timer + '秒钟之后跳转到首页'; timer--; } }, 1000); </script>案例:获取URL参数 <div></div> <script> console.log(location.search); // ?uname=andy // 1.先去掉? substr('起始的位置',截取几个字符); var params = location.search.substr(1); // uname=andy console.log(params); // 2. 利用=把字符串分割为数组 split('='); var arr = params.split('='); console.log(arr); // ["uname", "ANDY"] var div = document.querySelector('div'); // 3.把数据写入div中 div.innerHTML = arr[1] + '欢迎您'; </script>location对象的常见方法 <button>点击</button> <script> var btn = document.querySelector('button'); btn.addEventListener('click', function() { // 记录浏览历史,所以可以实现后退功能 // location.assign('http://www.itcast.cn'); // 不记录浏览历史,所以不可以实现后退功能 // location.replace('http://www.itcast.cn'); location.reload(true); }) </script>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);
2021年09月28日
4 阅读
0 评论
0 点赞
2021-09-28
Web APIs(三)
1.1. 节点操作1.1.1 删除节点node.removeChild() 方法从 node节点中删除一个子节点,返回删除的节点。 <button>删除</button> <ul> <li>熊大</li> <li>熊二</li> <li>光头强</li> </ul> <script> // 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]); } } </script>1.1.2 案例:删除留言 <textarea name="" id=""></textarea> <button>发布</button> <ul> </ul> <script> // 1. 获取元素 var btn = document.querySelector('button'); var text = document.querySelector('textarea'); var ul = document.querySelector('ul'); // 2. 注册事件 btn.onclick = function() { if (text.value == '') { alert('您没有输入内容'); return false; } else { // console.log(text.value); // (1) 创建元素 var li = document.createElement('li'); // 先有li 才能赋值 li.innerHTML = text.value + "<a href='javascript:;'>删除</a>"; // (2) 添加元素 // ul.appendChild(li); ul.insertBefore(li, ul.children[0]); // (3) 删除元素 删除的是当前链接的li 它的父亲 var as = document.querySelectorAll('a'); for (var i = 0; i < as.length; i++) { as[i].onclick = function() { // 删除的是 li 当前a所在的li this.parentNode; ul.removeChild(this.parentNode); } } } } </script>1.1.3 复制(克隆)节点 <ul> <li>1111</li> <li>2</li> <li>3</li> </ul> <script> var ul = document.querySelector('ul'); // 1. node.cloneNode(); 括号为空或者里面是false 浅拷贝 只复制标签不复制里面的内容 // 2. node.cloneNode(true); 括号为true 深拷贝 复制标签复制里面的内容 var lili = ul.children[0].cloneNode(true); ul.appendChild(lili); </script>1.1.4 案例:动态生成表格 <script> // 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++) { // 1. 创建 tr行 var tr = document.createElement('tr'); tbody.appendChild(tr); // 2. 行里面创建单元格td 单元格的数量取决于每个对象里面的属性个数 // 使用for in遍历学生对象 for (var k in datas[i]) { // 创建单元格 var td = document.createElement('td'); // 把对象里面的属性值 datas[i][k] 给 td 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) } } </script>1.1.5 创建元素的三种方式 <script> // 三种创建元素方式区别 // 1. document.write() 创建元素 如果页面文档流加载完毕,再调用这句话会导致页面重绘 var btn = document.querySelector('button'); btn.onclick = function() { document.write('<div>123</div>'); } // 2. innerHTML 创建元素 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(''); // 3. document.createElement() 创建元素 var create = document.querySelector('.create'); for (var i = 0; i <= 100; i++) { var a = document.createElement('a'); create.appendChild(a); } </script>1.1.6 innerTHML和createElement效率对比innerHTML字符串拼接方式(效率低)<script> function fn() { var d1 = +new Date(); var str = ''; for (var i = 0; i < 1000; i++) { document.body.innerHTML += '<div style="width:100px; height:2px; border:1px solid blue;"></div>'; } var d2 = +new Date(); console.log(d2 - d1); } fn(); </script>createElement方式(效率一般)<script> function fn() { var d1 = +new Date(); for (var i = 0; i < 1000; i++) { var div = document.createElement('div'); div.style.width = '100px'; div.style.height = '2px'; div.style.border = '1px solid red'; document.body.appendChild(div); } var d2 = +new Date(); console.log(d2 - d1); } fn(); </script>innerHTML数组方式(效率高)<script> function fn() { var d1 = +new Date(); var array = []; for (var i = 0; i < 1000; i++) { array.push('<div style="width:100px; height:2px; border:1px solid blue;"></div>'); } document.body.innerHTML = array.join(''); var d2 = +new Date(); console.log(d2 - d1); } fn(); </script>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(目标对象) 上,当该对象触发指定的事件时,指定的回调函数就会被执行。<button>传统注册事件</button> <button>方法监听注册事件</button> <button>ie9 attachEvent</button> <script> 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); }) </script>事件监听兼容性解决方案封装一个函数,函数中判断浏览器的类型:1.3.3. 删除事件(解绑事件) <div>1</div> <div>2</div> <div>3</div> <script> 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); } </script>删除事件兼容性解决方案 1.3.4. DOM事件流html中的标签都是相互嵌套的,我们可以将元素想象成一个盒子装一个盒子,document是最外面的大盒子。 当你单击一个div时,同时你也单击了div的父元素,甚至整个页面。 那么是先执行父元素的单击事件,还是先执行div的单击事件 ???比如:我们给页面中的一个div注册了单击事件,当你单击了div时,也就单击了body,单击了html,单击了document。当时的2大浏览器霸主谁也不服谁! IE 提出从目标元素开始,然后一层一层向外接收事件并响应,也就是冒泡型事件流。 Netscape(网景公司)提出从最外层开始,然后一层一层向内接收事件并响应,也就是捕获型事件流。 江湖纷争,武林盟主也脑壳疼!!! 最终,w3c 采用折中的方式,平息了战火,制定了统一的标准 —--— 先捕获再冒泡。 现代浏览器都遵循了此标准,所以当事件发生时,会经历3个阶段。DOM 事件流会经历3个阶段:捕获阶段当前目标阶段冒泡阶段 我们向水里面扔一块石头,首先它会有一个下降的过程,这个过程就可以理解为从最顶层向事件发生的最具体元素(目标点)的捕获过程;之后会产生泡泡,会在最低点( 最具体元素)之后漂浮到水面上,这个过程相当于事件冒泡。 事件冒泡 <div class="father"> <div class="son">son盒子</div> </div> <script> // onclick 和 attachEvent(ie) 在冒泡阶段触发 // 冒泡阶段 如果addEventListener 第三个参数是 false 或者 省略 // son -> father ->body -> html -> document var son = document.querySelector('.son'); // 给son注册单击事件 son.addEventListener('click', function() { alert('son'); }, false); // 给father注册单击事件 var father = document.querySelector('.father'); father.addEventListener('click', function() { alert('father'); }, false); // 给document注册单击事件,省略第3个参数 document.addEventListener('click', function() { alert('document'); }) </script>事件捕获 <div class="father"> <div class="son">son盒子</div> </div> <script> // 如果addEventListener() 第三个参数是 true 那么在捕获阶段触发 // document -> html -> body -> father -> son var son = document.querySelector('.son'); // 给son注册单击事件,第3个参数为true son.addEventListener('click', function() { alert('son'); }, true); var father = document.querySelector('.father'); // 给father注册单击事件,第3个参数为true father.addEventListener('click', function() { alert('father'); }, true); // 给document注册单击事件,第3个参数为true document.addEventListener('click', function() { alert('document'); }, true) </script>1.3.5. 事件对象什么是事件对象事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面,这个对象就是事件对象。比如:谁绑定了这个事件。鼠标触发事件的话,会得到鼠标的相关信息,如鼠标位置。键盘触发事件的话,会得到键盘的相关信息,如按了哪个键。事件对象的使用事件触发发生时就会产生事件对象,并且系统会以实参的形式传给事件处理函数。所以,在事件处理函数中声明1个形参用来接收事件对象。事件对象的兼容性处理事件对象本身的获取存在兼容问题:标准浏览器中是浏览器给方法传递的参数,只需要定义形参 e 就可以获取到。在 IE6~8 中,浏览器不会给方法传递参数,如果需要的话,需要到 window.event 中获取查找。只要“||”前面为false, 不管“||”后面是true 还是 false,都返回 “||” 后面的值。 只要“||”前面为true, 不管“||”后面是true 还是 false,都返回 “||” 前面的值。 <div>123</div> <script> var div = document.querySelector('div'); div.onclick = function(e) { // 事件对象 e = e || window.event; console.log(e); } </script>事件对象的属性和方法e.target 和 this 的区别this 是事件绑定的元素(绑定这个事件处理函数的元素) 。e.target 是事件触发的元素。常情况下terget 和 this是一致的, 但有一种情况不同,那就是在事件冒泡时(父子元素有相同事件,单击子元素,父元素的事件处理函数也会被触发执行), 这时候this指向的是父元素,因为它是绑定事件的元素对象, 而target指向的是子元素,因为他是触发事件的那个具体元素对象。 <div>123</div> <script> var div = document.querySelector('div'); div.addEventListener('click', function(e) { // e.target 和 this指向的都是div console.log(e.target); console.log(this); }); </script>事件冒泡下的e.target和this <ul> <li>abc</li> <li>abc</li> <li>abc</li> </ul> <script> var ul = document.querySelector('ul'); ul.addEventListener('click', function(e) { // 我们给ul 绑定了事件 那么this 就指向ul console.log(this); // ul // e.target 触发了事件的对象 我们点击的是li e.target 指向的就是li console.log(e.target); // li }); </script>1.3.6 阻止默认行为html中一些标签有默认行为,例如a标签被单击后,默认会进行页面跳转。 <a href="http://www.baidu.com">百度</a> <script> // 2. 阻止默认行为 让链接不跳转 var a = document.querySelector('a'); a.addEventListener('click', function(e) { e.preventDefault(); // dom 标准写法 }); // 3. 传统的注册方式 a.onclick = function(e) { // 普通浏览器 e.preventDefault(); 方法 e.preventDefault(); // 低版本浏览器 ie678 returnValue 属性 e.returnValue = false; // 我们可以利用return false 也能阻止默认行为 没有兼容性问题 return false; } </script>1.3.7 阻止事件冒泡事件冒泡本身的特性,会带来的坏处,也会带来的好处。 <div class="father"> <div class="son">son儿子</div> </div> <script> var son = document.querySelector('.son'); // 给son注册单击事件 son.addEventListener('click', function(e) { alert('son'); e.stopPropagation(); // stop 停止 Propagation 传播 window.event.cancelBubble = true; // 非标准 cancel 取消 bubble 泡泡 }, false); var father = document.querySelector('.father'); // 给father注册单击事件 father.addEventListener('click', function() { alert('father'); }, false); // 给document注册单击事件 document.addEventListener('click', function() { alert('document'); }) </script>阻止事件冒泡的兼容性处理1.3.8 事件委托事件冒泡本身的特性,会带来的坏处,也会带来的好处。什么是事件委托把事情委托给别人,代为处理。事件委托也称为事件代理,在 jQuery 里面称为事件委派。说白了就是,不给子元素注册事件,给父元素注册事件,把处理代码在父元素的事件中执行。生活中的代理:js事件中的代理:事件委托的原理 给父元素注册事件,利用事件冒泡,当子元素的事件触发,会冒泡到父元素,然后去控制相应的子元素。事件委托的作用我们只操作了一次 DOM ,提高了程序的性能。动态新创建的子元素,也拥有事件。 <ul> <li>知否知否,点我应有弹框在手!</li> <li>知否知否,点我应有弹框在手!</li> <li>知否知否,点我应有弹框在手!</li> <li>知否知否,点我应有弹框在手!</li> <li>知否知否,点我应有弹框在手!</li> </ul> <script> // 事件委托的核心原理:给父节点添加侦听器, 利用事件冒泡影响每一个子节点 var ul = document.querySelector('ul'); ul.addEventListener('click', function(e) { // e.target 这个可以得到我们点击的对象 e.target.style.backgroundColor = 'pink'; }) </script>1.4. 常用鼠标事件1.4.1 案例:禁止选中文字和禁止右键菜单<body> 我是一段不愿意分享的文字 <script> // 1. contextmenu 我们可以禁用右键菜单 document.addEventListener('contextmenu', function(e) { e.preventDefault(); }) // 2. 禁止选中文字 selectstart document.addEventListener('selectstart', function(e) { e.preventDefault(); }) </script> </body>1.4.2 鼠标事件对象1.4.3 获取鼠标在页面的坐标 <script> // 鼠标事件对象 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); }) </script>1.4.4 案例:跟随鼠标的天使 <img src="images/angel.gif" alt=""> <script> var pic = document.querySelector('img'); document.addEventListener('mousemove', function(e) { // 1. mousemove只要我们鼠标移动1px 就会触发这个事件 // 2.核心原理: 每次鼠标移动,我们都会获得最新的鼠标坐标, // 把这个x和y坐标做为图片的top和left 值就可以移动图片 var x = e.pageX; var y = e.pageY; console.log('x坐标是' + x, 'y坐标是' + y); //3 . 千万不要忘记给left 和top 添加px 单位 pic.style.left = x - 50 + 'px'; pic.style.top = y - 40 + 'px'; }); </script>
2021年09月28日
4 阅读
0 评论
0 点赞
2021-09-28
Web APIs(二)
1.1. 排他操作1.1.1 排他思想如果有同一组元素,我们想要某一个元素实现某种样式, 需要用到循环的排他思想算法:所有元素全部清除样式(干掉其他人)给当前元素设置样式 (留下我自己)注意顺序不能颠倒,首先干掉其他人,再设置自己 <button>按钮1</button> <button>按钮2</button> <button>按钮3</button> <button>按钮4</button> <button>按钮5</button> <script> // 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'; } } </script>1.2 案例:百度换肤<body> <ul class="baidu"> <li><img src="images/1.jpg"></li> <li><img src="images/2.jpg"></li> <li><img src="images/3.jpg"></li> <li><img src="images/4.jpg"></li> </ul> <script> // 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 + ')'; } } </script> </body>1.3 案例:表格隔行变色 <script> // 1.获取元素 获取的是 tbody 里面所有的行 var trs = document.querySelector('tbody').querySelectorAll('tr'); // 2. 利用循环绑定注册事件 for (var i = 0; i < trs.length; i++) { // 3. 鼠标经过事件 onmouseover trs[i].onmouseover = function() { // console.log(11); this.className = 'bg'; } // 4. 鼠标离开事件 onmouseout trs[i].onmouseout = function() { this.className = ''; } } </script>1.4 案例:全选 <script> // 1. 全选和取消全选做法: 让下面所有复选框的checked属性(选中状态) 跟随 全选按钮即可 // 获取元素 var j_cbAll = document.getElementById('j_cbAll'); var j_tbs = document.getElementById('j_tb').getElementsByTagName('input'); // 全选按钮注册事件 j_cbAll.onclick = function() { // this.checked 当前复选框的选中状态 console.log(this.checked); for (var i = 0; i < j_tbs.length; i++) { j_tbs[i].checked = this.checked; } } // 给所有的子复选框注册单击事件 for (var i = 0; i < j_tbs.length; i++) { j_tbs[i].onclick = function() { // flag 控制全选按钮是否选中 var flag = true; // 每次点击下面的复选框都要循环检查者4个小按钮是否全被选中 for (var i = 0; i < j_tbs.length; i++) { if (!j_tbs[i].checked) { flag = false; break; } } // 设置全选按钮的状态 j_cbAll.checked = flag; } } </script>1.5. 自定义属性操作1.5.1 获取属性值 <div id="demo" index="1" class="nav"></div> <script> var div = document.querySelector('div'); // 1. 获取元素的属性值 // (1) element.属性 console.log(div.id); //(2) element.getAttribute('属性') get得到获取 attribute 属性的意思 我们程序员自己添加的属性我们称为自定义属性 index console.log(div.getAttribute('id')); console.log(div.getAttribute('index')); </script>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栏 <script> // 获取元素 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'; } } </script>1.5.5. H5自定义属性自定义属性目的:是为了保存并使用数据。有些数据可以保存到页面中而不用保存到数据库中。自定义属性获取是通过getAttribute(‘属性’) 获取。但是有些自定义属性很容易引起歧义,不容易判断是元素的内置属性还是自定义属性。H5给我们新增了自定义属性: <div getTime="20" data-index="2" data-list-name="andy"></div> <script> var div = document.querySelector('div'); // console.log(div.getTime); console.log(div.getAttribute('getTime')); div.setAttribute('data-time', 20); console.log(div.getAttribute('data-index')); console.log(div.getAttribute('data-list-name')); // h5新增的获取自定义属性的方法 它只能获取data-开头的 // dataset 是一个集合里面存放了所有以data开头的自定义属性 console.log(div.dataset); console.log(div.dataset.index); console.log(div.dataset['index']); // 如果自定义属性里面有多个-链接的单词,我们获取的时候采取 驼峰命名法 console.log(div.dataset.listName); console.log(div.dataset['listName']); </script>1.6. 节点操作1.6.1. 节点概述 网页中的所有内容都是节点(标签、属性、文本、注释等),在DOM 中,节点使用 node 来表示。 HTML DOM 树中的所有节点均可通过 JavaScript 进行访问,所有 HTML 元素(节点)均可被修改,也可以创建或删除。 一般地,节点至少拥有nodeType(节点类型)、nodeName(节点名称)和nodeValue(节点值)这三个基本属性。1.6.2. 节点层级 利用 DOM 树可以把节点划分为不同的层级关系,常见的是父子兄层级关系。1.6.3. 父级节点 <div class="demo"> <div class="box"> <span class="erweima">×</span> </div> </div> <script> // 1. 父节点 parentNode var erweima = document.querySelector('.erweima'); // var box = document.querySelector('.box'); // 得到的是离元素最近的父级节点(亲爸爸) 如果找不到父节点就返回为 null console.log(erweima.parentNode); </script>1.6.4. 子节点所有子节点子元素节点 <ul> <li>我是li</li> <li>我是li</li> <li>我是li</li> <li>我是li</li> </ul> <script> // DOM 提供的方法(API)获取 var ul = document.querySelector('ul'); var lis = ul.querySelectorAll('li'); // 1. 子节点 childNodes 所有的子节点 包含 元素节点 文本节点等等 console.log(ul.childNodes); console.log(ul.childNodes[0].nodeType); console.log(ul.childNodes[1].nodeType); // 2. children 获取所有的子元素节点 也是我们实际开发常用的 console.log(ul.children); </script>第1个子节点最后1个子节点第1个子元素节点最后1个子元素节点 实际开发中,firstChild 和 lastChild 包含其他节点,操作不方便,而 firstElementChild 和 lastElementChild 又有兼容性问题,那么我们如何获取第一个子元素节点或最后一个子元素节点呢? <ol> <li>我是li1</li> <li>我是li2</li> <li>我是li3</li> <li>我是li4</li> <li>我是li5</li> </ol> <script> var ol = document.querySelector('ol'); // 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]); </script>1.6.5. 案例:新浪下拉菜单 <script> // 1. 获取元素 var nav = document.querySelector('.nav'); var lis = nav.children; // 得到4个小li // 2.循环注册事件 for (var i = 0; i < lis.length; i++) { lis[i].onmouseover = function() { this.children[1].style.display = 'block'; } lis[i].onmouseout = function() { this.children[1].style.display = 'none'; } } </script>1.6.6. 兄弟节点下一个兄弟节点上一个兄弟节点 <div>我是div</div> <span>我是span</span> <script> var div = document.querySelector('div'); // 1.nextSibling 下一个兄弟节点 包含元素节点或者 文本节点等等 console.log(div.nextSibling); console.log(div.previousSibling); // 2. nextElementSibling 得到下一个兄弟元素节点 console.log(div.nextElementSibling); console.log(div.previousElementSibling); </script>下一个兄弟元素节点(有兼容性问题)上一个兄弟元素节点(有兼容性问题) function getNextElementSibling(element) { var el = element; while (el = el.nextSibling) { if (el.nodeType === 1) { return el; } } return null; } 1.6.7. 创建节点1.6.8. 添加节点 <ul> <li>123</li> </ul> <script> // 1. 创建节点元素节点 var li = document.createElement('li'); // 2. 添加节点 node.appendChild(child) node 父级 child 是子级 后面追加元素 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. 添加元素 </script>1.6.9. 案例:简单版发布留言<body> <textarea name="" id=""></textarea> <button>发布</button> <ul> </ul> <script> // 1. 获取元素 var btn = document.querySelector('button'); var text = document.querySelector('textarea'); var ul = document.querySelector('ul'); // 2. 注册事件 btn.onclick = function() { if (text.value == '') { alert('您没有输入内容'); return false; } else { // console.log(text.value); // (1) 创建元素 var li = document.createElement('li'); // 先有li 才能赋值 li.innerHTML = text.value; // (2) 添加元素 // ul.appendChild(li); ul.insertBefore(li, ul.children[0]); } } </script> </body>
2021年09月28日
4 阅读
0 评论
0 点赞
1
2
3