JavaScript-16
1.数据可视化
数据可视化的主要目的:借助图形化的手段,清晰有效地传递与沟通信息
数据可视化可以把数据转换成图形,揭示蕴含在数据中的规律和道理
- 常用的数据可视化库
- D3.js:目前Web端评价最高的javascript可视化工具库
- ECharts.js:百度出品的一个开源JavaScript数据可视化库
- Highercharts.js:国外的前端数据可视化库,非商用免费
- AntV:蚂蚁金服全新一代数据可视化解决方案
- Echarts使用五部曲
- 下载并引入echarts.js文件
- 准备一个具备大小的DOM容器
- 初始化echarts实例对象
- 指定配置项和数据(option)
- 将配置项设置给echarts对象
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <title> Echarts体验</title> 6 <!-- 1.下载引入echarts文件 --> 7 <script src="js/echarts.js"></script> 8 </head> 9 <body> 10 <!-- 2.准备一个盒子用来装生成的图表 注意:这个盒子必须具备大小 --> 11 <div id="main" style="width: 600px;height:400px;"></div> 12 <script> 13 // 3.实例化echarts对象 14 var chart = echarts.init(document.querySelector("#main")); 15 // 4.指定配置项和数据 16 var option = { 17 title: { 18 text: 'ECharts 入门示例' 19 }, 20 tooltip: {}, 21 legend: { 22 data: ['销量'] 23 }, 24 xAxis: { 25 data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子'] 26 }, 27 yAxis: {}, 28 series: [ 29 { 30 name: '销量', 31 type: 'bar', 32 data: [5, 20, 36, 10, 10, 20] 33 } 34 ] 35 }; 36 // 5.将配置项和数据(option)设置给实例对象(chart) 37 chart.setOption(option); 38 </script> 39 </body> 40 </html>
- 选择不同类型图表(官网-实例-官方实例)
- 相关配置讲解
title | 标题组件 |
tooltip | 提示框组件 |
legend | 图例组件 |
toolbox | 工具栏 |
grid | 直角坐标系内绘图网格 |
xAxis | 直角坐标系grid中的x轴 |
yAxis | 直角坐标系grid中的y轴 |
series | 系列列表。每个系列通过type决定自己的图表类型 |
color | 调色盘颜色列表 |
-
- series:系列列表
type | 类型(什么类型的图表)比如line是折线bar柱形 |
name | 系列名称,用于tooltip的显示,legend的图例筛选变化 |
stack | 数据堆叠,蛇果设置相同值则会数据堆叠(数据一次叠加) |
- 边框图片及其切割原理
- 边框图片使用场景
盒子大小不已,但是边框样式相同,此时就需要边框图片来完成
-
- 边框图片(在CSS3中新增了border-image属性,这个新属性允许指定一幅图像作为元素的边框)
- 边框图片切图原理:
- 将四个角切出去(九宫格的由来,中间部分可以铺排、拉伸或者环绕)上右下左
- 边框图片使用语法
属性 | 描述 |
border-image-source | 用在边框图片的路径 |
border-image-slice | 图片边框向内偏移(裁剪的尺寸,一定不加单位,上右下左的顺序) |
border-image-width | 图片边框的宽度(需要添加的的单位)边框图片的宽度,不会挤压文字 |
border-image-repeat | 图片边框是否应平铺(repeat)、铺满(round)或拉伸(stretch)默认拉伸 |
-
- 通过类名调用字体图标
- 在HTML页面引入字体图标中css文件
- 标签直接调用图标对应的类名即可
- 通过类名调用字体图标
2.JavaScript面向对象编程
- 面向过程编程:POP
面向过程就是分析出解决问题所需要的步骤,然后使用函数将步骤实现,最后通过调用函数解决问题
- 面向对象:OOP
将事务分解成为一个个对象,然后由对象之间分工合作(面向对象是以对象功能来划分问题,而不是步骤)
- 面向对象的特性
- 封装性
- 继承性
- 多态性
- 面向过程和面向对象的对比
面向过程(蛋炒饭) | 面向对象(盖浇饭) |
优点:性能比面向对象高,适合跟硬件联系很紧密的东西 例如:单片机就采用面向过程编程 |
优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态的特性 可以设计出低耦合的系统,是系统更加灵活,更加易于维护 |
缺点:没有面向对象易维护、易复用、易扩展 | 缺点:性能比面向过程低 |
- ES6中的类和对象
- 面向对象的思维特点
- 抽取对象公用的属性和行为组织(封装)成一个类
- 对类进行实例化,获取类的对象
- 对象
- 对象是一个具体的事务
- 对象特指类中的某一个,通过实例化一个具体的对象
- 类
- 可以使用class关键字声明一个类
- 类抽象了对象的公共部分,它泛指某一大类
- 类抽取了对象的公共部分,它泛指某一大类
- 面向对象的思维特点
- 创建类
- 类constructor构造函数
constructor()方法是类的构造函数,用于传递参数,返回实例对象,通过new命令生成对象实例时,自动调用该方法
如果没有显示定义,类内部会自动给我们创建一个constructor()
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <title>创建类</title> 6 </head> 7 <body> 8 <script> 9 //1.创建类class 创建一个明星类 10 class Star{ 11 constructor(uname) { 12 this.uname = uname; 13 } 14 } 15 //2.利用类创建对象 16 var bbh = new Star('边伯贤');//只要包含new,自动调用constructor 17 console.log(bbh.uname); 18 /* 19 1.通过class关键字创建类,类名我们还是使用首字母大写 20 2.类里面有个constructor函数,可以接受传递过来的参数,同时发返回实例对象 21 3.constructor函数只要new生成实例时,就会自动调用这个函数,如果我们不写这个函数,类也会自动生成 22 4.生成实例new不能省略 23 5.语法规范:创建类,类名后面不要加小括号,生成实例,类名后面加小括号,构造函数不需要加function 24 */ 25 </script> 26 </body> 27 </html>
- 类中创建共有方法
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <title>类中创建共有方法</title> 6 </head> 7 <body> 8 <script> 9 //1.创建类class 创建一个明星类 10 class Star{ 11 constructor(uname) { 12 this.uname = uname; 13 } 14 sing(song){ 15 console.log(this.uname+'唱'+song); 16 } 17 } 18 //2.利用类创建对象 19 var bbh = new Star('边伯贤');//只要包含new,自动调用constructor 20 console.log(bbh.uname); 21 //3.我们类里面所有的函数不需要写function 22 //4.多个函数之间不需要添加逗号分隔 23 bbh.sing('Amusement park'); 24 </script> 25 </body> 26 </html>
- 类继承和super关键字
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title></title> 6 </head> 7 <body> 8 <script type="text/javascript"> 9 //1.类的继承 10 class Father{ 11 constructor(xing) { 12 this.xing = xing; 13 } 14 money(sum){ 15 console.log(this.xing+'某某的儿子继承了他的'+sum+'元财产'); 16 } 17 } 18 class Son extends Father { 19 // constructor(ming) { 20 // this.ming = '伯贤'; 21 // } 22 //报错: Must call super constructor in derived class before accessing 'this' 23 // or returning from derived constructor at new Son 24 constructor(xing) { 25 super(xing); 26 } 27 } 28 var son = new Son('边'); 29 son.money(1000000); 30 // super关键字用于访问和调用对象父类上的函数,可以调用父类的构造函数,也可以调用父类的普通函数 31 </script> 32 </body> 33 </html>
-
- super调用父类的普通函数
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title></title> 6 </head> 7 <body> 8 <script type="text/javascript"> 9 class Father { 10 say(){ 11 return "儿子儿子我是你爸爸~~~"; 12 } 13 } 14 class Son extends Father { 15 say(){ 16 // console.log("爸比你会唱小星星吗???"); 17 console.log(super.say()+'Σ(⊙▽⊙"a唱错了'); 18 //super.say就是调用父类中的普通函数say 19 } 20 } 21 var son = new Son(); 22 son.say(); 23 //继承中的属性或者查找原则:就近原则 24 //1.继承中,如果实例化子类输出一个方法,先看子类有没有这个方法,如果有就先执行子类的 25 //2.继承中,如果子类里面没有,就去查找父类有没有这个方法,如果有,就执行父类的这个方法(就近原则) 26 </script> 27 </body> 28 </html>
-
- 子类继承父类方法同时扩展自己的方法
子类构造函数中使用super,必须放到this前面
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>子类继承父类方法同时扩展自己的方法</title> 6 </head> 7 <body> 8 <script type="text/javascript"> 9 class Father{ 10 constructor(x,y) { 11 this.x = x; 12 this.y = y; 13 } 14 sum(){ 15 console.log(this.x + this.y); 16 } 17 } 18 // 子类继承父亲加法方法 同时 扩展减法方法 19 // 子类构造函数中使用super,必须放到this前面(必须先调用父类的构造方法,再使用子类构造方法) 20 class Son extends Father { 21 constructor(x,y) { 22 //调用父类的构造函数 23 super(x,y); 24 this.x = x; 25 this.y = y; 26 } 27 sum(x,y){ 28 super.sum(x,y); 29 } 30 multiply(){ 31 console.log(this.x - this.y); 32 } 33 } 34 var son = new Son(5,3); 35 son.sum(); 36 son.multiply(); 37 </script> 38 </body> 39 </html>
- 注意点
- 在ES6中没有变量提升,所以必须先定义类,才能通过类实例化对象
- 类里面共有的属性和方法一定要加this调用
- 类里面this的指向问题
- constructor里面的this指向的是创建的实例化对象
- 方法里面的this指向的是这个方法的调用者
- 面向对象案例(动态添加标签页)
- html
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title></title> 6 <script src="js/jquery-3.6.0.js"></script> 7 <script src="js/tab.js"></script> 8 <style type="text/css"> 9 * { 10 padding: 0; 11 margin: 0; 12 } 13 14 .box { 15 margin-top: 100px; 16 text-align: center; 17 } 18 19 .tab { 20 position: relative; 21 margin: 20px auto; 22 width: 600px; 23 height: 300px; 24 border: 1px solid firebrick; 25 } 26 27 .lab { 28 float: left; 29 position: absolute; 30 top: 0; 31 left: 0; 32 } 33 34 .lab li { 35 position: relative; 36 float: left; 37 list-style: none; 38 height: 30px; 39 width: 80px; 40 border-right: 1px solid firebrick; 41 border-bottom: 1px solid firebrick; 42 line-height: 30px; 43 cursor: pointer; 44 } 45 46 .close { 47 position: absolute; 48 height: 10px; 49 width: 10px; 50 top: 0; 51 right: 0; 52 color: white; 53 background-color: #000000; 54 border-bottom-left-radius: 8px; 55 font-size:8px; 56 line-height: 10px; 57 text-align: right; 58 cursor: pointer; 59 } 60 61 .btn { 62 float: right; 63 margin-top: 8px; 64 margin-right: 8px; 65 width: 15px; 66 height: 15px; 67 background-color: rgb(255, 255, 255); 68 border: 1px solid firebrick; 69 line-height: 15px; 70 } 71 72 .add { 73 float: right; 74 height: 30px; 75 border-bottom: 1px solid firebrick; 76 } 77 78 .content { 79 height: 269px; 80 margin-top: 31px; 81 } 82 83 .lab .current { 84 border-bottom: none; 85 } 86 87 .content section { 88 display: none; 89 } 90 91 .tab .now { 92 display: block; 93 text-align: left; 94 line-height: 30px; 95 text-indent: 1em; 96 } 97 98 .lab li textarea { 99 display: inline-block; 100 margin-top: 5px; 101 height: 20px; 102 width: 75px; 103 } 104 .content textarea { 105 display: inline-block; 106 margin: 5px auto; 107 height: 250px; 108 width: 570px; 109 } 110 </style> 111 </head> 112 <body> 113 <div class="box"> 114 <h5>JS 面向对象 动态添加标签页</h5> 115 <div class="tab"> 116 <ul class="lab"> 117 <li index = '0' class="current"> 118 测试1 119 <div class="close">x</div> 120 </li> 121 <li index = '1'> 122 测试2 123 <div class="close">x</div> 124 </li> 125 <li index = '2'> 126 测试3 127 <div class="close">x</div> 128 </li> 129 </ul> 130 <div class="add"> 131 <input class="btn" type="button" value="+"/> 132 </div> 133 <div class="content"> 134 <section id = "0" class = "now">测试1</section> 135 <section id = "1">测试2</section> 136 <section id = "2">测试3</section> 137 </div> 138 </div> 139 </div> 140 </body> 141 </html>
-
- tab.js
1 $(function(){ 2 change(); 3 function change(){ 4 var add = document.querySelector(".add"); 5 var lab = document.querySelector(".lab"); 6 var tab = document.querySelector(".tab"); 7 add.style.width = tab.offsetWidth - lab.offsetWidth - 1 + 'px'; 8 } 9 /* 10 Tab实现的功能 11 1.页面切换 12 2.页面添加 13 3.页面删除 14 4.页面编辑 15 */ 16 var that; 17 class Tab{ 18 constructor(box) { 19 that = this; 20 this.box = box; 21 this.lis = this.box.querySelectorAll("li"); 22 this.btn = this.box.querySelector(".btn"); 23 this.sections = this.box.querySelectorAll(".content section"); 24 this.content = this.box.querySelector('.content'); 25 this.ul = this.box.querySelector(".lab"); 26 this.init(); 27 } 28 init(){ 29 this.updateTab(); 30 this.btn.onclick = this.addTab; 31 for(var i = 0 ; i < this.lis.length ; i++){ 32 this.lis[i].onclick = this.toggleTab; 33 this.lis[i].ondblclick = this.modifyTab; 34 this.lis[i].children[0].onclick = this.delTab; 35 } 36 for(var j = 0 ; j < this.sections.length ; j++){ 37 this.sections[j].ondblclick = this.modifyTab; 38 } 39 } 40 //更新数据 41 updateTab(){ 42 that.lis = that.box.querySelectorAll(".lab li"); 43 that.sections = that.box.querySelectorAll(".content section"); 44 } 45 //1.页面切换 46 toggleTab(){ 47 that.init(); 48 for(var i = 0 ; i < that.lis.length ; i++){ 49 that.lis[i].className = ''; 50 that.sections[i].className = ''; 51 } 52 this.className = "current"; 53 var section = document.getElementById(this.getAttribute("index")); 54 section.className = 'now'; 55 change(); 56 } 57 //2.页面添加 58 addTab(){ 59 that.init(); 60 var num = Math.random()*100; 61 if(that.lis.length == 0){ 62 var li = "<li index = "+that.lis.length+" class='current'>添加<div class='close'>x</div></li>"; 63 var section = "<section id = "+that.sections.length+" class = 'now'>新建"+num+"</section>"; 64 that.content.insertAdjacentHTML('beforeend',section); 65 that.ul.insertAdjacentHTML('beforeend',li); 66 }else { 67 var key = +that.lis[that.lis.length-1].getAttribute("index") + 1; 68 var li = "<li index = "+key+" class='current'>添加<div class='close'>x</div></li>"; 69 var section = "<section id = "+key+" class = 'now'>新建"+num+"</section>"; 70 that.content.insertAdjacentHTML('beforeend',section); 71 that.ul.insertAdjacentHTML('beforeend',li); 72 } 73 that.init(); 74 that.lis[that.lis.length-1].click(); 75 } 76 //3.页面删除 77 delTab(e){ 78 if(this.parentNode.className === 'current' && this.parentNode.previousElementSibling != null){ 79 this.parentNode.previousElementSibling.click(); 80 }else if(this.parentNode.className === 'current' && this.parentNode.previousElementSibling == null && this.parentNode.nextElementSibling != null){ 81 this.parentNode.nextElementSibling.click(); 82 } 83 this.parentNode.remove(); 84 var section = document.getElementById(this.parentNode.getAttribute("index")); 85 section.remove(); 86 //阻止冒泡到li的点击事件 87 e.stopPropagation(); 88 change(); 89 } 90 //4.页面修改 91 modifyTab(e){ 92 // 阻止默认选中文字 93 window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty(); 94 var str = this.firstChild.nodeValue; 95 var reg = /\S/g; 96 this.innerHTML = '<textarea></textarea>'; 97 this.children[0].value = str.match(reg).toString().replace(/,/g,''); 98 this.children[0].select(); 99 this.children[0].addEventListener("blur",function(){ 100 var word = this.value; 101 if(this.parentNode.tagName === "LI"){ 102 this.parentNode.innerHTML = word+'<div class="close">x</div>'; 103 }else{ 104 this.parentNode.innerHTML = word; 105 } 106 }) 107 this.children[0].onkeyup = function(e){ 108 if(e.key === 'Enter'){ 109 this.blur(); 110 } 111 } 112 e.stopPropagation(); 113 } 114 } 115 new Tab(document.querySelector(".box")); 116 })