一、HTML
1. 针对移动浏览器端开发页面,不期望用户放大屏幕,且要求“视口(viewport)”宽度等于屏幕宽度,视口高度等于设备高度,如何设置?
移动web前端viewport详解
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1, maximum-scale=1, user-scalable=no">
2.data-xxx 属性的作用是什么?
HTML5 data-* 属性:
定义和用法
data-* 属性用于存储页面或应用程序的私有自定义数据。
data-* 属性赋予我们在所有 HTML 元素上嵌入自定义 data 属性的能力。
存储的(自定义)数据能够被页面的 JavaScript 中利用,以创建更好的用户体验(不进行 Ajax 调用或服务器端数据库查询)。
data-* 属性包括两部分:
属性名不应该包含任何大写字母,并且在前缀 "data-" 之后必须有至少一个字符
属性值可以是任意字符串
注释:用户代理会完全忽略前缀为 "data-" 的自定义属性。
这里的data-前缀就被称为data属性,其可以通过脚本进行定义,也可以应用CSS属性选择器进行样式设置。数量不受限制,在控制和渲染数据的时候提供了非常强大的控制。
html:
<div class="mm" data-name="张含韵"></div>
<div class="mm" data-name="undefined"></div>
css:
.mm{width:256px; height:200px;}
.mm[data-name='张含韵']{background:url(http://image.zhangxinxu.com/image/study/s/s256/mm1.jpg) no-repeat;}
.mm[data-name='undefined']{background:url(http://image.zhangxinxu.com/image/study/s/s256/mm3.jpg) no-repeat;}
js:
expense = document.getElementById('day2-meal-expense').dataset;
3.请描述一下cookies,sessionStorage和localStorage的区别?
之前总结过:http://www.jianshu.com/p/da227e50df43
HTTP cookies 详解
微软的 IE6 SP1 在 cookie 中引入了一个新的选项:HTTP-only,HTTP-Only背后的意思是告之浏览器该 cookie 绝不能通过 JavaScript 的 document.cookie属性访问。设计该特征意在提供一个安全措施来帮助阻止通过 JavaScript 发起的跨站脚本攻击 (XSS) 窃取 cookie 的行为
4.什么是浏览器的标准模式(standards mode)和怪异模式(quirks mode)
目前浏览器的排版引擎有三种模式:怪异模式(Quirks mode)、接近标准模式(Almost standards mode)、以及标准模式(Standards mode)。在怪异模式下,排版会模拟 Navigator 4 与 Internet Explorer 5 的非标准行为。为了支持在网络标准被广泛采用前,就已经建好的网站,这么做是必要的。在标准模式下,行为即(但愿如此)由 HTML 与 CSS 的规范描述的行为。在接近标准模式下,只有少数的怪异行为被实现。
那么所谓标准模式,就一定都“标准”吗?答案当然是否定的,因为各个浏览器厂商实现标准的阶段不同,所以各个浏览器的“标准模式”之间也会有很大的不同。
Firefox、Safari、Chrome、Opera (自 7.5 以后)、 IE8 和 IE9 都有一个准标准模式。那么既然标准模式都不那么标准,准标准的模式肯定就更不标准了。
-
浏览器如何决定用哪个模式?
对HTML文件来说,浏览器使用文件开头的 DOCTYPE 来决定用怪异模式处理或标准模式处理。为了确保你的页面使用标准模式,请确认你的页面如同本范例一样拥有 DOCTYPE:
<!DOCTYPE html>
<html>
<head>
<meta charset=UTF-8>
<title>Hello World!</title>
</head>
<body>
</body>
</html>
范例中的DOCTYPE,<!DOCTYPE html>,是所有可用的DOCTYPE之中最简单的,而且是HTML5 所推荐的。HTML的早期变种也属于推荐标准,不过今日的浏览器都会对这个 DOCTYPE 使用标准模式,就算是已过时的 Internet Explorer 6 也一样。目前并没有正当的理由,去使用其他更复杂的 DOCTYPE。如果你使用其他的 DOCTYPE,你可能会冒着触发接近标准模式或者怪异模式的风险。
- 使用
请确定你把 DOCTYPE 正确地放在 HTML 文件的顶端。任何放在 DOCTYPE 前面的东西,比如批注或 XML 声明,会令 Internet Explorer 9 或更早期的浏览器触发怪异模式。
在 HTML5中,DOCTYPE 唯一的作用是启用标准模式。更早期的 HTML 标准会附加其他意义,但没有任何浏览器会将 DOCTYPE 用于怪异模式和标准模式之间互换以外的用途。
由于历史的原因,各个浏览器在对页面的渲染上存在差异,甚至同一浏览器在不同版本中,对页面的渲染也不同。在W3C标准出台以前,浏览器在对页面的渲染上没有统一规范,产生了差异(Quirks mode或者称为Compatibility Mode);由于W3C标准的推出,浏览器渲染页面有了统一的标准(CSScompat或称为Strict mode也有叫做Standars mode),这就是二者最简单的区别。W3C标准推出以后,浏览器都开始采纳新标准,但存在一个问题就是如何保证旧的网页还能继续浏览,在标准出来以前,很多页面都是根据旧的渲染方法编写的,如果用的标准来渲染,将导致页面显示异常。为保持浏览器渲染的兼容性,使以前的页面能够正常浏览,浏览器都保留了旧的渲染方法(如:微软的IE)。这样浏览器渲染上就产生了Quircks mode和Standars mode,两种渲染方法共存在一个浏览器上。
火狐一直工作在标准模式下,但IE(6,7,8)标准模式与怪异模式差别很大,主要体现在对盒子模型的解释上,这个很重要,下面就重点说这个。那么浏览器究竟该采用哪种模式渲染呢?这就引出的DTD,既是网页的头部声明,浏览器会通过识别DTD而采用相对应的渲染模式:
- 浏览器要使老旧的网页正常工作,但这部分网页是没有doctype声明的,所以浏览器对没有doctype声明的网页采用quirks mode解析。
- 对于拥有doctype声明的网页,什么浏览器采用何种模式解析,这里有一张详细列表可参考:http://hsivonen.iki.fi/doctype。
- 对于拥有doctype声明的网页,这里有几条简单的规则可用于判断:对于那些浏览器不能识别的doctype声明,浏览器采用strict mode解析。
- 在doctype声明中,没有使用DTD声明或者使用HTML4以下(不包括HTML4)的DTD声明时,基本所有的浏览器都是使用quirks mode呈现,其他的则使用strict mode解析。
- 可以这么说,在现有有doctype声明的网页,绝大多数是采用strict mode进行解析的。
- 在ie6中,如果在doctype声明前有一个xml声明(比如:
<?xml version=”1.0″ encoding=”iso-8859-1″?>
),则采用quirks mode解析。这条规则在ie7中已经移除了。
如何判定现在是标准模式还是怪异模式:
方法一:执行以下代码
alert(window.top.document.compatMode) ;
//BackCompat 表示怪异模式
//CSS1Compat 表示标准模式
方法二:jquery为我们提供的方法,如下:
alert($.boxModel)
alert($.support.boxModel)
CSS
1. 解释一下盒模型宽高值的计算方式,边界塌陷,负值作用,box-sizing概念。
1.1 盒模型
a. ie678怪异模式(不添加 doctype)使用 ie 盒模型,宽度=边框+padding+内容宽度
b. chrome, ie9+, ie678(添加 doctype) 使用标准盒模型,宽度= 内容宽度
1.2 box-sizing
content-box(默认)
布局所占宽度Width:
Width = width + padding-left + padding-right + border-left + border-right
布局所占高度Height:
Height = height + padding-top + padding-bottom + border-top + border-bottom
border-box
布局所占宽度Width:
Width = width(包含padding-left + padding-right + border-left + border-right)
布局所占高度Height:
Height = height(包含padding-top + padding-bottom + border-top + border-bottom)
1.3 边界塌陷
之前总结的
1.4 负值作用
display:inline-block是什么呢?相信大家对这个属性并不陌生,根据名字inline-block我们就可以大概猜出它是结合了inline和block两者的特性于一身,简单的说:设置了inline-block属性的元素既拥有了block元素可以设置width和height的特性,又保持了inline元素不换行的特性。
在margin属性中一共有两类参考线,top和left的参考线属于一类,right和bottom的参考线属于另一类。top和left是以外元素为参考,right和bottom是以元素本身为参考。
厉害了我的margin_由浅入深漫谈margin属性
margin:-10px 20px -30px 40px;
这时候 margin 的解析逻辑是怎样的呢?首先我们要搞清 div 的和周边元素的关系,div 没有相连元素,而此时 div 的 containing block 是 body 产生的 block box。则根据上面介绍的参考线原理,div 的左外边距以 containing block 的 content 左边为参考线,及此时以 body 的 content 左边为参考线进行水平向右位移,位移的大小为 40px,同理,上边距以 body 的 content 上边为参考线进行垂直向上位移 10px(负值和正值的方向相反),下边距依照现在 div 的 borer 下边(此时的 div 已经经过上边距位移过了)垂直向上位移 30px(此时,margin 不会改变 box 的 border 内的物理大小,但会改变 box 的逻辑大小,即:以此 box 的 margin 的下边为参考的元素,不是从 box 的物理位置开始的,而是从逻辑位置开始),右边距依照现在 div 的 borer 右边(此时的 div 已经经过左边距位移过了)水平向右位移 20px。或许有朋友问你分析的顺序怎么和 margin 表达式中出现的顺序不一样?如果按照 margin 表达式中出现的顺序来分析,结果是一样的,只是为了更好的方便大家的理解而没有按照表达式的顺序来分析。
应用
- 左右固定,中间自适应(双飞翼)那些年,奇妙的圣杯与双飞翼,还有负边距
<div class="main">
<div class="main-content">main content</div>
</div>
<div class="left">left</div>
<div class="right">right</div>
*{ margin:0; padding: 0 }
.main{ float: left; width: 100%; }
.main .main-content{
margin: 0 210px;
background-color: rgba(33, 114, 214, 0.8);
height: 500px
}
.left{
width: 200px;
float: left;
background-color:
rgba(255, 82, 0, 0.8);
margin-left: -100%;
height: 200px
}
.right{
width: 200px;
height: 200px;
margin-left: -200px;
float: left;
background-color: rgba(90, 243, 151, 0.8);
}
- 负边距+定位:水平垂直居中
还有其他。。
[margin,padding]任一方向的百分数都是相对于包含块的宽度(width)的。
一般left和right(用于absolute/fixed)在一个样式是只能使用其一,不能left和right都设置,要么使用left就不使用right,要么使用right就不使用left,如果left和right均使用将会出现兼容问题,一个对象设置了靠左left多少距离,自然右边距离自然就有了所以无需设置左边。
相同道理,top和bottom对一个对象只能使用其一,不然会出现逻辑兼容问题。譬如一个人让你往左走,一个人让你往右走,同时发出往左往右走这个时候你也不好判断往那边走。
2. BFC(Block Formatting Context)是什么?有哪些应用?
Block Formatting Context,中文直译为块级格式上下文。BFC就是一种布局方式,在这种布局方式下,盒子们自所在的containing block顶部一个接一个垂直排列,水平方向上撑满整个宽度(除非内部盒子自己建立了新的BFC)。两个相邻的BFC之间的距离由margin决定。在同一个BFC内部,两个垂直方向相邻的块级元素的margin会发生“塌陷”。
文档这里也间接指出了垂直相邻盒子margin合并的解决办法:就是给这两个盒子也创建BFC。
通俗一点,可以把BFC理解为一个封闭的大箱子,箱子内部的元素无论如何翻江倒海,都不会影响到外部。
- 如何创建BFC
总结一下就是:
float属性不为none
overflow不为visible(可以是hidden、scroll、auto)
position为absolute或fixed
display为inline-block、table-cell、table-caption
- BFC的作用
1. 清除内部浮动我们在布局时经常会遇到这个问题:对子元素设置浮动后,父元素会发生高度塌陷,也就是父元素的高度变为0。解决这个问题,只需要把把父元素变成一个BFC就行了。常用的办法是给父元素设置overflow:hidden。
2. 垂直margin合并在CSS当中,相邻的两个盒子的外边距可以结合成一个单独的外边距。这种合并外边距的方式被称为折叠,并且因而所结合成的外边距称为折叠外边距。折叠的结果:
两个相邻的外边距都是正数时,折叠结果是它们两者之间较大的值。
两个相邻的外边距都是负数时,折叠结果是两者绝对值的较大值。
两个外边距一正一负时,折叠结果是两者的相加的和。这个同样可以利用BFC解决。关于原理在前文已经讲过了。
3. 创建自适应两栏布局在很多网站中,我们常看到这样的一种结构,左图片+右文字的两栏结构。
显然,这是文字受到了图片浮动的影响。当然,如果你想做文本绕排的效果,浮动是不二之选。不过在这里,这显然不是我们想要的。此时我们可以为P元素的内容建立一个BFC,让其内容消除对外界浮动元素的影响。给文字加上overflow:hidden
3.如何要求容器在宽度自由很缩的情况下,A/B/C的宽度始终是1:1:1,如何实现,写出两种方法。
flex布局:
.div1 {
width: 100%;
height: 400px;
border: 1px solid #888;
flex-direction: row;
/**主要代码*/
display: flex;
/* align-items: center; */
/* justify-content: center; */
}
.div {
/* position:absolute; */
/* width:500px; */
flex-grow: 1;
border: 1px solid #888;
}
百分数布局:inline-block元素间间隙产生及去除详解:
<div class="div1">
<div class="div2 div">
div2
</div><div class="div3 div">
div3
</div><div class="div4 div">
div4
</div>
</div>
.div1 {
width: 100%;
height: 400px;
background-color: red;
}
.div2{
margin-left: 5%;
}
.div {
width:30%;
display:inline-block;
background-color:#888;
}
4.
如图,A若宽高已知,如何实现水平、垂直均相对于父元素居中?若A高度未知呢?
之前总结的
JavaScript
1. 函数中的arguments是什么?是数组吗?若不是,如何将它转化为真正的数组?
arguments不是真正的数组。没有数组的方法
function a(){
console.log(arguments);
var args = Array.prototype.slice.call(arguments);
console.log(args);
/* arguments.forEach(function(){
}) */
}
a(1,2,3)
2. 列举JavaScript中typeof操作符的可能结果,如何区分:{}和[]类型?
3. Function中的call、apply、bind的区别是什么?请针对每一个写出一个代码示例。
4. 使用jQuery,找到id位selector的select标签中有用data-target属性为isme的option的值?
var se = $("#selector option[data-target=isme]");
console.log(se.val());
5. 优化代码
for(var i = 0; i < document.getElementsByTagName('a').length; i++) {
document.getElementsByTagName('a')[i].onmouseover = function(){
this.style.color = 'red';
};
document.getElementsByTagName('a')[i].onmouseout = function(){
this.style.color = '';
};
5.1 CSS
回流与重绘:CSS性能让JavaScript变慢?
翻译计划-重绘重排重渲染
通过类修改样式
有时候我们需要通过JavaScript给元素增加样式,比如如下代码:
element.style.fontWeight = 'bold';
element.style.backgroundImage = 'url(back.gif)';
element.style.backgroundColor = 'white';element.style.color = 'white';//...
这样效率很低,每次修改style属性后都会触发元素的重绘,如果修改了的属性涉及大小和位置,将会导致回流。所以我们应当尽量避免多次为一个元素设置style属性,应当通过给其添加新的CSS类,来修改其CSS
当一个元素的外观的可见性visibility发生改变的时候,重绘(repaint)也随之发生,但是不影响布局。类似的例子包括:outline, visibility, or background color。根据Opera浏览器,重绘的代价是高昂的,因为浏览器必须验证DOM树上其他节点元素的可见性。而回流更是性能的关键因为其变化涉及到部分页面(或是整个页面)的布局。一个元素的回流导致了其所有子元素以及DOM中紧随其后的祖先元素的随后的回流。
如何避免回流或将它们对性能的影响降到最低?
- 如果想设定元素的样式,通过改变元素的 class 名 (尽可能在 DOM 树的最末端)(Change classes on the element you wish to style (as low in the dom tree as possible))
- 避免设置多项内联样式(Avoid setting multiple inline styles)
- 应用元素的动画,使用 position 属性的 fixed 值或 absolute 值(Apply animations to elements that are position fixed or absolute)
- 权衡平滑和速度(Trade smoothness for speed)
- 避免使用table布局(Avoid tables for layout)
- 避免使用CSS的JavaScript表达式 (仅 IE 浏览器)(Avoid JavaScript expressions in the CSS (IE only))
结合着看
- “离线”的批量改变和表现DOM。“离线”意味着不在当前的DOM树中做修改。你可以:通过documentFragment来保留临时变动。
- 复制你即将更新的节点,在副本上工作,然后将之前的节点和新节点交换。
- 通过display:none属性隐藏元素(只有一次重排重绘),添加足够多的变更后,通过display属性显示(另一次重排重绘)。通过这种方式即使大量变更也只触发两次重排。
- 不要频繁计算样式。如果你有一个样式需要计算,只取一次,将它缓存在一个变量中并且在这个变量上工作。
- 通常情况下,考虑一下渲染树和变更后需要重新验证的消耗。举个例子,使用绝对定位会使得该元素单独成为渲染树中body的一个子元素,所以当你对其添加动画时,它不会对其它节点造成太多影响。当你在这些节点上放置这个元素时,一些其它在这个区域内的节点可能需要重绘,但是不需要重排。
5.2 事件绑定
当使用 addEventListener()为一个元素注册事件的时候,句柄里的 this 值是该元素的引用。其与传递给句柄的 event 参数的 currentTarget 属性的值一样。
document.addEventListener("mouseover", function(e){
var target = e.target;
if(target.nodeName.toLowerCase() === 'a'){
target.style.color = 'red';
}
}, false)
document.addEventListener("mouseout", function(e){
var target = e.target;
if(target.nodeName.toLowerCase() === 'a'){
target.style.color = '';
}
}, false)
6. 请设计一个算法。将两个有序数组合并为一个数组。请不要使用concat以及sort方法。
Javascript排序算法之合并排序(归并排序)的2个例子
function merge(left, right) {
var result = [],
il = 0,
ir = 0;
while (il < left.length && ir < right.length) {
if (left[il] < right[ir]) {
result.push(left[il++]);
} else {
result.push(right[ir++]);
}
}
result.push(left[il] ? left[il] : right[ir]);
return result;
}
var left = [1, 4, 7];
var right = [2, 5];
console.log(merge(left, right))
这个方法有个缺陷,left更大的时候,后面的元素没了
改下:
function merge(left, right) {
var result = [],
il = 0,
ir = 0;
while (il < left.length && ir < right.length) {
if (left[il] < right[ir]) {
result.push(left[il++]);
} else {
result.push(right[ir++]);
}
}
//这里注意
result = result.concat(left[il] ? left.slice(il) : right.slice(ir));
return result;
}
var left = [1, 4, 7, 8, 9, 10];
var right = [2, 5];
console.log(merge(left, right))