一、CSS hack
目的: 就是使你的CSS代码兼容不同的浏览器,反过来也可以利用CSS hack 为不同版本浏览器定制
编写不同的CSS效果。
概念:由于不同厂商的浏览器或浏览器的不同版本对CSS的支持、解析不一样,导致在不同浏览器的环境中呈现出
不一致的页面展现效果。这时,未获得统一的页面效果,就需要针对不同浏览器或不同版本写特定的CSS样式,
我们把这个过程叫做CSS hack。
1、 CSS hack方式以:条件注释法
这种方式是IE浏览器专有的Hack方式
只有在IE下生效
<!--[if IE]>
这段文字只在IE浏览器显示
<![endif]-->
<!--[if IE 6]>
这段文字只在IE6浏览器显示
<![endif]-->
<!--[if gte IE 6]>
这段文字只在IE6以上(包括)版本IE浏览器显示
<![endif]-->
<!--[if ! IE 8]>
这段文字在非IE8浏览器显示
<![endif]-->
<!--[if !IE]>
这段文字只在非IE浏览器显示
<![endif]-->
2、CSS hack方式二:类内属性前缀法
属性前缀法是在CSS样式属性前加上一些特定浏览器才能识别的hack前缀,以达到
预期的页面展示效果。
说明:在标准模式中
-″减号是IE6专有的hack
“9″ IE6/IE7/IE8/IE9/IE10都生效
“ ″ IE8/IE9/IE10都生效,是IE8/9/10的hack
“9 ″ 只对IE9/IE10生效,是IE9/10的hack
* IE6、IE7
+ IE6、IE7
*+background-color:pink;只有IE6和IE7认识。
3、 选择器前缀法
*html *前缀只对IE6生效
*+html *+前缀只对IE7生效
@media screen9{...}只对IE6/7生效
@media screen {body { background: red; }}只对IE8有效
二、bootstrap实现响应式布局的原理
响应式布局:就是一个网站能够兼容多个终端,而不是为每个终端做一个特定的版本。
这个概念为解决移动互联网浏览而诞生。
利用栅格系统实现响应式布局:
首选,栅格系统用于通过一系列的行(row)与列(column)的组合来创建
布局,“行”必须包含在.container(固定宽度)或 .container-fluid(宽度为100%)中
在Bootstrap3中主要把屏幕分成了三种(这里以行(row)来说明):
.col-xs-* 超小屏幕,手机(宽度<768px)
.col-sm-* 小屏幕,平板(宽度>=768px)
.col-md-* 中等屏幕,桌面显示器(宽度>=992px)
不管在哪种屏幕上,栅格系统都会自动的分12列
这里实现了依据不同的宽度进行改变:
.container {
padding-right: 15px;
padding-left: 15px;
margin-right: auto;
margin-left: auto;
}
@media (min- 768px) {/*当宽度大于768px时触发*/
.container {
750px;
}
}
@media (min- 992px) {/*当宽度大于992px时触发*/
.container {
970px;
}
}
@media (min- 1200px) {/*当宽度大于1200px时触发*/
.container {
1170px;
}
}
.container-fluid { /*这个是宽度默认*/
padding-right: 15px;
padding-left: 15px;
margin-right: auto;
margin-left: auto;
}
三、面试题目及答案:
1、浏览器的存储技术有哪些?
答案:cookie localStorage sessionStorage UserData GlobalStorage
Google Gear Flash ShareObject
(1)Cookie
1)cookie是什么:cookie 是指存储在用户本地终端上的数据,cookie数据会自动
在web浏览器和web服务器之间传输,也就是说HTTP请求发送时,会把
保存在该请求域名下的所有cookie值发送给web服务器,因此服务器监本是
可以读、写存储在客户端的cookie的操作。
2) cookie 的有效期
cookie默认情况下的有效期是很短暂的,一旦用户关闭浏览器,cookie保存的
数据就会丢失。
延长有效期:1.设置http头信息中的cache-control属性的max-age值
2.修改HTTp头信息中的expires属性值来延长有效期
3) cookie 的作用域:它是通过文档源和文档路径来确定的。该作用域通过
cookie的path和domain属性也是可以配置的。
4) cookie的数目和大小的限制:每个web服务器保存的cookie数不能超过
50个,每个cookie保存的数据不能超过4KB。如果超过4KB,服务器会处理不了。
cookie的有点:能用于和服务器通信;当cookie快要过期时,可以重新设置而不是删除。
cookie的缺点:它会随着http头信息一起发送,增加了网络流量(文档传输的负载)
它只能存储少量的数据;它只能存储字符串;有潜在的安全问题。
(2) LocalStorage(sessionStorage)
主要是用来作为本地存储来使用的,解决了cookie存储空间不足的问题,localStorage
中一般浏览器支持的是5M大小,不同浏览器中会有所不同。
localStorage优点:
1)localStorage 拓展了cookie的4K 限制
2)localStorage可以将第一次请求的数据直接存储到本地,这个相当于一个
5M大小的针对于前端页面的数据库,相比于cookie可以节约带宽,但是高版本
的浏览器才支持
3)localstorage 方法存储的数据没有时间限制。
localStorage的缺点:
1)浏览器的大小不同意,并且在IE8以上的版本才支持这个属性
2)目前所有浏览器中都会把localStorage 的值类型限定为
string类型,这个在对我们日常比较常见JSON对象类型需要一些转换。
3)在浏览器的隐私模式下面不可读取
4)localStorage 本质上是对字符串的读取,如果存储内容多的话会消耗内存空间,
会导致页面变卡
5)localStorage不能被爬虫抓取到
sessionStorage与localStorage的唯一一点区别就是localStorage属于永久性存储,而sessionStorage属于当会话结束的时候,sessionStorage中的键值对就会被清空。
(3)、UserData、GlobalStorage、Google Gear
这三种的使用都有一定的局限性,例如userData是IE浏览器专属,它的容量可以达到640K,这种方案可靠,不需要安装额外插件,只不过它仅在IE下有效~
globalStorage适用于Firefox 2+的浏览器,类似于IE的userData~
google gear是谷歌开发出的一种本地存储技术,需要安装Gear组件。
(4)Flash ShareObject
这种方式能能解决上面提到的cookie存储的两个弊端,而且能够跨浏览器,应该说是目前最好的本地存储方案。不过,需要在页面中插入一个Flash,当浏览器没有安装Flash控件时就不能用了。所幸的是,没有安装Flash的用户极少。
强调一下:cookie,localStorage和sessionStorage的异同:
共同点:都是保存在浏览器端,且同源的。
区别:
1)cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递;而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存;
2)cookie数据有路径(path)的概念,可以限制cookie只属于某个路径下;
3)存储大小限制也不同,cookie数据不能超过4k,同时因为每次http请求都会携带cookie,所以cookie只适合保存很小的数据,如会话标识;sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大;
4)数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭;
5)作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的;
2、arguments 对象
arguments 对象是所有(非箭头)函数中都可用的局部变量,此对象
包含传递给函数的每个参数的条目。
arguments对象不是一个 Array 。它类似于Array,但除了length属性和索引元素之外没有任何Array属性。
(function(){return typeof arguments})(); //object
3、如何判断js中的数据类型:typeof、instanceof、 constructor、 prototype方法比较
如何判断js中的类型呢,先举几个例子:
var a = "iamstring.";
var b = 222;
var c= [1,2,3];
var d = new Date();
var e = function(){alert(111);};
var f = function(){this.name="22";};
最常见的判断方法:typeof
alert(typeof a) ------------> string
alert(typeof b) ------------> number
alert(typeof c) ------------> object
alert(typeof d) ------------> object
alert(typeof e) ------------> function
alert(typeof f) ------------> function
其中typeof返回的类型都是字符串形式,需注意,例如:
alert(typeof a == "string") -------------> true
alert(typeof a == String) ---------------> false
另外typeof 可以判断function的类型;在判断除Object类型的对象时比较方便。
判断已知对象类型的方法: instanceof
alert(c instanceof Array) ---------------> true
alert(d instanceof Date) ------------> true
alert(f instanceof Function) ------------> true
alert(f instanceof function) ------------> false
注意:instanceof 后面一定要是对象类型,并且大小写不能错,该方法适合一些条件选择或分支。
根据对象的constructor判断: constructor
alert(c.constructor === Array) ----------> true
alert(d.constructor === Date) -----------> true
alert(e.constructor === Function) -------> true
注意: constructor 在类继承时会出错
eg,
function A(){};
function B(){};
A.prototype = new B(); //A继承自B
var aObj = new A();
alert(aobj.constructor === B) -----------> true;
alert(aobj.constructor === A) -----------> false;
而instanceof方法不会出现该问题,对象直接继承和间接继承的都会报true:
alert(aobj instanceof B) ----------------> true;
alert(aobj instanceof B) ----------------> true;
言归正传,解决construtor的问题通常是让对象的constructor手动指向自己:
aobj.constructor = A; //将自己的类赋值给对象的constructor属性
alert(aobj.constructor === A) -----------> true;
alert(aobj.constructor === B) -----------> false; //基类不会报true了;
通用但很繁琐的方法: prototype
alert(Object.prototype.toString.call(a) === ‘[object String]’) -------> true;
alert(Object.prototype.toString.call(b) === ‘[object Number]’) -------> true;
alert(Object.prototype.toString.call(c) === ‘[object Array]’) -------> true;
alert(Object.prototype.toString.call(d) === ‘[object Date]’) -------> true;
alert(Object.prototype.toString.call(e) === ‘[object Function]’) -------> true;
alert(Object.prototype.toString.call(f) === ‘[object Function]’) -------> true;
大小写不能写错,比较麻烦,但胜在通用。
通常情况下用typeof 判断就可以了,遇到预知Object类型的情况可以选用instanceof或constructor方法
function fn(){
return fn
}
new fn() instanceof fn //false
function Foo(){}
new Foo() instanceof Foo //true
// 判断 foo 是否是 Foo 类的实例 , 并且是否是其父类型的实例
function Aoo(){}
function Foo(){}
Foo.prototype = new Aoo();//JavaScript 原型继承
var foo = new Foo();
console.log(foo instanceof Foo)//true
console.log(foo instanceof Aoo)//true
4、下面哪个属性不会让div 脱离文档流(c)
A. position:absolute B.position:fixed C.position:relative
D.float:left
5、flexbox 布局
(1)基础
1)创建一个flex容器
要创建一个 flex 容器,您只需要将一个 display: flex 属性添加到一个元素上。默认情况下,所有的直接子元素都被认为是 flex 项,并从左到右依次排列在一行中。如果 flex 项的宽度总和大于容器,那么 flex 项将按比例缩小,直到它们适应 flex 容器宽度。
2)将flex项排成一列
可以通过(在 flex 容器中)设置 flex-direction: column 使 flex 项垂直布局。也可以通过设置 flex-direction: column-reverse 或 flex-direction: row-reverse 来使 flex 项以相反的顺序排列。
(2)新手
1)靠右对齐的flex项
每个 Flexbox 模型都有 flex 方向(主轴)。justify-content 用于指定 flex 项在 flex 方向(direction)上的对齐位置。在上面的例子中,justify-content:flex-end 表示 flex 项在水平方向上靠 flex 容器的末端对齐。这就是为什么他们被放在了右边
.flex-container {
display: flex;
justify-content: flex-end;
}
2)居中对齐flex项
.flex-container {
display: flex;
justify-content: center;
}
6、正则表达式/^d**[^d]*[w]{6}$/,下面的字符串中哪个能正确匹配?(A)
A. ***abcABCD_89 B.abc*abcABCDEF C.123*abcABCD-89 D. 123*ABCabcd-89
7、(function(){var a=b=5})();console.log(b)console.log(a);
上述代码输出结果是(程序抛错)
(function(){
var a=b=5;
console.log(b);
console.log(a)
})()
结果为//5 5
js中连等赋值的执行顺序是 从右向左
8、http 状态码有哪些,分别代表什么意思?
1**(信息类):表示接收到请求并且继续处理
100——客户必须继续发出请求
101——客户要求服务器根据请求转换HTTp协议版本
2** (响应成功):表示动作被成功接收、理解和接受
200——表明该请求被成功地完成,所请求的资源发送回客户端
201——提示知道新文件的URL
202——接受和处理、但处理未完成
203——返回信息不确定或不完整
204——请求收到,但返回信息为空
205——服务器完成了请求,用户代理必须复位当前已经浏览过的文件
206——服务器已经完成部分用户的GET请求
3**(重定向类):为了完成指定的动作,必须接受进一步处理
300——请求的资源可在多处得到
301——本网页被永久性转移到另一个URL
302——请求的网页被转移到一个新的地址,但客户访问仍继续通过原始URL地址,重定向,新的URL会在response中的Location中返回,浏览器将会使用新的URL发出新的Request。
303——建议客户访问其他URL或访问方式
304——自从上次请求后,请求的网页未修改过,服务器返回此响应时,不会返回网页内容,代表上次的文档已经被缓存了,还可以继续使用
305——请求的资源必须从服务器指定的地址得到
306——前一版本HTTP中使用的代码,现行版本中不再使用
307——申明请求的资源临时性删除
4**(客户端错误类):请求包含错误语法或不能正确执行
400——客户端请求有语法错误,不能被服务器所理解
401——请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
HTTP 401.1 - 未授权:登录失败
HTTP 401.2 - 未授权:服务器配置问题导致登录失败
HTTP 401.3 - ACL 禁止访问资源
HTTP 401.4 - 未授权:授权被筛选器拒绝
HTTP 401.5 - 未授权:ISAPI 或 CGI 授权失败
402——保留有效ChargeTo头响应
403——禁止访问,服务器收到请求,但是拒绝提供服务
HTTP 403.1 禁止访问:禁止可执行访问
HTTP 403.2 - 禁止访问:禁止读访问
HTTP 403.3 - 禁止访问:禁止写访问
HTTP 403.4 - 禁止访问:要求 SSL
HTTP 403.5 - 禁止访问:要求 SSL 128
HTTP 403.6 - 禁止访问:IP 地址被拒绝
HTTP 403.7 - 禁止访问:要求客户证书
HTTP 403.8 - 禁止访问:禁止站点访问
HTTP 403.9 - 禁止访问:连接的用户过多
HTTP 403.10 - 禁止访问:配置无效
HTTP 403.11 - 禁止访问:密码更改
HTTP 403.12 - 禁止访问:映射器拒绝访问
HTTP 403.13 - 禁止访问:客户证书已被吊销
HTTP 403.15 - 禁止访问:客户访问许可过多
HTTP 403.16 - 禁止访问:客户证书不可信或者无效
HTTP 403.17 - 禁止访问:客户证书已经到期或者尚未生效
404——一个404错误表明可连接服务器,但服务器无法取得所请求的网页,请求资源不存在。eg:输入了错误的URL
405——用户在Request-Line字段定义的方法不允许
406——根据用户发送的Accept拖,请求资源不可访问
407——类似401,用户必须首先在代理服务器上得到授权
408——客户端没有在用户指定的饿时间内完成请求
409——对当前资源状态,请求不能完成
410——服务器上不再有此资源且无进一步的参考地址
411——服务器拒绝用户定义的Content-Length属性请求
412——一个或多个请求头字段在当前请求中错误
413——请求的资源大于服务器允许的大小
414——请求的资源URL长于服务器允许的长度
415——请求资源不支持请求项目格式
416——请求中包含Range请求头字段,在当前请求资源范围内没有range指示值,请求也不包含If-Range请求头字段
417——服务器不满足请求Expect头字段指定的期望值,如果是代理服务器,可能是下一级服务器不能满足请求长
5**(服务端错误类):服务器不能正确执行一个正确的请求
HTTP 500 - 服务器遇到错误,无法完成请求
HTTP 500.100 - 内部服务器错误 - ASP 错误
HTTP 500-11 服务器关闭
HTTP 500-12 应用程序重新启动
HTTP 500-13 - 服务器太忙
HTTP 500-14 - 应用程序无效
HTTP 500-15 - 不允许请求 global.asa
Error 501 - 未实现
HTTP 502 - 网关错误
HTTP 503:由于超载或停机维护,服务器目前无法使用,一段时间后可能恢复正常
10、PNG、GIF、JPG 的区别即及如何选?
Gif:色彩效果最低,但是体积小,有着几号的压缩效果,支持动画,并且支持透明
的效果(不支持半透明哦),如果图片只是很单调的色彩,没有渐变色,选Gif最好。
JPG:是数码相机最常用的格式,色彩还原好,可以在招聘不明显失真情况下,大福降低体积。
缺点是不支持透明
PNG:是最适合网络的图片!PNG的优点是,清晰,无损压缩,压缩比率很高,
可渐变透明,具备几乎所有GIF的特点,缺点是没有JPG的颜色丰富。同样的
图片体积也比JPG略大,8位的PNG完全可以替代掉GIF。
11、如何判断一个对象是否属于某个类
例子:
class Animal {
constructor(){
this.type = 'animal'
}
says(say){
setTimeout(()=>{
console.log(this.type + ' says ' + say)
}, 1000)
}
}
var animal = new Animal();
判断animal 这个对象是否属于Animal 的方法:
animal instanceof Animal
animal.constructor === Animal
12、请尽可能多的列举浏览器兼容性问题
问题一:不同浏览器,标签默认的外间距和内间距不同
问题症状:随便写几个标签,不加样式控制的情况下,各自的margin 和padding差异较大。
碰到频率:100%
解决方案:CSS里 *{margin:0;padding:0;}
备注:这个是最常见的也是最易解决的一个浏览器兼容性问题,几乎所有的CSS文件开头都会用通配符*来设置各个标签的内外补丁是0。
问题二:行内属性标签,设置display:block后采用float布局,又有横行的margin的情况,IE6间距bug
问题症状:IE6里的间距比超过设置的间距
碰到几率:20%
解决方案:在display:block;后面加入display:inline;display:table;
备注:行内属性标签,为了设置宽高,我们需要设置display:block;(除了input标签比较特殊)。在用float布局并有横向的margin后,在IE6下,他就具有了块属性float后的横向margin的bug。不过因为它本身就是行内属性标签,所以我们再加上display:inline的话,它的高宽就不可设了。这时候我们还需要在display:inline后面加入display:talbe。
问题三:设置较小高度标签(一般小于10px),在IE6,IE7中高度超出自己设置高度
问题症状:IE6、7里这个标签的高度不受控制,超出自己设置的高度
碰到频率:60%
解决方案:给超出高度的标签设置overflow:hidden;或者设置行高line-height 小于你设置的高度。
备注:这种情况一般出现在我们设置小圆角背景的标签里。出现这个问题的原因是IE8之前的浏览器都会给标签一个最小默认的行高的高度。即使你的标签是空的,这个标签的高度还是会达到默认的行高。
问题四:图片默认有间距
问题症状:几个img标签放在一起的时候,有些浏览器会有默认的间距,加了问题一中提到的通配符也不起作用。
碰到几率:20%
解决方案:使用float属性为img布局
备注:因为img标签是行内属性标签,所以只要不超出容器宽度,img标签都会排在一行里,但是部分浏览器的img标签之间会有个间距。去掉这个间距使用float是正道。
13、请用css实现一个100x100的div横向和纵向的居中
.div{
100px;
height: 100px;
border:4px solid red;
position:absolute;
text-align: center;
left:0;
right:0;
top:0;
bottom:0;
margin:auto;
}
14、有一个数组,var a= ['1','2','3'...];a的长度是100,内容填充随机整数的字符串,请
先构造此数组a,然后将其内容去重
const a = new Set();
function random(){
var num = Math.floor(Math.random()*100+1);
return ''+num;
}
for(var i=0;i<100;i++){
a.add(random());
}
console.log(a)
15、编写一个函数,将列表子元素顺序反转
<ul id='list'>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
var ul = $('#list');
var lis = $('li');
console.log(lis);
var arr=[];
for(var i =0;i<lis.length;i++){
arr.push(lis[i].innerText);
}
console.log(arr);
arr = arr.reverse();
console.log(arr);
ul.empty();
for(var i=0;i<arr.length;i++){
ul.append(`<li>${arr[i]}</li>`)
}
16、input的属性为placeholder时,怎样改变placeholder里字体的颜色?
<style>
input::-webkit-input-placeholder{
color:red;
}
input::-moz-placeholder{ /* Mozilla Firefox 19+ */
color:red;
}
input:-moz-placeholder{ /* Mozilla Firefox 4 to 18 */
color:red;
}
input:-ms-input-placeholder{ /* Internet Explorer 10-11 */
color:red;
}
</style>
17、写出下面代码的输出结果
class Junjia{
static fn(){
console.log(this.age+'28');
}
constructor(age){
this.age = age;
this.fn = function(){
console.log(this.age);
}
}
}
let test = new Junjia('28');
test.fn() // 28
Junjia.fn();// undefined28
18、输出一下代码的运行结果
var bar = 0;
var obj = {
bar:1,
foo:function(){
console.log(this.bar);
}
}
var obj2 = {
Bar:2,
foo:obj.foo
}
var obj3 = {
bar:3,
foo:function(){
return obj.foo
}
}
var tempFoo = obj2.foo;
obj.foo(); //1
obj2.foo(); //undefined
obj3.foo() //function(){console.log(this.bar)}
tempFoo(); // 0
19、图片懒加载原理
1) 什么是图片懒加载
就是当访问一个页面的时候,先把img元素或其他元素的背景图片路径替换成一张大小为1*1px图片的路径(这样就只需请求一次),只有
当图片出现在浏览器的可是区域内时,才设置图片真正的路径,让图片显示出来。这就是图片懒加载
2)为什么使用图片懒加载
比如一个页面中有很多图片,如淘宝、京东首页等,如果一上来就发送那么多请求,页面加载就会很漫长,更要命的是一上来就发送百八十个请求,服务可能就吃不消了(因为不是一两个人在访问这个页面),因此图片懒加载不仅可以减轻服务器压力,而且可以让加载好的页面更快的呈现在用户面前(用户体验好)