笔试题答案整理

跨域怎么实现?jsonp的原理是什么?
h5新标签有哪些?为什么要加强语义化?
为什么要清除浮动?怎么清除浮动?
行内元素、块元素有哪些?它们有什么不同?
有哪几种存储方式?有什么不同?
setTimeout输出值的时候,如何实现i按序输出?
vue实现双向绑定的原理?
vue组件之间的传值?
点击按钮进行数据请求,怎么实现按序执行请求?
怎么让文本不自动换行?怎么让超过文本部分变成省略号?
vue的生命周期有哪些?它们有什么不同?
详解:
1. 跨域怎么实现?jsonp的原理是什么?
跨域,指的是浏览器不能执行其他网站的脚本。浏览器执行
javascript
脚本时,会检查这个脚本属于哪个页面,如果不是同源页面,就不会被执行。解决办法:
①JSONP:注意JSONP只支持GET请求,不支持POST请求。
原理:ajax请求受同源策略影响,不允许进行跨域请求,而script标签src属性中的链接却可以访问跨域的js脚本,利用这个特性,服务端不再返回JSON格式的数据,而是返回一段调用某个函数的js代码,在src中进行了调用,这样实现了跨域。
②代理:写后端接口,在后端调用页面拿到返回值返回给html文件。相当于绕过了浏览器,就不会存在跨域问题。
③PHP端修改header
header('Access-Control-Allow-Origin:*');//允许所有来源访问
header('Access-Control-Allow-Method:POST,GET');//允许访问的方式2. h5新标签有哪些?为什么要加强语义化?
新标签:
文档类型设定:
<!doctype html>
;字符设定:
<meta charset="utf-8">
;常用新标签:
header
,一般作为网页的头部使用,可以多个;footer
,底部,不一定是文档最底部,可以多个;aside
,侧边栏;nav
,导航栏;article
,独立内容区域,与session类似,用于文章blog、帖子、短文或者回复、评论等;section
,代表某一个区域/分区/页面/文档的一部分区域,有独立的内容,但结构相近,就可以用section,范围比div大,语义比div更强,可以包含header、h1-h6
……凸显语义的标签;datalist
,标签定义选项列表,请与 input 元素配合使用该元素;<input type="text" value="输入" list="TFboys"/> <!-- input里面用list -->
<datalist id="TFboys"> <!-- datalist里面用id -->
<option>易烊千玺</option>
<option>王俊凯</option>
<option>王源</option>
</datalist>fieldset
,可将表单内的相关元素分组,打包legend(为fieldset
元素定义标题)使用;<fieldset>
<legend>用户登录</legend>
用户名: <input type="text"><br />
密 码: <input type="password">
</fieldset>
address
,标签定义文档或文章的作者/拥有者的联系信息,字体样式默认倾斜;
time
,时间标签,主要用于搜索引擎和其它一些内容引擎特殊的解析和展示;
hgroup
,专门用来包含标题h标签的分组;
detail
,细节、详情 ,open属性:默认展开,summary相当于详情的标题;
新增了许多input type属性:email
、tel
、url
、number
、search搜索框,加强语义
、range自由拖动滑块
、time
、date日期
、datetime时间
、month
、week
新增了许多input的属性:placeholder占位符,默认文字
、autofocus页面加载时自动获得焦点
、multiple多文件上传
、autocomplete
、required必填项
、accesskey规定激活元素的快捷键
多媒体标签:embed定义嵌入的内容
、audio播放音频
、video播放视频
;
src导入
,autoplay自动播放
、controls是否默认显示播放件
、loop循环播放
......
原因:1.默认样式不一样 ;2.有SEO优化作用;
3.为什么要清除浮动?怎么清除浮动?
产生原因:子盒子浮动导致的父盒子内高度为 0 ,父级盒子不能被撑开,发生高度塌陷的情况。
带来的负作用:
背景不能显示
边框不能撑开
margin和padding值不能正确显示
清除浮动的方法:
给父盒子设置合适的高度;
给父盒子添加样式
overflow:hidden/auto;
(这个属性相当于触发BFC,让父级紧贴内容,包括使用了浮动的盒子)(为了去除兼容性问题,会添加zoom:1;
)在父盒子里面的子盒子后面添加一个子盒子,如div,添加样式
.clear{clear:both;}
;采用伪元素,给父元素追加
:after
,给父元素添加一个类.clearfix{content:"";clear:both;}
BFC块级格式化上下文的特征:
内部的Box会在垂直方向,从顶部开始一个接一个地放置;
Box垂直方向的距离由margin决定,属于同一个BFC的两个相邻Box的margin会发生叠加。
每个元素的margin box的左边, 与包含块border box的左边相接触,即使存在浮动也是如此。
BFC的区域不会与float box叠加。
BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然。
计算BFC的高度时,浮动元素也参与计算。
创建块级格式化上下文:
浮动 (元素的 float不为 none)
绝对定位元素 (元素的 position为 absolute 或 fixed)
行内块 inline-blocks (元素的 display: inline-block)
表格单元格 (元素的 display: table-cell,HTML表格单元格默认属性)
表格标题 (元素的 display: table-caption,HTML表格标题默认属性)
overflow的值不为 visible的元素(元素的 overflow: hidden,overflow: auto)
弹性盒子 flex boxes (元素的 display: flex 或 inline-flex)
4.行内元素、块元素有哪些?它们有什么不同?
行内元素:b、span、a、u、em、i、img、input、select、label、textarea、button
块级元素:div、h、ol、ul、dl、li、table、td、th、tr、dd、dt、p、caption
行内元素的特点:
1、行内元素只能容纳文本或者其他行内元素。
2、宽度只与内容有关。
3、和其他元素都在一行上。
4、高,行高及外边距和内边距部分可改变。
块级元素的特点:
1、高度,行高以及外边距和内边距都可控制。
2、总是在新行上开始,占据一整行。
3、它可以容纳内联元素和其他块元素。
4、宽度始终是与浏览器宽度一样,与内容无关。
区别:
1、行内元素会在一条直线上分列,都是统一行的,程度偏向分列。
块级元素各盘踞一行,垂直偏向分列;块级元素重新行开端停止接着一个断行。
2、行内元素不可以包括块级元素,只能包容文本或许其余行内元素。
块级元素能够包括行内元素和块级元素,还能够包容内联元素和其余元素;。
3、行内元素与块级元素属性的分歧,主要在盒模子属性上。
行内元素设置width无效,height无效(能够设置line-height),margin、padding设置上下有效。
5. 有哪几种存储方式?有什么不同?
cookie
、localStorage
、sessionStorage
;
相同点:都保存在浏览器端;
不同点:
①传递方式不同
cookie
数据始终在同源的http请求中携带(即使不需要),即cookie
在浏览器和服务器间来回传递。
sessionStorage
和localStorage
不会自动把数据发给服务器,仅在本地保存。
②数据大小不同
(cookie
数据还有路径(path)的概念,可以限制cookie只属于某个路径下。) 存储大小限制也不同,cookie数据不能超过4k,同时因为每次http请求都会携带cookie
,所以cookie只适合保存很小的数据,如会话标识。
sessionStorage
和localStorage
虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。
③数据有效期不同
sessionStorage
:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持;
localStorage
:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;
cookie
只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。
④作用域不同
sessionStorage
不在不同的浏览器窗口中共享,即使是同一个页面;
localStorage
在所有同源窗口中都是共享的;
cookie
也是在所有同源窗口中都是共享的。
6. setTimeout输出值的时候,如何实现i按序输出?
for(var i=0;i<10;i++){
setTimeout(function ten(){
console.log(i);
},10);
}//输出结果是10个10
问:为什么输出的是10个10?
答:JS是一个单线程的解释器,setTimeout本质是间隔一定时间将任务添加到任务队列中。输出的时候for循环作为主线程已经执行完毕,此时作用域中的i=5
;按序执行10次输出i
,就会输出10个10;
问:如何输出成按序输出?
答:方法一:
生成一个立即执行的函数,将i
作为参数输入(闭包)
for(var i=0;i<10;i++){
(function(i){
setTimeout(function ten(){
console.log(i);
},10);
})(i)
}
方法二:用es6中的let来声明变量,相当于let在每个块级作用域里面都声明了一个变量i
for(let i=0;i<10;i++){
setTimeout(function ten(){
console.log(i);
},10);
}
方法三:使用setTimeout
的第三个参数
for(var i=0;i<10;i++){
setTimeout(function ten(){
console.log(i);
},10,i);
}
7. vue实现双向绑定的原理?
VUE实现双向数据绑定的原理就是利用了 Object.defineProperty()
方法重新定义了对象获取属性值get和设置属性值set的操作来实现的;
Object.defineProperty()
三个参数:要操作的对象,要定义或修改的对象属性名,属性描述符;
其中,属性描述符是一个对象,主要有两种形式(任选其一):数据描述符和存取描述符(get、set)。
var obj = { };
var name;
//第一个参数:定义属性的对象;第二个参数:要定义或修改的属性的名称;第三个参数:将被定义或修改的属性描述符。
Object.defineProperty(obj, "data", {
//获取值
get:function () {
return name;
},
//设置值
set:function (val) {
name = val;
console.log(val);
}
})
//赋值调用set
obj.data = 'aaa';
//取值调用get
console.log(obj.data);
这里着重理解data更新,view视图层是怎么更新的:(view更新,要data改变只要进行事件监听即可)利用Object.defineProperty()
对属性设置的set函数,改变了data数据就会触发set函数,在这个函数里面添加更新view视图层的方法即可。
8. vue组件之间的传值?
父传子:
先在父组件中绑定变量
<child :msg="parent"></child>
,parent是定义在父组件中的变量/值;再在子组件中添加props属性接收父组件传递过来的变量
props:['msg']
;最后就可以在子组件中使用
{{msg}}
来表示父组件中parent变量中的值了。子传父:
先在子组件中绑定事件
@change="sendChild"
,触发的时候在setChild
事件中用$emit()
触发父组件中的函数,并将子组件中的变量作为参数传递;methods:{
sendChild:function(){
this.$emit('transparent',this.msg)
}
}在父组件中绑定事件
<child @transparent="getChild"></child>
,当子组件触发这个事件的时候,就可以调用getChild
方法获取到传递过来的参数;methods:{
getChild(msg){
this.user=msg;
}
}兄弟组件互相传值,通过Vuex状态管理传值:
先通过npm加载vuex,创建store.js文件
//store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
const state={name:'Alice'};
const mutations={
newName(state,message){
state.name=message
}
}
export default new Vuex.Store({state,mutations})兄弟组件互相传值,引入bus.js文件,发布者订阅者模式:
import Bus from './bus.js'
//一个子组件触发
methods:{
Bus.$emit('触发的方法名',需要传递的值);
} //一个子组件监听
mounted:{
bus.$on("方法名",(传递的值)=>{ })
}
5. 兄弟组件互相传值$root
//一个子组件触发
this.$root.$emit('触发的方法名',需要传递的值);//一个子组件监听
this.$root.$off("方法名");//每次进入先关闭一下
this.$root.$on("方法名",(传递的值)=>{ })
9.点击按钮进行数据请求,怎么实现按序执行请求?
问:点击页面上一个按钮发送两个ajax请求,其中一个请求会不会等待另一个请求执行完毕之后再执行?
答:不会,这两个异步请求会同时发送,执行的快与慢是看响应的数据量的大小及后台逻辑的复杂程度。
问:怎么让它们按序执行?
答:两种方案:
Ajax2()方法的执行放到Ajax1()的success回调函数的最后一行。
Ajax1()的异步请求方法中,增加一个回调函数 :complete : Ajax2
10.怎么让文本不自动换行?怎么让超过文本部分变成省略号?
white-space:nowrap;
overflow:hidden;
text-overflow:ellipsis;
11.vue的生命周期有哪些?它们有什么不同?
生命周期钩子组件状态最佳实践beforeCreate实例初始化之后,this指向创建的实例,不能访问到data、computed、watch、methods上的方法和数据常用于初始化非响应式变量created实例创建完成,可访问data、computed、watch、methods上的方法和数据,还未挂载到DOM,不能访问到$el属性,$ref属性内容为空数组常用于简单的ajax请求,页面的初始化beforeMount在挂载开始之前被调用,beforeMount之前,会找到对应的template,并编译成render函数-mounted实例挂载到DOM上,此时可以通过DOM API获取到DOM节点,$ref属性可以访问常用于获取信息和操作,ajax请求beforeUpdate响应式数据更新时调用,发生在虚拟DOM打补丁之前适合在更新之前访问现有的DOM,比如手动移除已添加的事件监听器updated虚拟DOM重新渲染和打补丁之后调用,组件DOM已经更新,可执行依赖于DOM的操作避免在这个钩子函数中操作数据,可能陷入死循环beforeDestroy实例销毁之前调用。这一步,实例仍然完全可用,this仍能获取到实例常用于销毁定时器、解绑全局事件、销毁插件对象等操作destroyed实例销毁后调用,调用后,Vue实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁-
注:
其中created和mounted中ajax请求的区别:created的时候视图未出现,请求较多的情况下,会出现白屏;
初始化组件的时候,仅执行beforeCreated/created/beforeMount/mounted四个钩子函数;
当改变data中定义的响应式变量时,会执行beforeUpadate/updated;
初始化和销毁时的钩子函数只会执行一次,beforeUpadate/updated可执行多次;
挂载的时候,子组件完成挂载后,父组件才会挂载;
当子组件完成挂载后,父组件会主动执行一次beforeUpdate/updated钩子函数(仅首次);
销毁父组件时,先将子组件销毁后,才会销毁父组件;