前端面试题(1)

1,CSS盒子模型
CSS的盒模型有两种:标准盒模型,IE盒模型。IE盒模型,其中content包含了内边距padding和边框border。盒子的实际宽度 = content+margin。标准盒模型,盒子的实际宽度 = content(内容)+padding(内边距)+border(边框)+margin(外边距)CSS3新增一种盒模型计算方式,box-sizing属性,这个属性有3个值,content-box (默认值),padding-box  (存在兼容性),border-box当取此值,该元素的content就包含了padding和border,换言之,可以把标准盒模型转化为 IE盒模型。
2,样式初始化作用
因为浏览器兼容问题,不同浏览器对有些标签的默认值是不一样的,如果没有对css样式进行初始化设置,往往会出现浏览器之间页面显示差异。样式初始化会对SEO有一定影响,但力求影响最小的情况下进行初始化。
//正式项目中,一般不用
{ margin:0; padding:0 }
3,语义化理解
用正确的标签做正确的事情。优点:便于开发者阅读,写出更优雅的代码;便于团队开发和维护,语义化更具有可读性;让浏览器爬虫与机器更好的解析。语义化标签:header,nav,article,section,aside,footer
4,对web标准的理解
web标准不是某一个标准,而是一系列标准的集合。页面主要有三部分组成:结构,表现和行为。W3C对web提出了一些规范化要求:1) 标签字母要小写。2)标签要闭合。3)标签不允许随意嵌套。4)尽量使用外链css样式和js脚本,link和script。5)标签的id和class等属性命名要做到见文知义,标签越少,加载越快,用户体验提高,代码维护简单,便于改版。
5,一个页面从输入 url 到页面加载显示完成经历的过程。
(1)浏览器根据请求的url交给DSN域名解析,找到真实IP,然后向服务器发送请求。(2)服务器交给后台处理,完成后返回数据,浏览器接受文件(HTML,JS,CSS,图像等)。(3)浏览器对加载到的资源(HTML,JS,CSS等)进行语法解析,建立相应的内部数据结构(DOM树等)。(4)载入解析到的资源文件,渲染页面完成。
6,HTML常见的块级元素和行内元素
6.1,常见的块级元素
 	块级元素特点:(1)所有的块级元素都会独占一行;(2)块级元素可以直接设置高度和宽度;(3)如果一个块级元素没有设置宽度,那么其默认的宽度是父元素的宽度。``````shell
div, p, h1-h6, ul, ol, li, table, th, td, dl, dt, dd, address, audio, canvas
6.2,常见的内联元素
行内元素特点:(1)所有的行内元素都在一行上显示;(2)行内元素设置的宽度和高度不生效。
a, b, span, big, del, em, i, strong, sub, sup, video
6.3,常见的行内块元素
行内块元素特点:(1)与所有的行内元素相同都在一行上显示;(2)与块元素一样可以设置宽度与高度。
img, input, select, button, textarea
6.4, 常见的空元素
br, hr, img, input, link, meta
6.5,不同元素之间的转换方式
转换为块级元素:  display:block 转换为行内块元素: display:inline-block 转换为行内元素: display: inline
7, HTML语义化标签
根据内容的结构化,选择合适的标签,便于开发者阅读,写出更优雅的代码,让浏览器爬虫和浏览器很好的解析。
7.1,常见的语义化标签
header, nav, article, section, aside, footer, h1-h6, title, main, strong, em, address
好处:(1)为了在没有css样式情况下,也可以很好地呈现出内容结构,代码结构。(2)提高用户体验:title,alt用于解释名词或解释图片信息。(3)有利于SEO: 和搜索引擎建立良好沟通,有助于爬虫抓取更多的有效信息,爬虫依赖于标签来确定上下文和各个关键字的权重;(4)方便其他设备解析。(盲人阅读器,移动设备。)(5)便于团队开发和维护,语义化更具有可读性。
8,css position定位
position定位有4个值: static,relative,absolute,fixed (1)static:默认值,没有定位,元素出现在正常文档流中。静态定位的元素不会受到top,bootom,left,right  影响。(2 relative:相对定位,相对于正常文档流位置产生移动,元素仍出现在正常文档流中。会受top,bottom, left,right影响。(3)absolute:绝对定位,脱离文档流,绝对定位的元素的位置相对于最近的已定位的父元素,如果该元素的父级元素没有相对定位,那么它的位置相对于html 。(4)fixed:固定定位,脱离文档流,元素的位置相对于浏览器窗口固定位置。即使浏览器窗口是滚动的它也不会移动。
9,元素水平垂直居中
//html
<div class="parent" style="width:400px;height:200px;background:red"><div class="child" style="width:200px;height:100px;background:green"></div>
</div>
// 方法一:子元素相对定位 
// 这种方法只在子元素宽高已知的情况下适用。
.parent{}
.child{position: relative;left:100px;top:50px
}
// 方法二:子元素相对于父元素绝对定位,并配合使用负值的 margin
// 最常用的方法,这种方法只能在子元素宽高已知的情况下使用。
.parent{position: relative;
}
.child{position: absolute;top:50%;left:50%;margin-top: -50px;margin-left: -100px
}
// 方法三:子元素相对父元素绝对定位,并使用calc()计算属性
// 思想上同上,只不过用计算属性代替了偏移量和margin,这种方式同样只在子元素宽高已知的情况下使用。
.parent{position: relative;
}
.child{position: absolute;top:calc(50% - 50px);left:calc(50% - 100px)
}
// 方法四:子元素相对于父元素绝对定位,并使用 transform属性这种方式和第二、第三方法类似,只不过是用了transform偏移量实现了负值 margin的效果。不同的地方在于,使用  transform  对子元素的宽高没有要求,在未知宽高的情况下依然适用。这种方式在子元素是单行或多行文本的时候要求垂直居中的情况下十分适用。
.parent{position: relative;
}
.child{position: absolute;top:50%;left:50%;transform:translate(-50%,-50%)
}
// 方法五:子元素相对于父元素绝对定位(偏移量都是0),子元素设置margin:auto// 这种方式同样只在子元素宽高已知的情况下使用。
.parent{position: relative;
}
.child{position: absolute;top:0;right:0;bottom:0;left:0;margin:auto
}
// 方法六:父元素display:flex,子元素margin:auto// 最简单的方式,子元素宽度已知或者未知的情况都适用
.parent{display:flex
}
.child{margin:auto;
}
// 方法七:父元素设置 display:flex,以及内容的水平和垂直居中
.parent{display:flex;justify-content: center;align-items: center
}
.child{}
// 方法八:通过line-height和align-text实现块内元素中,行内元素居中// 适用条件:包裹的必须是行内元素
.parent{text-align: center;line-height: 200px
}
.child{}<div class='parent' style='width:400px;height: 200px;background: red;'><span>这里必须是块内元素</span>
</div>
10,BFC 块级格式化上下文
BFC: (Block Formatting context) 块级格式化上下文 ,BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,并且在一个BFC中,块盒与行盒都会垂直的沿着其父元素的边框排列。// 10.1,如何创建BFC(1)float 的值不是none。例如:left,right。(2)position的值不是static或者relative。例如:absolite,fixed 。(3 display的值是inline-block,inline-flex, flex,table-cell,table-caption。(4)overflow的值不是visible。例如:hiddle 。
11,闭包
闭包其实就是一个函数,只不过该函数能访问其他函数里的内容变量,这些变量不会因函数执行完毕而销毁,而是始终保存在内存中。作用:闭包能够保护函数内的变量安全;不会造成全局变量的污染。缺点:占用内存比较大,还需要手动释放。
12,原型与原型链
原型:javascript中每个函数都存在有一个原型对象属性prototype,并且所有函数的默认原型都是Object的实例。原型链:当访问一个对象的某个属性时,先在自身属性中查找,找到返回;如果没有找到,则沿着它的__proto__ 隐式原型上查找,找到返回;如果最终还没有找到,则返回undefined。
13 用一个 div 实现旋转的图片
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>动画</title><style>*{margin:0;padding:0}@keyframes mycircle{to{transform:rotate(0deg)}from{transfrom:rotate(360deg)}}img{width:200px;height:200px;border-radius:50%;animation:mycircle 3s linear infinite}</style>
</head>
<body><img src="./circle.jpg" alt="">
</body>
</html>
13.1 动画( animation ),转换( transform )和 过渡 (transition):
// animation 至少包含两个属性:1)动画名称;2)完成一个周期所需要的时间。
// 使用方法:animation:动画名称 完成一次动画所需的时间 动画运行速度 动画播放的次数// 动画名称就是说 @keyframes 动画名称 {}
// transform 属性应用于元素的 2D 或者 3D 转换,这个属性允许你将元素旋转,缩放,移动,倾斜等。// 旋转:transform:rotate(旋转度数)
transform:rotate(30deg) //元素旋转30度// 缩放:transform:scale(x,y) 参数代表: X 轴和 Y 轴缩放比例。
transform:scale(1.2) // X轴和Y轴同时放大1.2倍// 移动:transform:translate(X,Y) 参数:移动的最终坐标。
// transform:translateX()或者transform:translateY()
transform:translate(200,300)// 倾斜:transform:skew(x-angle,y-angle)
// transition 样式过渡,从一种效果逐渐改变为另一种效果
// 用法:transition: 属性名 完成过渡需要的时间 过渡的速度 何时开始div{width:100px;height:100px;background: red;transition:width 4s linear 1s;
}
div:hover{width:300px;
}
14 Flex 布局
flex布局是一种弹性布局,布局样式比较灵活,在大多数情况下可以代替float而且不会脱离文档流。要想让父容器变成flex布局,则必须设置display:flex  。
14.1父容器属性
// 1. 用于父元素的样式:(1)flex-direction :设置主轴方向。取值: row  (向右)  |    row-reverse  (向左)   |    column  (向下) |  column-reverse   (向上)(2) flex-wrap  : 是否换行。取值: nowrap  (不换行)   |    wrap  (换行)(3) flex-flow  : 是  flex-direction  和  flex-wrap  的缩写。默认  flex-flow : row nowrap (4) justify-content  :决定子元素水平方向排列方式。(假设主轴方向向右,即  flex-direction:row )取值: flex-start  (自左向右排列) |  flex-end  (自右向左排列) |  center  (居中) |  space-between  (两端对齐) |  space-around  (均匀分布)(5) align-items  : 决定子元素垂直方向排列方式。(假设主轴方向向右,即  flex-direction:row )取值: flex-start  (自上而下排列) |  flex-end  (自下而上排列) |  center  (居中) |  baseline  (第一个子元素的文字基线对齐) | stretch (子元素高度会和父元素高度一样高)(6) align-content  : 父元素所包含的行在交叉方向有空余空间时,如何分别空间。属性定义了多根轴线的对齐方式,如果项目自有一根轴线,该属性不起作用。取值: flex-start  (自上而下排列) |  flex-end  (自下而上排列) |  center  (居中) |  baseline  (第一个子元素的文字基线对齐) |  stretch  (子元素高度会和父元素高度一样高)
// 2. 用于子元素的样式(1) order  : 定义子元素的排列顺序。数组越小,排列越靠前,默认为 0。(2) flex-grow  : 定义子元素的放大比例,默认 0,即如果存在剩余空间,也不放大。-如果所有的子元素的  flex-grow  属性值都是 1( flex-grow:1 ),则它们将等分剩余空间。
-如果一个子元素的  flex-grow:2 ,其他的子元素  flex-grow:1 ,则前者占据的剩余空间将比其他子元素多一倍。(3) flex-shrink :定义子元素的缩小比例,默认值1,即如果空间不足,该值子元素将缩小。如果所有子元素的  flex-shrink  属性都是 1( flex-shrink:1 ),则都将等比缩小。
如果一个子元素的  flex-shrink:0 ,其他项目都为  flex-shrink:1 ,则空间不足时,前者不缩小。(4) flex-basis : 定义在分配多余空间之前,子元素占据的主轴空间。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为  auto ,即项目的本来大小。它可以设置为跟  width  或者  heigh  属性一样的值(比如  350px ),则项目将占据固定空间。(5) flex : 是  flex-grow , flex-shrink  和  flex-basis  的简写。默认值  flex:0 1 auto 。后两个属性可选。(6) align-self : 允许单个子元素有与其他子元素不样的对齐方式,可覆盖  align-items  属性。取值: auto  (默认值,表示继承父元素的  align-items  属性,如果没有父元素,则等同于  stretch ) |  flex-start  (自上而下排列) |  flex-end  (自下而上排列) |  center  (居中) |  baseline  (第一个子元素的文字基线对齐) |  stretch  (子元素高度会和父元素高度一样高)
15 ul 和 ol 列表
// ul 无序列表
// ol 有序列表
// 无序列表  <===>  有序列表 通过 list-style-type
//无序列表取值:list-style-type:disc(实心圆) | circle(空心圆) | aquare(实心方块) | none(无)
//有序列表取值:list-style-type:decimal(阿拉伯数字带圆点) | lower-roman(小写罗马数字) |
// upper-roman(小写罗马数字) | lower-alpha(小写英文字母) | upper-alpha | none//list-style-image:url(图片地址)  图片作项目符号。
//list-style-position:outside | inside 图片相对于li列表项内容位置,outside表示在li标签内。
//list-style:列表的复合属性
//语法:list-style:url() none outside.
16 各个浏览器内核和前缀
Chrom(谷歌浏览器)    |  blink内核   |  -webkit-
Firefox(火狐浏览器)  |  Gecko内核   |  -moz-
IE(IE浏览器)        |  Trident内核  |  -ms-
Opera(欧朋浏览器)    |  presto内核   |  -o-
17 img 标签边距问题解决办法
原因:块级元素包含内联元素如图片文字等时,内联元素默认是和父级元素的  baseline (基线)对齐的,而 baseline  又和父级元素底边有一定的距离(这个距离和  font  有关,不一定是  5px ),所以以上代码的效果中不同 div  之间有间隙,这是因为图片与父元素的底边有距离。
(1) img 标签转化为块级元素。
(2) 通过 float 浮动解决。
(3) 父容器的字号设置为 font-size:0; 子元素的字号重新设置。
(4) 更改图片的对齐方式 vertical-align:top img{vertical-align:top}
18 JavaScript 事件的捕获和事件冒泡
DOM  事件流存在三个阶段:捕获阶段、目标阶段、冒泡阶段。事件捕获:当鼠标点击或者触发 DOM 事件时(被触发 DOM 事件的这个元素被称为事件源),浏览器会从根节点  => 事件源(由外到内)进行事件传播。事件冒泡:事件源 => 根节点(由内到外)进行事件传播。 DOM  标准事件流的触发的先后顺序为:先捕获,再冒泡。即当触发  DOM  事件时,会先进行事件捕获,捕获到事件源之后通过事件传播进行事件冒泡。
// 事件监听  addEventListener  方法:
// 第一个参数表示事件名称;
// 第二个参数触发事件后要执行的函数;
// 第三个参数默认值 false 表示事件冒泡阶段调用事件处理函数;true 表示事件捕获阶段调用事件处理函数。
element.addEventlistener(event,function,useCapture)
18.1 事件冒泡实例
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>事件冒泡</title><style>#parent{width:200px;height: 200px;background: greenyellow}#child{width:100px;height: 100px;background:red}</style>
</head>
<body><div id="parent">父元素<div id="child">子元素</div></div><script type="text/javascript">var parent = document.getElementById("parent");var child = document.getElementById("child");document.body.addEventListener("click",function(e){console.log("click-body");},false);parent.addEventListener("click",function(e){console.log("click-parent");},false);child.addEventListener("click",function(e){console.log("click-child");},false);</script></body>
</html>
// 当点击子元素时,执行结果: click-child  click-parent  click-body
// 当点击父元素时,执行结果: click-parent click-body
// 事件执行顺序是:从 事件源 ==> 根节点。 
事件执行顺序是由内到外的,这就是事件冒泡。如果点击子元素不想触发父元素的事件,可使用  event.stopPropagation()  来阻止事件冒泡。
child.addEventListener("click",function(e){console.log("click-child");e.stopPropagation(); // 阻止事件往外冒泡。
})
18.2 事件捕获实例
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>事件冒泡</title><style>#parent{width:200px;height: 200px;background: greenyellow}#child{width:100px;height: 100px;background:red}</style>
</head>
<body><div id="parent">父元素<div id="child">子元素</div></div><script type="text/javascript">var parent = document.getElementById("parent");var child = document.getElementById("child");// false 表示在事件冒泡阶段,调用事件处理函数。// true 表示在事件捕获阶段,调事件处理函数。document.body.addEventListener("click",function(e){console.log("click-body");},false);parent.addEventListener("click",function(e){console.log("click-parent-事件传播");},false);parent.addEventListener("click",function(e){console.log('click-parent-事件捕获')},true)child.addEventListener("click",function(e){console.log("click-child");// 阻止事件冒泡//e.stopPropagation();},false);</script></body>
</html>
// 当点击子元素时,(先捕获再冒泡)
// 执行结果是: click-parent-事件捕获   click-child   click-parent-事件传播  click-body//父元素通过事件捕获的方式,注册了click事件,所以在事件捕获阶段就会触发,然后到了目标阶段,即事件源,
//之后进行事件冒泡,parent同时也用冒泡方式注册了click事件,所以这里会触发冒泡事件,最后到根节点
//(body)。这就是整个事件流程。(捕获阶段  ==>  目标阶段  ==>  冒泡阶段  ==>  根节点)
18.3 事件委托(事件代理)
事件委托也可以叫事件代理,是事件冒泡与事件捕获的运用。概念:会把一个或者一组元素的事件委托到它的父层或者更外层元素上,真正绑定事件的是外层元素,当事件相应到需要绑定的元素上时(事件捕获),会通过事件冒泡机制从而触发它的外层元素的绑定事件上,然后在外层元素上执行函数。优点:减少内存消耗,节约效率。
// 实例
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>事件委托</title><style>ul li{margin-bottom: 20px;background: red;}</style>
</head><body><ul id="list"><li class="class-1">item 1</li><li>item 2</li><li class="class-1">item 3</li><li>item 4</li><li>item 5</li><li class="class-1">item 6</li></ul>
</body>
<script>document.getElementById('list').addEventListener('click', function (e) {// 兼容性处理var event = e || window.event;// 获取目标元素var target = event.target || event.srcElement;   // 通过类名,判断哪个元素被触发了。if (target.className === 'class-1') {console.log('the content is: ', target.innerHTML);}});
</script>
</html>
19. JavaScript 中哪些是传数值,哪些是传地址
在  JavaScript  中,有两个不同的方式可以操作数据的值,分别是 传值 和 传址。根据操作数据方式的不同,数据类型分为两种类型:基本数据类型 和 引用数据类型。基本数据类型有:数字( number )、布尔类型( boolean )、字符串( string )。其操作方式为, 传数值。引用数据类型有:对象( object )、数组( array )、函数( function )。其操作方式为, 传地址。
20 如何实现一个定时器
 function playTime(time){// setInterval 设置定时器。var stopTime = setInterval(function(){console.log(time)time--;if(time === -1){// clearInterval 关闭定时器clearInterval(stopTime)}},1000)
}//调用函数
playTime(15)
21 重绘与回流
回流:当渲染树(rander tree)中的一部分或者全部因为元素的尺寸,布局,隐藏等改变,而需要重新构建渲染树这个过程。回流一定引起重绘,重绘不一定引起回流。
// 触发回流的css属性
// 1. 盒子模型相关的
width,height,padding,margin,display,border-width,border,min-height//定位属性以及浮动属性
position, top, left, right, bottom, float, clear// 改变节点内部文字结构
text-align, overflow-y, font-weight, overflow, font-family, line-height, 
vertical-align, white-space, font-size。
重绘:当渲染树的一些元素需要更新属性,而这些属性影响外观,风格,样式,但不影响布局,这个重新渲染的过程。
// 触发重绘的属性
color, border-style, border-radius, visibility, background, text-decoration, outline
box-shadow
优化方法:(1)避免使用触发重绘回流的  css  属性。(2)将容易产生重绘的元素独立到一个图层。(3)避免使用  table  布局,可能很小改动会造成整个  table  的重新布局。(4)不要一条条的修改  DOM  样式,预先定义好  class ,然后修改  className 。
22 display : none , visibility:hidden 和 opacity:0 之间的区别
1. 空间占据:display:none  隐藏后不占据额外空间,它会产生回流和重绘。visibility:hiddle  和  opacity:0  元素虽然隐藏了,但仍占据空间,它们两个只会引起页面重绘。
2. 子元素继承display:none  不会被子元素继承。visibility:hidden  会被子元素继承,可以通过设置子元素  visibility:visible  使子元素显示出来。opacity:0  会被子元素继承,但是不能通过设置子元素  opacity:1  使子元素显示出来。
3. 事件绑定display:none  无法触发上面绑定的事件。visibility:hidden  无法触发上面绑定的事件。opacity:0  可以触发上面绑定的事件。
4. 过渡动画transition  对  display  是无效的。transition  对  visibility  也是无效的。transition  对  opacity  是有效的。 
23.1 Object.defineProperty() 方法使用。

 Object.defineProperty()  方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回这个对象。
// 语法:Object.defineProperty(obj,propName,descriptor)// 参数说明:
// obj:必需。目标对象。
// propName:必需的。需定义或者修改的属性的名字。
// descriptor:必需。目标属性所拥有的特性。
属性描述符是  Object.defineProperty(obj, propName, descriptor)  方法里的  descriptor  这个对象。属性描述符有两种主要形式:数据描述符和存取描述符。数据描述符是一个具有值的属性,该值可能是可写的,也可能是不可写的。存取描述符是由 getter-setter函数对描述的属性。属性描述符必须是这两种形式之一;不能同时是两者。
// (1)数据描述符
let obj = {}
object.defineProperty(obj,"name",{// enumerable:true时,该属性才能够出现在对象的枚举属性中。enumerable:false, //是可选值,默认值是 false// configurable 该属性的作用是:目标属性是否可以 delete 删除,是否可以再次设置特性。configurable:false, //是可选的,默认值是 false。// 当 writable:true 时,value 才能被赋值运算符改变。默认值为 false。 writable:false,// value 对应的是数字,可以是任何有效的 javaScript 数据类型。value:"张三"
})
// (2)存取描述符
let obj = {}
let newVal;
Object.defineProperty(obj,"name",{enumerable:false,configurable:false,get:function(){// 当获取值的时候,触发函数。console.log("读取数据时,执行里面的代码。")return newVal},set:function(value){// 当设置值的时候,触发函数,设置的新值通过参数 value 拿到。console.log("写入数据时,执行里面的代码。",value)}
})
存取描述符有  set  和  get  函数,但是不存在  writable  和  value  这2个属性。get  : 一个给属性提供  getter  的方法,如果没有  getter  则为  undefined  。当访问该属性时,该方法被执行,方法执行是没有参数传入,但是会传入 this 对象。(由于继承关系,这里的  this  并不一定是定义该属性的对象)。默认值为  undefined 。set  : 一个给属性提供  setter  的方法,如果没有  setter  则为  undefined 。当属性值修改时,触发执行该方法。该方法将接受唯一参数,即该属性新的参数值。默认值为  undefined 。 
属性描述符可同时具有的键值
configurableenumerableValuegetset
数据描述符YesYesYesNoNo
存取描述符YesYesNoYesYes
23.2 Vue的双向数据绑定原理

 vue.js  是采用数据劫持结合发布者-订阅者模式的方式,通过  Object.defineProperty()  来劫持各个属性的  setter  和  getter 。在数据变动时,发布消息给订阅者,触发相应的监听回调。具体步骤:第一步:需要数据监听器(Observe) 对数据对象进行递归遍历,包括子属性对象的属性,都加上 setter 和getter这样的话,给这个对象的某个值赋值。就会触发 setter,那么就能监听到了数据变化。第二步: compile  解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图。第三步:Watcher 订阅者是 Observer 和 Compile 之间通信的桥梁,主要做的事:(1)在自身实例化时,往属性订阅(dep)里面添加自己;(2)自身必须有一个 update() 方法;(3)待属性变动 dep.notice()通知时,能调用自身的 update() 方法,并触发 Compile 中绑定的回调。第四步:MVVM 作为数据绑定的入口,整合 Observer、Compile 和 Watcher 三者,通过 Observe 来监听自己的 modes数据变化,通过 Compile 来解析编译模板指令,最终利用 Watcher 搭起 Observer 和 Compile 之间的通信桥梁,达到数据变化 ->  视图更新;视图交互变化 -> 数据 model 变更的双向绑定效果。
// 简单的双向数据绑定实例
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>通过object.difinePorperty实现简单的数据双向绑定</title>
</head>
<body><input type="text" id="input_id"><p id='p_id'></p>    
</body>
<script>var obj = {}var inputId = document.getElementById("input_id")var pId = document.getElementById("p_id")inputId.addEventListener('keyup',function(e){obj.name = e.target.value})Object.defineProperty(obj,'name', {get:function(){// 获取对象属性值的时候,执行里面的代码。console.log(1111)},set:function(value){// 设置对象属性值的时候,执行里面的代码。inputId.value = valuepId.innerHTML = value}})
</script> 
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/810884.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

rocky9 yum 安装与配置MySQL8

1.前置条件&#xff1a; 把yum包更新到最新 [rootlocalhost ~]# yum update 查看系统中是否已安装 MySQL 服务 rpm -qa|grep mysql 如果有安装mysql,则需要先卸载之前安装的mysql&#xff1a;yum -y remove mysql 然后再查看mysql是否都卸载完成,如果还有没卸载完成的&am…

小程序开发SSL证书下载和安装

在开发小程序时&#xff0c;确保数据的安全传输至关重要&#xff0c;而实现这一目标的关键在于正确获取与安装SSL证书。以下详细介绍了从获取到安装SSL证书的完整流程&#xff0c;以助您为小程序构建可靠的加密通信环境。 一、小程序SSL证书类型选择&#xff1a; 域名验证型D…

创新指南|全球需求低迷中国企业出海趋势洞察和创新机会

对于企业出海来说&#xff0c;第一步判断趋势非常重要&#xff0c;这甚至事关企业生死。比如十年前的2014年&#xff0c;中国最大的两家电商平台阿里和京东成功IPO&#xff08;上市&#xff09;后&#xff0c;认为接下来最大的机会在于中国市场的消费升级。与阿里、京东不同&am…

TypeScript基础语法

这里写自定义目录标题 变量条件控制循环函数类和接口模块开发 变量 TypeScript在JavaScript的基础上加入了静态类型检查功能&#xff0c;因此每一个变量都有固定的数据类型。 let msg: string hello worldlet 声明变量的关键字&#xff0c; const 则代表常量 msg 变量名称 &…

Linux:软件包管理器 - yum

Linux&#xff1a;软件包管理器 - yum Linux的软件安装方式源代码安装rpm包安装yum安装 yum三板斧yum listyum installyum remove yum生态yum源 Linux的软件安装方式 源代码安装 在Linux下安装软件, 一个通常的办法是下载到程序的源代码, 并进行编译, 得到可执行程序 源代码安…

git知识

如何将develop分支合并到master分支 #简单版 git checkout master git pull origin master git merge origin/develop # 解决可能的冲突并提交 git push origin master#复杂版 git checkout master # 拉取远程 master 分支的最新代码并合并到本地 git pull origin master # 拉…

新时代·高质量·硬道理丨开放的大门越开越大、开放的水平越来越高

新时代下&#xff0c;中国坚定不移地实施扩大高水平对外开放战略&#xff0c;致力于构建更高层次、更宽领域的开放型经济体系。以下是对新时代高质量硬道理这一主题下&#xff0c;中国开放大门越开越大、开放水平越来越高的几个关键点分析&#xff1a; 全方位开放格局 政府工…

YOLOv8打印模型结构配置信息并查看网络模型详细参数:参数量、计算量(GFLOPS)

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

计算机基础知识-第7章-程序的本质(2)——算法与数据结构概论

一、算法数据结构程序 提出这一公式并以此作为其一本专著的书名的瑞士计算机科学家尼克劳斯沃思&#xff08;Niklaus Wirth&#xff09;由于发明了多种影响深远的程序设计语言&#xff0c;并提出结构化程序设计这一革命性概念而获得了1984年的图灵奖。他是至今惟一获此殊荣的瑞…

Java——测试相关

1、测试的常用方法 单元测试&#xff1a;针对软件中最小可测试单元进行的测试&#xff0c;如类、方法等。功能测试&#xff1a;检查软件的各项功能是否按照需求规格书执行&#xff0c;通常包括正常功能、边界情况和异常情况的测试。性能测试&#xff1a;检查软件的速度、响应时…

【Linux杂货铺】文件系统

目录 &#x1f308;前言&#x1f308; &#x1f4c1; 硬盘 &#x1f4c2; 物理结构 &#x1f4c2; 存储结构 &#x1f4c2; CHS定址法 &#x1f4c2; 操作系统对硬盘的管理和抽象 &#x1f4c1; 文件系统 &#x1f4c2; 分区 &#x1f4c2; 分组 &#x1f4c2; inode号 分配…

1113. 红与黑--Flood Fill 算法

目录 1113. 红与黑--Flood Fill 算法---宽搜&#xff08;BFS&#xff09; 输入格式 输出格式 数据范围 输入样例&#xff1a; 输出样例&#xff1a; 思路&#xff1a; 代码&#xff1a; 运行结果&#xff1a; 1113. 红与黑--Flood Fill 算法---宽搜&#xff08;BFS&am…

无人机技术在光伏电站勘探中的重要应用

随着科技的不断进步和创新&#xff0c;无人机技术在各个领域中都发挥着越来越重要的作用。其中&#xff0c;光伏电站对于无人机的应用也成为了行业内的高效运维方式之一&#xff0c;凭借无人机卓越的性能和可靠性&#xff0c;有效的减少了人力运维的危险性和延迟性&#xff0c;…

Java研学-RBAC权限控制(三)

四 部门管理 1 数据库表 CREATE TABLE department (id bigint(20) NOT NULL AUTO_INCREMENT,name varchar(255) DEFAULT NULL,sn varchar(255) DEFAULT NULL,PRIMARY KEY (id) ) ENGINEInnoDB AUTO_INCREMENT9 DEFAULT CHARSETutf8;2 实体类 Data public class Department {…

股票价格预测 | Python股票价格数据导入和处理

文章目录 文章概述代码设计导入处理文章概述 股票价格预测 | Python股票价格数据导入和处理 代码设计 导入 import os import numpy as np import csv import pandas as pd import matplotlib.pyplot

【NC16596】计算系数

题目 计算系数 组合数&#xff0c;快速幂 思路 这是一道数学题&#xff0c;由之前的数学知识可以知道&#xff0c;题目要我们算一个数&#xff1a; ( C k m a n b m ) m o d 10007 (C_k^ma^nb^m)\mod\ 10007 (Ckm​anbm)mod 10007 题意很明显&#xff0c;没有弯弯绕&#xff…

python入门(一)配置环境和选择IDE

Python&#xff0c;作为一种简洁易懂的编程语言&#xff0c;近年来在全球范围内受到了广泛的关注和追捧。它不仅语法简单明了&#xff0c;易于上手&#xff0c;而且拥有强大的第三方库和广泛的应用领域。从数据分析、机器学习到Web开发&#xff0c;Python都能发挥出色的性能&am…

华为OD-C卷-密码解密[100分]

题目描述 给定一段“密文”字符串 s,其中字符都是经过“密码本”映射的,现需要将“密文”解密并输出。 映射的规则(a ~ i)分别用(1 ~ 9)表示;(j ~ z)分别用("10*" ~ "26*")表示。 约束:映射始终唯一。 输入描述 “密文”字符串 输出描述 …

【京东、字节后端二面】讨论不同的系统性能瓶颈点:流量增加时,秒杀系统的性能瓶颈在哪里呢?

1 短网址系统 1.1 如何设计一个短网址系统。什么是这个短网址系统啊&#xff1f; 短网址系统是一种将长网址转换为更短、更易于分享的网址的服务。这类系统特别受欢迎&#xff0c;因为它们可以使复杂的URL变得简单&#xff0c;便于口头传播和在社交媒体上分享&#xff0c;同时…

Vue路由跳转及路由传参

跳转 跳转使用 router vue 的路由跳转有 3 个方法&#xff1a; go 、 push 、 replace go &#xff1a;接收数字&#xff0c; 0 刷新&#xff0c;正数前进&#xff0c;负数后退 push &#xff1a;添加&#xff0c;向页面栈中添加一条记录&#xff0c;可以后退 replace &#…