Fork me on GitHub

我使用过的面试题

技术基础

HTML

doctype的作用

告知浏览器的解析器用什么文档标准解析这个文档。DOCTYPE不存在或格式不正确会导致文档以兼容模式呈现。

HTML5 为什么只需要写 <!DOCTYPE HTML>?

HTML5 不基于 SGML,因此不需要对DTD进行引用,但是需要doctype来规范浏览器的行为(让浏览器按照它们应该的方式来运行);
而HTML4.01基于SGML,所以需要对DTD进行引用,才能告知浏览器文档所使用的文档类型。

data-属性的作用和相关的API操作

HTML 5 增加了一项新功能是 自定义数据属性 ,也就是 data-* 自定义属性。
在HTML5中我们可以使用以 data- 为前缀来设置我们需要的自定义属性,来进行一些数据的存放。
data数据都属于页面私有,不会被搜索引擎等外部系统引用。
相关的API

1
2
3
4
5
6
7
8
9
10
11
12
<div id="user" data-id="001" data-uname="fanerge" data-date-of-birth="1991-10-15"> </div>
<script>
let dom = document.querySelector('#user')
// 老的访问方式
dom.getAttribute('data-uname') // fanerge
dom.setAttribute('data-uname', '余真帆') // 余真帆
// HTML5 提供的访问方法(存在一定的兼容性)
dom.dataset // 一个DOMStringMap
dom.dataset.id // 001
dom.dataset.dateOfBirth // 1991-10-15
</script>

扩展,data-属性选择器

1
2
3
4
5
6
7
// css
.user[data-name='fanerge'] {
color: brown;
}
// js
document.querySelectorAll('[data-text-colour="red"]')

defer和async属性

defer和async是script标签的两个属性,用于在不阻塞页面文档解析的前提下,控制脚本的下载和执行。
defer (延迟脚本)
相当于告诉浏览器立即下载,但延迟执行(整个页面都解析完毕)。
async(异步脚本)
指定async属性的目的是不让页面等待脚本下载和执行,从而异步加载页面其他内容(css、图片、font等)。
需要注意,异步脚本不要在加载期间修改DOM。

事件DOMContentLoaded和load的区别

它们触发的时机不一样,先触发DOMContentLoaded事件,后触发load事件。
DOM文档加载的步骤为

1.    解析HTML结构。
2.    加载样式表文件和外部脚本。
3.    解析并执行脚本代码。
4.    DOM树构建完成。//DOMContentLoaded(这里也是jquery的ready方法绑定的时机)
5.    加载图片等外部文件。
6.    页面加载完毕。//load

HTML5

localStorage

  1. 与Cookie的比较
    来看MDN定义:
    sessionStorage 为每一个给定的源(given origin)维持一个独立的存储区域,该存储区域在页面会话期间可用(即只要浏览器处于打开状态,包括页面重新加载和恢复)。
    localStorage 同样的功能,但是在浏览器关闭,然后重新打开后数据仍然存在。
    Cookie 是一个请求首部,其中含有先前由服务器通过 Set-Cookie 首部投放并存储到客户端的 HTTP cookies。
    共同点:都是保存在浏览器端、且同源的
    区别点:
    1.cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递,而sessionStorage和localStorage不会自动把数据发送给服务器,仅在本地保存。cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下
    2.存储大小限制也不同,cookie数据不能超过4K,同时因为每次http请求都会携带cookie、所以cookie只适合保存很小的数据,如会话标识。sessionStorage和localStorage虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大
    3.数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭之前有效;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie:只在设置的cookie过期时间之前有效,即使窗口关闭或浏览器关闭
    4.作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localstorage在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的
    5.web Storage提供了良好的api如length、key、setItem、getItem、removeItem、clear等方法
    个人认为产生这些客户端存储的目的是由于 http协议 是无状态,客户端帮助存储客户的操作,发送给服务端以便服务端做出相应的判断。
    cookie语法:

    1
    2
    3
    4
    5
    6
    document.cookie="name=value; domain=cookieDomain; path=/; ";
    ;path=path (例如 '/', '/mydir') 如果没有定义,默认为当前文档位置的路径。
    ;domain=domain (例如 'example.com', '.example.com' (包括所有子域名), 'subdomain.example.com') 如果没有定义,默认为当前文档位置的路径的域名部分。
    ;max-age=max-age-in-seconds (例如一年为60*60*24*365)
    ;expires=date-in-GMTString-format 如果没有定义,cookie会在对话结束时过期这个值的格式参见Date.toUTCString()
    ;secure (cookie只通过https协议传输) cookie的值字符串可以用encodeURIComponent()来保证它不包含任何逗号、分号或空格(cookie值中禁止使用这些值).

    cookie的路径:(路径能解决在同一个域下访问 cookie 的问题)
    出于安全方面的考虑,只有与创建 cookie 的页面处于同一个目录或在创建cookie页面的子目录下的网页才可以访问。那么此时如果希望其父级或者整个网页都能够使用cookie,就需要进行路径的设置。
    让这个设置的cookie 能被其他目录或者父级的目录访问的方法:
    document.cookie = “userName = 独行冰海; path=/“;
    cookie的域:(域能解决同一个主域下的访问问题)
    让 “www.baidu.com” 下的cookie被 “mp3.baidu.com” 访问,我们就需要用到 cookie 的domain属性,并且需要把path属性设置为 “/“
    document.cookie = “username=独行冰海; path=/; domain=baidu.com”

  2. 扩展-缓存相关的知识
    http头部缓存相关key
    request header缓存相关

    1.cache-control:no-cache、no-store、max-age
    2.if-none-match:该字段与响应中的eTag一起使用,表示检查实体是否有更新改变
    3.if-modified-since: 该字段与last-modified配合使用
    

    response header缓存相关:

    1.Etag:
    2.expires:
    3.last-modified:
    
  3. 应用场景
    首次注册用户的引导等

  4. 在什么情况是失效
    1.浏览器清除缓存
    2.5M大小的限制
    3.IOS safari 的隐私模式(主要我查MDN上有说明,其他浏览器隐私模式会新建 Storage对象,不会与普通模式公用,且关闭隐私模式时 Storage对象 就消失)

  5. 浏览器内多个标签页之间的通信
    1.localstorge + storage 事件
    页面1:localStorage.setItem(“name”, ‘测试’);
    页面2: window.addEventListener(‘stroge’, (e)=> { console.log(${e.key} = ${e.newValue}) }, false)
    2.cookie + setInterval(类似于轮询)

Canvas

History API

History.length
History.scrollRestoration (实验性)-- 允许Web应用程序在历史导航上显式地设置默认滚动恢复行为。
History.state 返回一个表示历史堆栈顶部的状态的值。这是一种可以不必等待popstate 事件而查看状态而的方式。

History.back()
History.forward()
History.go()
History.pushState()
History.replaceState()

postMessage

通常,对于两个不同页面的脚本,只有当执行它们的页面位于具有相同的协议(通常为https),端口号(443为https的默认值),以及主机 (两个页面的模数 Document.domain设置为相同的值) 时,这两个脚本才能相互通信。
作用:解决上面问题,window.postMessage() 方法可以安全地实现跨源通信。
语法:otherWindow.postMessage(message, targetOrigin, [transfer]);
参数:otherWindow
其他窗口的一个引用,比如iframe的contentWindow属性、执行window.open返回的窗口对象、或者是命名过或数值索引的window.frames。
message
将要发送到其他 window的数据。它将会被结构化克隆算法序列化。这意味着你可以不受什么限制的将数据对象安全的传送给目标窗口而无需自己序列化。
targetOrigin(安全性从这里入手)
通过窗口的origin属性来指定哪些窗口能接收到消息事件,其值可以是字符串”*“(表示无限制)或者一个URI。在发送消息的时候,如果目标窗口的协议、主机地址或端口这三者的任意一项不匹配targetOrigin提供的值,那么消息就不会被发送;只有三者完全匹配,消息才会被发送。这个机制用来控制消息可以发送到哪些窗口;例如,当用postMessage传送密码时,这个参数就显得尤为重要,必须保证它的值与这条包含密码的信息的预期接受者的orign属性完全一致,来防止密码被恶意的第三方截获。如果你明确的知道消息应该发送到哪个窗口,那么请始终提供一个有确切值的targetOrigin,而不是*。不提供确切的目标将导致数据泄露到任何对数据感兴趣的恶意站点。
transfer 可选
是一串和message 同时传递的 Transferable 对象. 这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权。
其他window监听message事件

1
2
3
4
5
6
7
8
9
10
11
window.addEventListener("message", receiveMessage, false);
function receiveMessage(event){
// For Chrome, the origin property is in the event.originalEvent
// object.
var origin = event.origin || event.originalEvent.origin;
if (origin !== "http://example.org:8080")
return;
// todo...
}

PS:message 的属性有:
data
从其他 window 中传递过来的对象。
origin
调用 postMessage 时消息发送方窗口的 origin . 这个字符串由 协议、“://“、域名、“ : 端口号”拼接而成。例如 “https://example.org (implying port 443)”、“http://example.net (implying port 80)”、“http://example.com:8080”。请注意,这个origin不能保证是该窗口的当前或未来origin,因为postMessage被调用后可能被导航到不同的位置。
source
对发送消息的窗口对象的引用; 您可以使用此来在具有不同origin的两个窗口之间建立双向通信。

关注下安全性问题
1.如果您不希望从其他网站接收message,请不要为message事件添加任何事件侦听器。
2.请始终使用origin和source属性验证发件人的身份,还应该始终验证接收到data的消息的语法。
3.当您使用postMessage将数据发送到其他窗口时,始终指定精确的目标origin,而不是*。
详细需了解-MDN

WebSocket对象

作用:
提供了用于创建和管理 WebSocket 连接,以及可以通过该连接发送和接收数据的 API。
WebSocket构造器方法接受一个必须的参数和一个可选的参数:
语法:
WebSocket WebSocket(in DOMString url,in optional DOMString[] protocols);
具体参数:
url – 表示要连接的URL。这个URL应该为响应WebSocket的地址。
protocols 可选 – 可以是一个单个的协议名字字符串或者包含多个协议名字字符串的数组。这些字符串用来表示子协议,这样做可以让一个服务器实现多种WebSocket子协议(例如你可能希望通过制定不同的协议来处理不同类型的交互)。如果没有制定这个参数,它会默认设为一个空字符串。
属性:
binaryType、onclose、onerror、onmessage、onopen(EventListener)
方法:
void send(in DOMString data);
void close(in optional unsigned long code, in optional DOMString reason);
构造器方法可能抛出以下异常:
SECURITY_ERR – 试图连接的端口被屏蔽。
示例:

1
2
3
4
5
6
7
8
9
10
11
12
// Create WebSocket connection.
const socket = new WebSocket('ws://localhost:8080');
// Connection opened
socket.addEventListener('open', function (event) {
socket.send('Hello Server!');
});
// Listen for messages
socket.addEventListener('message', function (event) {
console.log('Message from server', event.data);
});

MDN-WebSocket

扩展(Ajax轮询)这是比较原始的方案
定义:轮询(polling):客户端按规定时间定时向服务端发送ajax请求,服务器接到请求后马上返回响应信息并关闭连接。

1
window.setInterval(function(){$.ajax(getting)},1000);

长轮询(递归)
    
1
2
3
4
5
6
7
8
9
10
11
12
13
var getting = {
url:'server.php',
dataType:'json',
success:function(res) {
// todo...
$.ajax(getting); //关键在这里,回调函数内再次请求Ajax
}
error:function(res){
$.ajax(getting);
}
};
$.ajax(getting); // 这里第一次调用ajax

CMD和AMD以及UMD,UMD的实现

AMD(浏览器环境)– RequireJS
CMD(Node) – CommonJS
UMD: 通用模块规范(兼容低版本浏览器设置在window上的属性如window.$ – 代表jquery)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// 自己封装一个符合UMD的功能函数库取名 fanerge
(function (window, factory) {
if (typeof exports === 'object') {
// UMD先判断是否支持Node.js的模块(exports)是否存在,存在则使用Node.js模块模式。
module.exports = factory();
} else if (typeof define === 'function' && define.amd) {
// 再判断是否支持AMD(define是否存在),存在则使用AMD方式加载模块。
define(factory);
} else {
// 否则就绑定到全局的一个属性上,这里绑定到window对象的fanerge属性上
window.fanerge = factory();
}
})(this, function () {
let fanerge = {};
fanerge.alert = function alert() {
alert('fanerge');
}
fanerge.log = function log() {
console.log('fanerge');
}
return fanerge;
});
// 使用时
fanerge.log()

Web Worker

分类:专用worker(一个专用worker仅仅能被生成它的脚本所使用)、共享worker
作用:Web Worker为Web内容在后台线程中运行脚本提供了一种简单的方法。线程可以执行任务而不干扰用户界面。
限制:在worker内直接操作DOM节点,或者使用window对象的默认方法和属性。
主线程与worker数据传递:workers和主线程间的数据传递通过这样的消息机制进行——双方都使用postMessage()方法发送各自的消息,使用onmessage事件处理函数来响应消息(消息被包含在Message事件的data属性中)。这个过程中数据并不是被共享而是被复制。
终止worker:
在主线程中终止:workerName.terminate(); worker 线程会被立即杀死,不会有任何机会让它完成自己的操作或清理工作。
在worker中终止:close();
处理错误:onerror 事件处理函数会被调用,对应的参数,message – 可读性良好的错误消息;filename – 发生错误的脚本文件名;lineno – 发生错误时所在脚本文件的行号。
生成subworker: 在worker 中能够生成 worker。这就是所谓的subworker,它们必须托管在同源的父页面内。
引入脚本与库:Worker 线程能够访问一个全局函数importScripts()来引入脚本,该函数接受0个或者多个URI作为参数来引入资源;
共享worker与专有worker的区别:
1.创建worker
var myWorker = new Worker(‘worker.js’); // 专有
var myWorker = new SharedWorker(‘worker.js’); // 共享
2.通信(发送消息和接收消息都需要携带port)
父级线程和worker线程需要双向通信,那么它们都需要调用start()方法。
myWorker.port.start(); // 父级线程中的调用
port.start(); // worker线程中的调用, 假设port变量代表一个端口
共享worker中消息的接收和发送
消息可以像之前那样发送到worker了,但是postMessage() 方法必须被端口对象调用。
详情参考MDN-web Worker

File API

1、File- 单个文件;提供了诸如file name、file size、mimetype等只读文件属性。
2、FileList- 一个类数组File对象集合;
构造函数
File() 返回一个新构建的文件对象(File)。
属性
File.lastModified – 返回当前 File 对象所引用文件最后修改时间, 自 1970年1月1日0:00 以来的毫秒数。
File.name – 返回当前 File 对象所引用文件的名字。
File.size – 返回文件的大小。
File.type – 返回文件的 多用途互联网邮件扩展类型。
获取用户选择文件的方式
来自用户在一个input元素上选择文件后返回的FileList对象。
e.target.files; //FileList
来自拖放操作生成的 DataTransfer对象。
e.dataTransfer.files; //FileList
来自在一个HTMLCanvasElement上执行mozGetAsFile()方法后返回结果。

FileReader API

FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。
构造函数
FileReader() – 返回一个新构造的FileReader。
属性:
error DOMError 在读取文件时发生的错误. 只读.
readyState unsigned short 表明FileReader对象的当前状态. 值为State constants中的一个. 只读
result jsval 读取到的文件内容.这个属性只在读取操作完成之后才有效,并且数据的格式取决于读取操作是由哪个方法发起的. 只读.
方法:
void abort();
void readAsArrayBuffer(in Blob blob);
void readAsBinaryString(in Blob blob);
void readAsDataURL(in Blob blob);
void readAsText(in Blob blob, [optional] in DOMString encoding);
事件处理程序:
onabort – 当读取操作被中止时调用.
onerror – 当读取操作发生错误时调用.
onload – 当读取操作成功完成时调用.
onloadend – 当读取操作完成时调用,不管是成功还是失败.该处理程序在onload或者onerror之后调用.
onloadstart – 当读取操作将要开始之前调用.
onprogress – 在读取数据过程中周期性调用.
示例(本地文件预览)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
let oFReader = new FileReader(), // 新建一个 FileReader实例
rFilter = /^(?:image\/bmp|image\/)$/i; // 可以读取的文件格式
// 文件异步读取完成时,将设置预览组件的 src 属性
oFReader.onload = function (oFREvent) {
document.getElementById("uploadPreview").src = oFREvent.target.result;
};
// 加载用户选择的图片
function loadImageFile() {
// 没有选择文件
if (document.getElementById("uploadImage").files.length === 0) { return; }
var oFile = document.getElementById("uploadImage").files[0];
// 文件的 MIMETYPE 不满足当前正则
if (!rFilter.test(oFile.type)) { return; }
// 读取文件
oFReader.readAsDataURL(oFile);
}
loadImageFile()

CSS

盒子模型

块级元素和行内元素的区别

CSS sprites

line-height 和 vertical-align

line-height的值由font-size和字体类型共同决定。
vertical-align的值
vertical-align: top / bottom,表示与 line-box 的顶部或底部对齐
vertical-align: text-top / text-bottom,表示与 content-area 的顶部或底部对齐

z-index

需要配合脱离文档流的属性使用,position: relative, absolute, fixed。

栅格系统

以Bootstrap3为例(12栅格系统)
采用float + width(百分比) + @media(媒体查询实现适配)
以Bootstrap4为例
采用容器flex布局(容器6个属性,子项目6个属性)

Media Query

语法:
1.link元素中的CSS媒体查询
<link rel="stylesheet" media="(max-width: 800px)" href="example.css" />
2.样式表中的CSS媒体查询
@media (max-width: 600px) { … }
逻辑操作符:
all(默认)
not – not 关键字应用于整个媒体查询,在媒体查询为假时返回真 (比如 monochrome 应用于彩色显示设备上或一个600像素的屏幕应用于 min-width: 700px 属性查询上 )。
and – and关键字用于合并多个媒体属性或合并媒体属性与媒体类型。
@media tv and (min-width: 700px) and (orientation: landscape) { … }
only – only关键字防止老旧的浏览器不支持带媒体属性的查询而应用到给定的样式
<link rel="stylesheet" media="only screen and (color)" href="example.css" />

CSS选择器的性能优化

说明:
1.样式系统从最右边的选择符开始向左进行匹配规则。只要当前选择符的左边还有其他选择符,样式系统就会继续向左移动,直到找到和规则匹配的元素,或者因为不匹配而退出。
2.如果你非常在意页面的性能那千万别使用CSS3选择器。实际上,在所有浏览器中,用 class 和 id 来渲染,比那些使用同胞,后代选择器,子选择器(sibling, descendant and child selectors)对页面性能的改善更值得关注。
CSS选择器的效率从高到低排序:
1.id选择器(#myid)2.类选择器(.myclassname)3.标签选择器(div,h1,p)4.相邻选择器(h1+p)5.子选择器(ul > li)6.后代选择器(li a)7.通配符选择器(*)8.属性选择器(a[rel=”external”])9.伪类选择器(a:hover,li:nth-child)
具体做法:
1.不要在编写id规则时用标签名或类名
2.不要在编写class规则时用标签名
3.把多层标签选择规则用class规则替换,减少css查找
4.避免使用子选择器
5.依靠继承
参考阿里文章

CSS预处理器(SASS,Compass,Stylus,LESS),实践经验以及思考

SASS

Webfonts

作用:WebFont 技术可以让网页使用在线字体,而无需使用图片,从而有机会解决开头设计师提到的问题。它通过 CSS 的@font-face语句引入在线字体,使用 CSS 选择器指定运用字体的文本,与此同时专用于 Web 展示的 woff 格式字体也得到各大浏览器厂商支持,进一步减少了字体的体积。
语法:

1
2
3
4
5
6
7
8
@font-face {
font-family: 'ciclefina';
src: url('fonts/cicle_fina-webfont.eot');
src: url('fonts/cicle_fina-webfont.eot?#iefix') format('embedded-opentype'),
url('fonts/cicle_fina-webfont.woff2') format('woff2');
font-weight: normal;
font-style: normal;
}

WebFont的优势:
支持选中、复制
支持 Ctrl+F 查找
对搜索引擎友好
支持工具翻译
支持无障碍访问,支持朗读
字体是矢量图形,支持矢量缩放,自动适配高清屏
文本修改方便
字形可以重复利用,节省网络资源
中文 WebFont 的困境:
1、中文字体体积
2、浏览器类型(各种壳的浏览器)
3、操作系统(主要是XP系统)
现有的中文 WebFont 解决方案:
1.本地制作
通过字体制作工具来删除没有使用的字符,即制作精简版字体,这也是我之前实践过的方案。

2. 字体云服务    

https://www.youziku.com/
3开源工具
字蛛(Font-Spider)
参考Webfont

Flexbox

说明:Flex 是 Flexible Box 的缩写,意为”弹性布局”,用来为盒状模型提供最大的灵活性。
由容器 Container 和 子项目 Item 构成。

Container 容器相关的属性

首先 display: flex / inline-flex;
flex-direction – 决定主轴的方向(即项目的排列方向)。
flex-wrap – 如果一条(主轴)轴线排不下,如何换行。
flex-flow – 是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap。
justify-content – 定义了项目在主轴上的对齐方式。
align-items – 定义项目在交叉轴上如何对齐。
align-content – 定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。

Item 子项目相关的属性

order – 定义项目的排列顺序。数值越小,排列越靠前,默认为0。
flex-grow – 定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。
flex-shrink – 定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。
flex-basis – 定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。
flex – 是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。
align-self – 允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。
阮老师博客-Flex

适配retina屏幕

什么是retina屏幕适配?
当一个图像在标准设备下全屏显示时,一位图像素对应的就是一设备像素,导致一个完全保真的显示,因为一个位置像素不能进一步分裂。而当在Retina屏幕下时,他要放大四倍来保持相同的物理像素的大小,这样就会丢失很多细节,造成失真的情形。
换句话说,每一位图像素被乘以四填补相同的物理表面在视网膜屏幕下显示。
适配方法:
1.直接加载2倍大小的图片。
假如要显示的图片大小为200px300px,你准备的实际图片大小应该为400px600px,并且使用以下代码控制即可:

1
<img src="pic.png" height="200px" width="300px" />

缺点:
    对于普通屏来说加载多倍图势必会导致页面加载时间加长,用户体验不佳。
更好的方案:

开源retina.js
原理是通过window.devicePixelRatio > 1判断是不同屏还是retina屏,然后再加载对应的几倍图。
2.Image-set控制
假如要显示的图片大小为200px300px,你准备的图片应有两张:一张大小为200px300px,命名为pic.png;另一张大小为400px*600px,命名为pic@2x.png(@2x是Retina图标的标准命名方式),然后使用以下css代码控制:
背景方式使用:

1
2
3
4
5
6
7
#logo {
background: url(pic.png) 0 0 no-repeat;
background-image: -webkit-image-set(url(pic.png) 1x, url(pic@2x.png) 2x);
background-image: -moz-image-set(url(pic.png) 1x,url(images/pic@2x.png) 2x);
background-image: -ms-image-set(url(pic.png) 1x,url(images/pic@2x.png) 2x);
background-image: -o-image-set(url(url(pic.png) 1x,url(images/pic@2x.png) 2x);
}

在img标签属性中使用:
1
<img src="pic.png" srcset="pic@2x.png 2x" />

3.使用@media控制
实际是判断屏幕的像素比来取舍是否显示高分辨率图像,代码如下:

1
2
3
4
5
6
7
8
9
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
only screen and (min--moz-device-pixel-ratio: 1.5), /* 注意这里的写法比较特殊 */
only screen and (-o-min-device-pixel-ratio: 3/2),
only screen and (min-device-pixel-ratio: 1.5) {
#logo {
background-image: url(pic@2x.png);
background-size: 100px auto;
}
}

参考文章

CSS3新增伪类以含义

p:first-letter 选择每一个P元素的第一个字母
p:first-line 选择每一个P元素的第一行
p:first-child 指定只有当p元素是其父级的第一个子级的样式
p:last-child 选择每个p元素是其父级的最后一个子级。
p:first-of-type 选择每个p元素是其父级的第一个p元素
p:last-of-type 选择每个p元素是其父级的最后一个p元素
p:only-of-type 选择每个p元素是其父级的唯一p元素
p:only-child 选择每个p元素是其父级的唯一子元素
p:nth-child(2) 选择每个p元素是其父级的第二个子元素
p:nth-last-child(2) 选择每个p元素的是其父级的第二个子元素,从最后一个子项计数
p:nth-of-type(2) 选择每个p元素是其父级的第二个p元素
p:nth-last-of-type(2) 选择每个p元素的是其父级的第二个p元素,从最后一个子项计数

:root 选择文档的根元素
p:empty 选择每个没有任何子级的p元素(包括文本节点)
input:enabled 选择每一个已启用的输入元素
input:disabled 选择每一个禁用的输入元素
input:checked 选择每个选中的输入元素
:not(p) 选择每个并非p元素的元素
::selection 匹配元素中被用户选中或处于高亮状态的部分

a[src^=”https”] 选择每一个src属性的值以”https”开头的元素
a[src$=”.pdf”] 选择每一个src属性的值以”.pdf”结尾的元素
a[src*=”runoob”] 选择每一个src属性的值包含子字符串”runoob”的元素

javascript

JavaScript语言

闭包

定义:定义在一个函数内部的函数(将函数内部的变量保留在内存中,这样外部就可以改函数内相关的变量)。
闭包就是能够读取其他函数内部变量的函数。
用途:一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。
1.匿名自执行函数 (function(){ // todo… })()
2.缓存(针对于复杂的计算,每次计算前先读缓存如果没有在进行计算并添加到缓存)
3.实现封装(可以将函数内部的变量通过暴露接口在函数外可以访问)

1
2
3
4
5
6
7
8
9
10
11
12
13
var person = function(){
//变量作用域为函数内部,外部无法访问
var name = "default";
return {
getName : function(){
return name; // 可以访问 name 属性
},
setName : function(newName){
name = newName; // 可以为 name 赋值
}
}
}();

4.闭包的另一个重要用途是实现面向对象中的对象
    
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function Person(){
var name = "default";
return {
getName : function(){
return name;
},
setName : function(newName){
name = newName;
}
}
};
var john = Person();
john.getName();
john.setName("john");
john.getName();

51脚本

作用域

变量作用域
函数作用域
块级作用域
ES6提出,let 和 const 声明。{}范围为该区域
建议在支持的环境尽量使用 let 和 const 代替 var。
作用域链
动态作用域 – 函数执行时才确定的。this(4种情况,资料较多这里不再阐述)
静态作用域 – 函数定义时就确定的。
函数的可以允许嵌套的。例如有一个全局函数a, 在 a 在有又定义了函数 b,此时就形成了一条作用域链。
b -> a -> window(浏览器)/global(Node环境)

原型(-> 代表指向)

Number.prototype(有一些自己的方法如,toFixed) -> Object.prototype (对象所有的方法) -> undefined(原型链的顶层,为null)
Number、String、Boolean、Array、Date、RegExp、都是上面的原型链。
Math对象有点特殊,无需在使用这个对象之前对它进行定义。类似于在该对象上定义了许多静态属性和静态方法,可以直接使用(Math.PI、Math.abs(-3))。
搞懂这张就好了

面向对象/继承

面向对象
继承
JS实现继承的几种方式

this(也就是说的动态作用域)

1.普通函数(挂载到全局上面)
在 ‘use strict’ 严格模式中指向 undefined
在非严格模式中指向window/global(适执行环境而定)
2.对象的方法
this 指向该对象
3.作为构造函数调用
this 指向该构造函数的实例
4.call、apply以及bind方法可以改变this指向
this 均指向第一个参数
区别:call、apply返回值是你调用的方法的返回值;而bind返回由指定的this值和初始化参数改造的原函数拷贝。
关于这三个方法的区别,请访问MDN

call和apply的作用,以及区别

参见上面

匿名函数

1.过去常用于设计为一个独立的作用域
(function(形参){ // todo })(实参);
2.函数声明也是匿名函数
let demo = function(){};

正则

1.描述几个正则的语法含义,比如:[]、{}、\w、\d、\s等
[abc] 查找方括号之间的任何字符。
[^abc] 查找任何不在方括号之间的字符。
[0-9] 查找任何从 0 至 9 的数字。
n{X} 匹配包含 X 个 n 的序列的字符串。
n{X,} 前面的模式 n 连续出现至少 X 次时匹配。
n{X,Y} 前面的模式 n 连续出现至少 X 次,至多 Y 次时匹配。
PS:所有的大写均表示非。
\w 查找单词字符。
\d 查找数字。
\s 查找空白字符。包括空格符、制表符、回车符、换行符、垂直换行符、换页符
\b 匹配单词边界。
2.i/g/m等的含义(ES6中添加u、y)
i – ignore(忽略大小写)
g – global(全局匹配及查找所有匹配而非在找到第一个匹配后停止)
m – multiple(执行多行匹配)
ES6 对正则表达式添加了u修饰符,含义为“Unicode 模式”,用来正确处理大于\uFFFF的 Unicode 字符。
ES6 还为正则表达式添加了y修饰符,叫做“粘连”(sticky)修饰符。
3.replace方法
第二个参数为string – string.replace(searchvalue,newvalue)
第二个参数是回调函数

1
2
3
4
this.replace(/(^\s+)|(\s+$)/g,function(result,$1,$2,offset,source){
//arguments中的每个元素对应一个参数
console.log(arguments);
});

具体参数说明:
result: 本次匹配到的结果
$1,…$9: 正则表达式中有几个(),就会传递几个参数,$1~$9分别代表本次匹配中每个()提取的结果,最多9个
offset:记录本次匹配的开始位置
source:接受匹配的原始字符串
4.匹配任意字符(使用互补的方式来实现)
[\s\S] 或 [\w\W] 或 [.\r\n]
注:\w 等价于 [A-Za-z0-9_]
51job

事件

1.DOM事件流
冒泡:事件冒泡的过程是:a –> div –> body 。
产生的原因:因为事件源本身(可能)并没有处理事件的能力,即处理事件的函数(方法)并未绑定在该事件源上。
处理问题:event.stopPropagation()阻止事件的传递行为。
应用:事件委托
捕获:事件从Document节点自上而下向目标节点传播的阶段
完整的DOM事件流模型:
捕获阶段 、目标阶段 、冒泡阶段
2.兼容性问题(优先级逐渐升高)
html的onclick属性绑定
dom.onclick = function(){}
dom.attachEvent(“onclick”, callback) // dom.detachEvent(“onclick”, callback)
dom.addEventListener(‘click’, callback, userCapture) // dom.removeEventListener(‘click’, callback, userCapture)
3.事件代理
原理为事件冒泡
例如一下DOM结构
ul
li
li
对ul绑定事件,而不是对li绑定事件。在通targe.tagName,以及点的是哪一个li做不用的操作。
4.自定义事件
如何实现一个自定义事件的系统
定义:自定义事件就是自己定义事件类型,自己定义事件处理函数,在合适的时候需要哪个事件类型,就去调用哪个处理程。
实现过程:(其实就是发布订阅模式或监听者模式)
1.定义自定义事件构造函数

1
2
3
4
function EventTarget(){
//保存事件处理程序数组集合,每个实例不共享
this.handlers = {};
}

2.在构造函数的原型上添加实例共享的方法

1
2
3
4
5
6
7
8
9
EventTarget.prototype = {
constructor: EventTarget, // 矫正原型链指向
addEvent: function(type, handler) {}, // 添加一个事件处理函数
addEvents: function(obj){}, // 批量添加事件
removeEvent: function(type, handler){}, // 移除一个事件处理函数
removeEvents: function(params) {}, // 批量移除事件
fireEvent: function(type) {}, // 触发一个事件
fireEvents: function(array) {} // 批量触发事件
};

3.调用

1
2
3
4
5
6
7
8
function b(){
console.log(123);
}
var target = new EventTarget();
target.addEvent("eat", b);
target.fireEvent({ type: "eat" }); // 12

详细信息参考博客

BOM/DOM

BOM – 浏览器对象模型(Browser Object Model,简称BOM)。
提供了独立于内容而与浏览器窗口进行交互的对象。描述了与浏览器进行交互的方法和接口,可以对浏览器窗口进行访问和操作,譬如可以弹出新的窗口,改变状态栏中的文本,对Cookie的支持等。
Window 对象
Navigator 对象
Screen 对象
History 对象
Location 对象
DOM – 文档对象模型(Document Object Model,简称DOM)。
DOM 就是针对 HTML 和 XML 提供的一个API。
兼容性问题
常规的增删改查等操作的原生方法的考核
查:
getElementById()、
getElementsByTagName()、
getElementsByName()、
getElementsByClassName()、
querySelector()、
querySelectorAll()
改:
document.getElementById(id).innerHTML=new value:修改HTML元素
document.getElementById(id).attribute=new value:修改元素属性
document.getElementById(id).style.property=new style:修改元素CSS
setAttribute():setAttribute()方法将设置元素中某个属性和值
parent.replaceChild(child,oldElem):替换节点
增:
A.append(B) : 把B追加到A内部(所有的A元素,以下类似)
A.appendTo(B) : 把A追加到B内部
A.prepend(B) : 把B追加到A内部的内容前(即B成为A第一个子元素)
A.prependTo(B) : 把A追加到B的内容前(即A成为B第一个子元素)
A.after(B) : 在A后追加B
A.before(B): 在A前追加B
node.insertBefore(A,B): 在父节点node里面的B节点前面追加A
parent.replaceChild(child,oldElem):替换节点
删:
dom.remove():删除该元素
parent.removeChild(child):删除子元素

动画

1.JS实现一个动画的方式
setTimeout、
setInterval、
setImmediate(window.clearImmediate)微软取消该方法,不建议使用、
window.requestAnimationFrame(callback)(window.cancelAnimationFrame() )
参数:一个在每次需要重新绘制动画时调用的包含指定函数的参数。
这个回调函数有一个传参,DOMHighResTimeStamp,指示从触发 requestAnimationFrame 回调到现在的时间。
2.CSS3的动画
申明一个动画:

1
2
3
4
@keyframes animationName {
from {background: red;}
to {background: yellow;}
}

    PS:参数说明,animationname、keyframes-selector(from(0%)、to(100%))、css-styles
使用一个动画:
    
1
2
3
4
div:hover {
animation: animationName 5s;
}
PS:animation: name duration timing-function delay iteration-count direction fill-mode play-state;

3.如何优化动画的流畅度
每一帧都需要在16ms内渲染
动画添加到opacity和transform等属性之上。
将内容藏在不起眼的地方,使用pointer-events:通过透明度为0来隐藏元素。
不要同一时间所有元素都做动画,除非使用编排。
轻微地增加延迟,让编排动作变得简单。
使用全局倍数来设计慢动画,然后加速之后所有的元素。
拍下你的UI,并且重放他们,以获取有价值的第三方关点。
网络活动导致滞后,你需要提前或者滞后加载大的http请求。
不要直接绑定滚动。
尽早&经常在手机上测试。
在不同的设备上经常测试,屏幕大小,像素,或者设备都有着极大的暗示。
4.animation-fill-mode
animation-fill-mode 这个 CSS 属性用来指定在动画执行之前和之后如何给动画的目标应用样式。
属性值:none | forwards | backwards | both
流畅web动画的十个法则

组合动画

动画事件/自定义事件(start、process、end等)

animationstart - CSS 动画开始后触发
animationiteration - CSS 动画重复播放时触发
animationend - CSS 动画完成后触发

shim和polyfill

polyfill 是 shim 的一种。
shim 是将不同 api 封装成一种,比如 jQuery 的 $.ajax 封装了 XMLHttpRequest 和 IE 用 ActiveXObject 方式创建 xhr 对象;
polyfill 特指 shim 成的 api 是遵循标准的,其典型做法是在IE浏览器中增加 window.XMLHttpRequest ,内部实现使用 ActiveXObject。

Ajax/跨域

1.对Ajax的作用、API方法的理解
Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术。
XMLHttpRequest(ActiveXObject 兼容版本ie)或新的Fetch API
重点研究下Fetch API
Fetch API提供了一个 JavaScript接口,用于访问和操纵HTTP管道的部分,例如请求和响应。
Fetch 接口
GlobalFetch
包含了 fetch() 方法,用于获取资源。
Headers(构造器)
相当于 response/request 的头信息,可以修改它,或者针对不同的结果做不同的操作。
Headers.append()
给现有的header添加一个值, 或者添加一个未存在的header并赋值.
Headers.delete()
从Headers对象中删除指定header.
Headers.get()
从Headers对象中返回指定header的第一个值.
Headers.getAll()
以数组的形式从Headers对象中返回指定header的全部值.
Headers.has()
以布尔值的形式从Headers对象中返回是否存在指定的header.
Headers.keys()
以迭代器的形式返回Headers对象中所有存在的header名.
Headers.set()
替换现有的header的值, 或者添加一个未存在的header并赋值.
Headers.values()
以迭代器的形式返回Headers对象中所有存在的header的值.
Headers.entries()
以 迭代器 的形式返回Headers对象中所有的键值对.

1
2
3
4
5
6
var myHeaders = new Headers();
myHeaders.append("Content-Type", "text/plain");
myHeaders.set("Content-Type", "text/html");
console.log(myHeaders.get("Content-Length")); // 11
myHeaders.delete("X-Custom-Header");
myHeaders.has("Content-Type")

Body
代表响应/请求的正文,允许你声明其内容类型是什么以及应该如何处理。
Body.bodyUsed(属性)
包含一个指示body是否被读取过的 Boolean 值。
Body.arrayBuffer()
使用一个buffer数组来读取 Response流中的数据,并将bodyUsed状态改为已使用。
Body.blob()
使用一个Blob对象来读取 Response流中的数据,并将bodyUsed状态改为已使用。
Body.formData()
使用一个 FormData 对象来读取 Response流中的数据,并将bodyUsed状态改为已使用。
Body.json()
使用一个 JSON 对象来读取 Response流中的数据,并将bodyUsed状态改为已使用。
Body.text()
使用一个USVString (文本) 对象来读取 Response流中的数据,并将bodyUsed状态改为已使用。
MDN-Fetch-body
Request(构造器)
相当于一个资源请求。
Request.method 只读
请求使用的方法 (GET, POST, 等.)
Request.url 只读
请求使用的 URL。
Request.headers 只读
请求所关联的 Headers 对象。
Request.context 只读
请求的上下文 例如:(例如:audio, image, iframe, 等)
Request.referrer 只读
请求的来源 (例如:client).
Request.mode 只读
请求的模式 (例如: cors, no-cors, same-origin).
Request.credentials 只读
请求的凭证 (例如: omit, same-origin).
Request.redirect 只读
如何处理重定向模式 (例如: follow, error, or manual)
Request.integrity 只读
请求内容的 subresource integrity 值 (例如: sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=).
Request.cache 只读
请求的缓存模式 (例如: default, reload, no-cache).
Body.bodyUsed 只读
指示body是否被使用, 类型为Boolean
Request.clone()
创建当前request的副本。

Request implements Body, so it also has the following methods available to it:
    Body.arrayBuffer()
    Returns a promise that resolves with an ArrayBuffer representation of the request body.
    Body.blob()
    Returns a promise that resolves with an Blob representation of the request body.
    Body.formData()
    Returns a promise that resolves with an FormData representation of the request body.
    Body.json()
    Returns a promise that resolves with an JSON representation of the request body.
    Body.text()
    Returns a promise that resolves with an USVString (text) representation of the request body.

MDN-Fetch-request
Response(构造器)
相当于请求的响应。
Response.type 只读
包含Response的类型 (例如, basic, cors).
Response.url 只读
包含Response的URL.
Response.useFinalURL
包含了一个布尔值来标示这是否是该Response的最终URL.
Response.status 只读
包含Response的状态码 (例如, 200 成功).
Response.ok 只读
包含了一个布尔值来标示该Response成功(状态码200-299) 还是失败.
Response.redirected 只读
表示该Response是否来自一个重定向,如果是的话,它的URL列表将会有多个
Response.statusText 只读
包含了与该Response状态码一致的状态信息 (例如, OK对应200).
Response.headers 只读
包含此Response所关联的Headers 对象.
Response 实现了 Body, 所以以下属性同样可用:
Body.bodyUsed 只读
包含了一个布尔值来标示该Response是否读取过Body.
Response.clone()
创建一个Response对象的克隆
Response.error()
返回一个绑定了网络错误的新的Response对象
Response.redirect()
用另一个URL创建一个新的 response.
Response 实现了 Body, 所以以下方法同样可用:
Body.arrayBuffer()
读取 Response对象并且将它设置为已读(因为Responses对象被设置为了 stream 的方式,所以它们只能被读取一次) ,并返回一个被解析为ArrayBuffer格式的promise对象
Body.blob()
读取 Response对象并且将它设置为已读(因为Responses对象被设置为了 stream 的方式,所以它们只能被读取一次) ,并返回一个被解析为Blob格式的promise对象
Body.formData()
读取Response对象并且将它设置为已读(因为Responses对象被设置为了 stream 的方式,所以它们只能被读取一次) ,并返回一个被解析为FormData格式的promise对象
Body.json()
读取 Response对象并且将它设置为已读(因为Responses对象被设置为了 stream 的方式,所以它们只能被读取一次) ,并返回一个被解析为JSON格式的promise对象
Body.text()
读取 Response对象并且将它设置为已读(因为Responses对象被设置为了 stream 的方式,所以它们只能被读取一次) ,并返回一个被解析为USVString格式的promise对象
参数:

1
2
3
4
5
6
var myHeaders = new Headers();
var myInit = { method: 'GET',
headers: myHeaders,
mode: 'cors',
cache: 'default' };
fetch('flowers.jpg',myInit)

返回值:
    Promise 对象
    PS:就算是404也会返回promise resolved 还需要使用Response.ok 是不是为 true进一步判断。

2.同步和异步
3.同源策略
作用:同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。
定义:同domain(或ip),同端口,同协议视为同一个域,一个域内的脚本仅仅具有本域内的权限,可以理解为本域脚本只能读写本域内的资源,而无法访问其它域的资源。这种安全限制称为同源策略。
同源主要的限制:
(1) Cookie、LocalStorage 和 IndexDB 无法读取。
(2) DOM和js对象无法获得。
(3) AJAX 请求不能发送。
4.跟后端的数据交互的方式:JSON/XML,JS如何解析JSON为对象
// json字符串
var str1 = ‘{ “name”: “cxh”, “sex”: “man” }’;
// json对象
var str2 = { “name”: “cxh”, “sex”: “man” };

// JSON字符串转换为JSON对象方法一
// var obj = eval('(' + str1 + ')');
// JSON字符串转换为JSON对象方法二
// var obj = JSON.parse(str1)

// JSON对象转换为JSON字符串方法一
JSON.stringify(str2)

对HTTP协议的理解

1.常见的状态码
200 OK
301 Moved Permanently
302 Found
304 Not Modified
307 Temporary Redirect
400 Bad Request
401 Unauthorized
403 Forbidden
404 Not Found
410 Gone
500 Internal Server Error
501 Not Implemented
前端同学需要了解的通信知识
2.常见的HTTP请求和响应
参考博客
3.1同源策略限制了一下行为:
1.Cookie、LocalStorage 和 IndexDB 无法读取
2.DOM 和 JS 对象无法获取
3.Ajax请求发送不出去
3.2解决跨域的方法
window.name + iframe
location.hash + iframe
jsonp(jsonp的原理和优缺点)
1.原理:动态创建script标签,利用script标签的src属性可以获取任何域下的js脚本,通过这个特性(也可以说漏洞),服务器端不在返回json格式,而是返回一段调用某个函数的js代码(该页面中存在该函数),在src中进行了调用,这样实现了跨域。
前面3中方式均只支持get方式
document.domain + iframe(跨子域)
HTML5中postMessage方案
window.postMessage(msg,targetOrigin)
window.addEventListener(‘message’,function(e) {}
跨域资源共享 CORS
WebSocket协议跨域
后端主要配置,Access-Control-Allow-Origin
node代理跨域
nginx代理跨域
详细请自行参考MDN相关文档
正确面对跨域,别慌
4.JSONP请求如何取消?
删除script标签(存在兼容性问题)
将callback函数置为空函数
5.GET/POST方法的区别和使用场景
get只应该用于获取数据,post用于提交数据(存在副作用)。
6.JavaScript模板引擎
Template.js
pug
Mustache
参考segmentfault
7.JavaScript设计模式
javascript设计模式

Mobile Web

重要概念
设备像素:设备屏幕的物理像素,对于任何设备来讲物理像素的数量是固定的。
CSS像素:这是一个抽象的像素概念,它是为web开发者创造的(是可以改变的,取决于用于是否缩放)。
设备像素比(DPR) = 设备像素个数 / 理想视口CSS像素个数(device-width)
最重要的两个视口,布局视口和理想
布局视口:移动端CSS布局的依据视口,即CSS布局会根据布局视口来计算。
理想视口,定义了理想视口的宽度,比如对于iphone5来讲,理想视口是320*568。但是最终作用的还是布局视口,因为我们的css是依据布局视口计算的,所以你可以这样理解理想视口:理想的布局视口。
下面这段代码可以告诉手机浏览器要把布局视口设为理想视口:

屏幕适配 – 主要是屏幕分辨率、尺寸、屏幕方向这些因素。
CSS3的媒体查询(media query)
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" />
width=device-width - 布局视口等于理想视口
device-width - 设备的宽度
initial-scale - 初始的缩放比例
minimum-scale - 允许用户缩放到的最小比例
maximum-scale - 允许用户缩放到的最大比例
user-scalable - 用户是否可以手动缩放
<meta name="format-detection" content="telephone=no,email=no" >
//禁止自动识别电话号码和邮箱
<meta name="apple-mobile-web-app-capable" content="yes" >
//苹果手机:会删除默认的工具栏和菜单栏,网站开启对web app程序的支持
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
//苹果手机:在web app应用下状态条(屏幕顶部条)的颜色,默认值为default(白色),可以定为black(黑色)和black-translucent(灰色半透明)。
<meta name="apple-touch-fullscreen" content="yes" />
//苹果手机:如果把一个web app添加到了主屏幕中,那么从主屏幕中打开这个web app则全屏显示
<link rel="apple-touch-icon" href="/static/images/identity/HTML5_Badge_64.png" />
//苹果手机:将应用添加到手机主屏幕,会有一个icon可以直接进入
重置部分css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
body {
font: 16px/1.5 Helvetica, Arial;
//这里是设置字体,Helvetica字体在移动端各系统都支持(都不支持微软雅黑)
-webkit-text-size-adjust: none;
//设置文本不会放大,普通网页在移动端打开文本是会跟随网页结构缩放的
}
* {
-webkit-tap-highlight-color: transparent;
//在一些手机上,如iphone,点击按钮等元素会出现点击态的背景色,设置为透明就看不出来了
-webkit-user-select:none;
//设置元素内的文字及其子元素将不会被选中
}
// 去除webkit的滚动条
::-webkit-scrollbar{
display: none;
}
div {
-webkit-overflow-scrolling : touch;
}
// 去除button在ios上的默认样式
button {
-webkit-appearance: none;
border-radius: 0;
}
// placeholder元素样式的修改
input::-webkit-input-placeholder{color:red;}
input:focus::-webkit-input-placeholder{color:green;}
// 使用css3的transition、transform(translate、scale、rotate、skew)、或者animation来进行动画或过度。
// 使用图片时,会发现图片下总是有大概4px的空白
img{display:block};
img{vertical-align:top}

事件
touchstart:当手指放在屏幕上触发;
touchmove:当手指在屏幕上滑动时,连续地触发;
touchend:当手指从屏幕上离开时触发;
touchcancel: 当系统停止跟踪时触发;
event.touches.length // 当前几个手指在触屏上

综合

模块化

1.对AMD、CMD(node.js)、UMD等规范的了解,以及ES6中关于模块的标准定义
2.使用过常用的模块化框架:Requirejs、Seajs等
3.使用模块化的方式,能够解决什么问题?
命名空间冲突(全局变量覆盖)
文件依赖管理
立即执行函数 + 闭包(实现模块的基本方法)
4.动态加载JavaScript有几种方式?
1.使用document.write/writeln()方式
document.writeln(““);
2.使用jquery getScript(url,callback)方法实现动态加载js文件
$.getScript(‘test.js’,function(){
// TODO…
});
3.动态改变已有script的src属性
4.使用原生js 动态创建script标签,并指定script的src属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
function loadJs(url,callback){
var script=document.createElement('script');
script.type="text/javascript";
if(typeof(callback)!="undefined"){
if(script.readyState){
script.onreadystatechange=function(){
if(script.readyState == "loaded" || script.readyState == "complete"){
script.onreadystatechange=null;
callback();
}
}
}else{
script.onload=function(){
callback();
}
}
}
script.src=url;
document.body.appendChild(script);
}
loadJs("test.js",function(){
// todo...
});

5.用XHR取得要脚本的内容,再创建 Script 对象。
6.如何判断动态脚本是否加载完成
    为scriptdom节点添加监听事件 onload 和 onreadystatechange
    
1
2
3
4
5
scriptDom.onload = scriptDom.onreadystatechange = function(){
// 这里处理了兼容性,不同浏览器 readyState 的值不一样
if(!this.readyState||this.readyState=='loaded'||this.readyState=='complete'){
// todo...
}

5.动态加载CSS方法
1.导入css文件
@import url(style.css);
2.简单的在页面中加载一个外部CSS文件
document.createStyleSheet(cssFile);
3.用createElement方法创建CSS的Link标签
7.分析依赖的方式
动态分析,也是运行时分析
本地编译分析出依赖链
8.如何做好模块加载的性能优化

Promise

参见阮一峰教程

MVVM

Angularjs
React (重点)
Babkbone
Vuejs (重点)

前端安全(XSS、CSRF等,攻击和防范方案)

在项目中有遇到过前端方面的安全问题吗?
什么是XSS、CSRF?
常见的漏洞场景有哪些?
如何防范XSS、CSRF
网站登陆都加验证码是为了解决哪方面的安全问题?有没有更好的方案?

性能优化

1.请减少HTTP请求(代理模式合并http请求)
合并图片(css sprites),合并CSS和JS文件;图片较多的页面也可以使用 lazyLoad 等技术进行优化。
2.请正确理解 Repaint重绘 和 Reflow重排
3.减少DOM操作(缓存dom节点)
对DOM操作的代价是高昂的,这在网页应用中的通常是一个性能瓶颈。
4.尽量使用json数据与后端交互而不是xml
5.高效使用HTML标签和CSS样式 (语义化利于seo)
6.使用CDN加速(内容分发网络)
7.将CSS和JS放到外部文件中引用,CSS放头,JS放尾
8.精简CSS和JS文件(压缩)
9.压缩图片和使用图片Sprite技术
10.注意控制Cookie大小和污染(使用storage代替)
cookie会在每次http请求自动添加,有点浪费
11.按需加载资源
12.缓存(主要是http头部字段和service workers)

浏览器

1.有哪几种浏览器内核
Trident – ie4-ie8
Gecko – 网景-firefox
Presto – Opera(Opera现已改用Google Chrome的Blink内核)
Webkit – Chrome、Safari
2.排版引擎
KHTML
WebCore
3.浏览器兼容性
css前缀
js自带方法的适配
对各种资源的支持webP图片格式
4.浏览器渲染页面的原理(不同浏览器不一样)
DOM Tree:浏览器将HTML解析成树形的数据结构。
CSS Rule Tree:浏览器将CSS解析成树形的数据结构。
Render Tree: DOM和CSSOM合并后生成Render Tree。
layout: 有了Render Tree,浏览器已经能知道网页中有哪些节点、各个节点的CSS定义以及他们的从属关系,从而去计算出每个节点在屏幕中的位置。
painting: 按照算出来的规则,通过显卡,把内容画到屏幕上。
reflow(重排)和repaint(重绘)
参考
5.浏览器检测和识别
根据浏览器特性来判断
根据UA来检测 – navigator.userAgent 字符串比较

框架

1.框架的设计方案

2.解决哪些问题

前端架构设计

前端架构是一系列工具和流程的集合,旨在提升前端代码质量,并实现高效、可持续的工作流。
1.前端架构四个核心:
● 代码——如何实现系统架构中的HTML、CSS和JavaScript
● 流程——构建高效并且防止出错的工作流所需要的工具和流程
● 测试——为网站搭建稳固基础
● 文档——规划好系统设计蓝图
2.前端架构师职责:
● 体系设计——清晰描绘产品和代码的最终形态
● 工作规划——制定完整开发工作流
● 监督跟进——保证项目高效率完成

跨终端开发

1.响应性设计(Mobile web),Media Queries
栅格系统(bootstrap)具体实现float + width百分比 + @media query
松软盒子flex 具体实现flex布局 + width百分比 + @media query
2.Hybird APP(PhoneGap、AppCan、Titanium等)大致的原理,以及解决的问题
Web App、Hybrid App、 Native App
原理:通过JSBridge,web页面可以调用Native的api,Native也可调用web页面的api或者通知H5页面回调。
3.React Native 和 weex
4.重构
主要考虑(性能优化和扩展性)
性能优化
5.前端工程化
借助Node.js的功能(读写文件、搭建服务器、读写数据库等等)帮我们完成如图片、代码压缩、代码检测等事情。
模块化与组件化: npm, es6, react/angularjs
代码版本管理: git
代码风格管理: jscs, editorconfig
代码编译: babel, scss, imgmin, csssprit, inline-svg
代码质量管理 (QA): eslint, mocha
代码构建: webpack
项目脚手架: yeoman
持续集成/持续交付/持续部署: jenkins
本地化与国际化
6.系统架构/设计

开放性问题

  1. 描述一个你遇到过的技术问题,你是如何解决的?
  2. 是否有设计过通用的组件?
    请设计一个 Dialog(弹出层)等组件
    你会提供什么接口?
    调用过程是怎样的?可能会遇到什么细节问题?
    API
    visible – 对话框是否可见
    title – 标题
    closable – 是否显示右上角的关闭按钮
    mask – 是否展示遮罩
    maskClosable – 点击蒙层是否允许关闭
    maskStyle – 遮罩样式
    bodyStyle – Dialog body 样式
    footer – 底部内容,当不需要默认底部按钮时,可以设为 footer={null}
    cancelText – 取消按钮文字
    okText – 确认按钮文字
    onCancel – 点击遮罩层或右上角叉或取消按钮的回调
    onOk – 点击确定回调
    zIndex 设置 Modal 的 z-index(特殊情况使用)

  3. 请描述一下你做过的哪个前端方面的功能让你特别有成就感

  4. 在制作一个Web应用或Web站点的过程中,你是如何考虑它的UI、安全性、高性能、SEO、可维护性以及技术因素的?
  5. 说说最近最流行的一些东西吧?常去哪些网站?

潜力(加分项)

  1. 熟悉一门非前端语言,并且有项目开发经验,包括且不限于C/C++/Python/PHP/Java/Ruby等
  2. 在Native开发上有相关的经验(iOS、Android)等
  3. 有自己的独立博客并且有自己的思考和总结性质的文章、github有自己维护的仓库并且活跃(即开源项目)
  4. 对技术的追求有热情,特别对新技术的敏感性,能够积极主动学习新技术,并且能够有实践性的应用,比如:HTML5、Nodejs、MVVM、Promise、React、React Native、Angular等等
  5. 有较好的产品意识,并且有积极推动业务进步并拿到结果的案例
  6. 主动性、逻辑性、沟通、协同等方面的软实力良好
  7. 项目管理PM角色的经历(团队合作、沟通、协调能力)

你对break和continue的理解

break 关键字
break 主要用在循环语句或者 switch 语句中。
break 在循环语句中作用是跳出本层(并非本次)的循环。
break 在switch语句中作用是跳出该switch语句体。
continue 关键字
continue 适用于任何循环语句中。作用是让程序立刻跳转到下一次循环的迭代。
在 for 循环中,continue 语句使程序立即跳转到更新语句i++。
在 while 或者 do…while 循环中,程序立即跳转到布尔表达式的判断语句。

-------------本文结束感谢您的阅读,如果本文对你有帮助就记得给个star-------------
Donate comment here