基础
前端页面有哪三层构成?
结构层HTML、表示层CSS、行为层JavaScript。
结构层由HTML创建,定义网页内容,搭建文档结构;表示层由CSS创建,定义页面样式,设置文档展示效果;行为层由JavaScript创建,实现文档行为,响应用户操作。
- HTML是一门什么样的语言及特点?
超文本标记语言,包括一系列标签.通过这些标签将网络上的文档格式统一,主要是用来制作网页的。 - CSS是一门什么样的语言及特点?
层叠样式表 (Cascading Style Sheets),定义如何显示 HTML 元素,解决内容与表现分离的问题 - JavaScript是一门什么样的语言及特点?
一种基于对象和事件驱动的的脚本语言,
第一个特点简单:采用弱类型的变量类型,对使用数据类型没有严格要求;java变量在定义时就规定变量类型
2解释性的脚本语言,源代码不需要预编译,在浏览器中运行时被解释
3基于对象:可以创建对象,也能使用现有对象;比如 Object Array Math Date
4事件驱动:不需要经过Web服务器就可以对用户点击触摸输入等操作做出响应
5跨平台:JavaScript依赖浏览器,与操作环境无关
html文档类型声明
文档模式有三种:混杂模式(quirks mode)、标准模式(standards mode)和准标准模式,告诉浏览器使用哪种HTML版本来显示网页
h5文档类型 !DOCTYPE html
浏览器内核(渲染引擎)
①IE内核 -- Trident
②Firefox内核 -- Gecko
③Safari内核(曾经Chrome内核) -- Webkit
④现Chrome内核 -- Blink
绑定事件的方式?
1、直接在dom元素里绑定:<div onclick="test(this)"></div>
2、在JavaScript代码中绑定:xxx.onclick=test;
3、绑定事件监听函数:dom.addEventListener("click", ele, boolean)
事件委托/事件代理
事件在冒泡过程中会上传到父元素,把子元素的监听函数定义在父元素上,让父元素的监听函数统一处理所有子元素的事件,这种方式称为事件代理(Event delegation)。
优点
1.节省内存消耗,减少事件注册 如果一个列表有很多列表项,需要在点击列表项的时候响应一个事件,把这个事件绑定到他的父层
2.动态绑定事件 选择器只会选择页面中已经存在的元素,事先不存在元素无法绑定事件,利用事件冒泡机制触发它外层元素的绑定事件上,然后在外层元素上去执行函数
(拓展:js事件流模型?)
事件:事情发生并且得到处理的操作/指文档和浏览器窗口发生特定交互的瞬间。
事件流:事件从发生到传播结束的过程
“dom事件流”三个阶段:事件捕捉,当前目标阶段,事件冒泡;
“事件捕捉”:由document先接收,然后逐级向下,一直到目标元素;
“事件冒泡”:由目标元素先接收,然后逐级向上传播,一直到document
1. JS代码只能执行捕获或者冒泡其中一个
2. onblur,onfocus事件是没有冒泡的。(onmouseenter-鼠标指针移动到元素上时触发, onmouseleave-鼠标指针移出元素上时触发;jQuery测试时还是会冒泡)
3. 如果 addEventListener 第三个参数是true处于捕获阶段,false或省略处于冒泡阶段,其他事件都处于冒泡阶段
e.stopPropagation() 阻止冒泡
e.preventDefault() 阻止默认事件
事件event
代表事件的状态,描述事件所有的相关信息,比如事件发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态,Event.target:返回触发事件的元素,Event.currentTarget:返回绑定事件的元素。事件委托下Event.target是目标元素,
4、form表单提交与ajax提交什么区别?
1、Ajax必须要使用JS来实现,不启用JS的浏览器无法完成操作;Form提交是浏览器本能,无论是否开启JS都可以提交表单。
2、Ajax在提交、请求、接收中整个过程都需要代码来对其数据进行整理;Form提交的数据根据表单结构自动完成,不需要代码干预。
3、Ajax在整个过程都是异步进行的,网页不需要刷新;而Form提交则是新建一个页面,哪怕是提交给自己本身的页面,也是需要刷新的。
5、为什么要用Ajax?
让页面不重载全部内容的情况下加载局部内容,降低数据传输量,避免用户跳转和刷新页面,提高用户体验
6、离线存储--本地存储和离线缓存 及优缺点
1.本地存储--1) cookie 2) localStorage 3) sessionStorage
2.离线缓存--1) Application Cache (Manifest)
Cookie
优点:
可控制过期时间,默认情况下是关闭浏览器后失效
会参与到与服务端的通信中,一般会携带在http请求头
支持同源策略
缺点:
数量和长度有限制,最多20条,最长不能超过4k
主要应用:
客户端登录、购物车
localStorage(本地存储) sessionStorage(会话存储)
优点:
拓展了cookie的4k限制,可以存储5M数据
单纯的前端存储,不参与与服务端的通信
支持同源策略,不同网站不能共用相同的localStorage
缺点:
需要手动删除,否则长期存在
只支持string类型的存储,JSON对象需要转换
本质上是对字符串的读取,如果存储内容多的话会消耗内存空间,会导致页面变卡
特点:
支持同源策略、只在本地存储、永久保存、同浏览器共享、存储方式、存储上限限制(大多数5MB以下)。
应用场合:
数据比较大的临时保存方案。在线编辑文章时的自动保存。
sessionStorage(会话存储)
有效期是只保持在当前页面,关闭当前页或者浏览器后就会失效
应用场合:
适合单页应用程序,方便在各业务模块进行传值。
离线缓存--Application Cache (Manifest)
优势:
离线浏览:用户可在应用离线时使用它们
速度:已缓存资源加载速度块
减少服务器负载:浏览器只从服务器下载更新过的资源
使用方法:
在html标签添加manifest属性,属性值为manifest文件的路径
<!DOCTYPE HTML>
<html manifest=""demo.manifest""></html>
编写manifest文件
manifest文件可分为三部分:
(1) CACHE MANIFEST - 在此标题下列出的文件将在首次下载后进行缓存
(2)NETWORK - 在此标题下列出的文件需要与服务器的连接,且不会被缓存
(3)FALLBACK - 在此标题下列出的文件规定当页面无法访问时的回退页面(比如 404 页面)
CACHE MANIFEST
#version 1.1 /*版本号*/
CACHE:
html/index.html /*需要缓存的文件*/
NETWORK:
js/jquery.js /*不需要缓存的文件*/
FALLBACK:
html/index.html /*当页面无法访问时的回退页面*/
HTML
1、HTML 块级元素、行内元素
块级元素:
①排斥其他元素位于同一行;
②长宽,行高以及内外边距都可控制;
③宽度默认是它的容器的100%,除非设定一个宽度。
④它可以容纳内联元素和其他块元素
div p from table ol ul dl li h1-h6标题
nav、header、section、footer。
行内元素:
①和其他元素都在一行上;
②宽高,行高及上下(内外)边距不可改变;
③内联元素只能容纳文本或者其他内联元素
span br a lable(为input元素定义标注,焦点关联表单控件) i(无意义的加粗、斜体) em(有意义的加粗、斜体) strong(加粗)
行内块状元素:
综合了行内元素和块状元素的特性,显示效果为行内元素,但它拥有块状元素的属性。
input textarea button img select
这三者可以通过 display 相互转换。
3、表单标签的 readonly 与 disabled 的区别
readonly 只读,只用于文本输入框,input type="text/password"、textarea;
使用表单提交时会提交此元素,应用在用户只读同时需要提交数据的场景。
disabled 禁用,可用于所有表单标签,使用表单提交时不会提交此元素。
2、HTML5 新特性
1、语义特性 -- 新增语义化标签,例如 datalist header section footer nav;新增自定义数据属性data-变量名,删除标签 <big> <center> <font> <frame> <frameset> <noframes>;
2、本地存储特性 -- localStorage sessionStorage ApplicationCache应用程序缓存。
3、移动端touch系列事件
4、连接特性 -- Web Sockets
5、网页多媒体特性 -- Audio 和 Video 标签
6、三维图形 特性 -- 画布 Canvas,可缩放矢量图形 SVG。
7、设备访问特性 -- 地理位置API - 获取用户的地理位置 getCurrentPosition(),媒体访问API getUserMedia()
ES6
1、ES6
1、块级作用域
ES5 只有全局作用域和函数作用域,let、const 实际上为JS 新增了块级作用域
不存在变量提升、不允许重复声明。
let 命令
暂时性死区,在代码块内使用let命令声明某变量之前,该变量都是不可用的
const 命令
声明一个只读的常量且必须赋值。一旦声明,常量的值就不能改变。如果是对象则不能改变对象的引用,或可以增加属性。
ES6 声明变量的六种方法
var、function(ES5)
let、const、import、class
使用解构赋值{}(直接从数组或者对象中取值赋值给变量)、扩展运算符...(把数组的中括号,对象的{}直接去掉;用到左侧聚合,右侧展开)
2、字符串
模板字符串 使用反引号 $ {}组成HTML,以前用+特别麻烦
2、数字
传统的全局数字方法parseInt parseFloat,isFinite(),isNaN() 转换成 Number.isFinite(), Number.isNaN(),Number.parseInt(), Number.parseFloat()。新增 Number.isInteger() ,Number.isSafeInteger()
2、数学 Math.cbrt()立方根(Math.sqrt现有平方根)
4、对象
属性名表达式,如果属性名不合法不能用.访问用中括号访问
Object.assign() 合并对象 如果第一个参数为空对象且拷贝对象第一层数据是基本数据类型返回的对象属于深拷贝
5、数组
Array.from 方法 将类似数组的对象转为数组(ES5 -- Array.prototype.slice.call)。
Array.of()方法用于将一组值,转换为数组
find()查找符合条件的数组项,findIndex(),findLast(),findLastIndex(),includes()是否包含 fill()填充
flat(),flatMap()-拉平嵌套的数组
使用数组成员对变量赋值时,优先使用解构赋值。
6、箭头函数 -- 匿名函数的简写 -- 比如setTimeout
不绑定this与arguments,不能用作构造器,也没有prototype属性,隐式返回值。立即执行函数可以写成箭头函数的形式
简单的、单行的、不会复用的函数,建议采用箭头函数。如果函数体较为复杂,行数较多,还是应该采用传统的函数写法。
9、模块
①使用import取代require。
②使用export取代module.exports。
1、Promise 的含义
保存未来才会结束的事件结果,有三种状态:pending(进行中)、resolved(已成功)和rejected(已失败)。Promise对象是一个构造函数,接受一个函数作为参数,这个函数的两个参数分别是resolve函数和reject函数。由 JavaScript 引擎提供,不用自己定义。
resolve函数的作用是Promise对象的状态从“未完成pending”变为“成功resolved”,在异步操作成功时调用,将异步操作的结果作为参数传递出去;
reject函数的作用是将Promise对象的状态从“未完成pending”变为“失败rejected”,在异步操作失败时调用,将异步操作报出的错误作为参数传递出去。
Promise实例生成以后,用then方法catch方法指定resolved状态和rejected状态的回调函数
调用resolve或reject并不会终结 Promise 的参数函数的执行,应该加上return
Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例,接受多个Promise 实例组成的数组作为参数,多个Promise 实例的状态都变成resolve时Promise.all返回resolve,只要有一个rejected那Promise.all返回rejected,适合多图片上传。
作为参数的 Promise 实例,自己定义了catch方法,如果它被rejected,不会触发Promise.all()的catch方法。
Promise.race()方法同样是将多个 Promise 实例包装成一个新的 Promise 实例。作为参数的某个实例先改变状态就改变Promise.race()状态
缺点:1.无法取消Promise,一旦新建它就会立即执行,无法中途取消
2.如果不设置回调函数,Promise内部抛出的错误,不会反应到外部
3.当处于pending状态时,无法得知目前进展到哪一个阶段
const promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
promise.then(function(value) {
// success
}, function(error) {
// failure
});
async/await
async表示函数里有异步操作,await表示跟在后面的表达式需要等待结果,await必须写在async函数中,但是async可以没有await,一般是联合使用
async函数返回一个 Promise 对象,必须等到内部所有await命令(后面的 Promise 对象,异步操作)执行完或者遇到return语句,才会改变状态,才会执行then方法指定的回调函数;抛出错误执行catch回调函数;
正常情况下,await命令后面是一个 Promise 对象,返回这个对象的结果。如果不是 Promise 对象,就直接返回对应的值。
有时希望前一个异步操作失败也不要中断后面的异步操作,可以将第一个await放在try...catch结构里面,这样不管这个异步操作是否成功,第二个await都会执行。
8、Class extends
对类使用new命令,跟构造函数的用法完全一样
类定义不会被提升,必须在访问前对类进行定义,类中方法不需要 function 关键字。
constructor 方法是类的默认方法,创建类的实例化对象时被调用。相当于ES5构造函数
prototype 还存在,直接在类中定义原型方法
子类继承父类使用extents+super()方法,子类 constructor 方法中必须有 super ,必须出现在 this 之前
9、Map 键值对的集合(Hash 结构)“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。,Map 结构提供了“值—值”的对应
.set get has(key) delete(key) clear()方法 size属性
.keys():返回键名的遍历器 .values():返回键值的遍历器 .entries():返回所有成员的遍历器 .forEach():遍历 Map 的所有成员。
Map 转为JSON JSON.stringify(strMapToObj(strMap));
JSON转为Map objToStrMap(JSON.parse(jsonStr));
10、Set 类似于数组,但是成员的值都是唯一的,没有重复的值
Set.prototype.add(value):添加某个值,返回 Set 结构本身。
.delete(value):删除某个值 .has(value) .clear() .size属性-没有括号
.keys():返回键名的遍历器 .values():返回键值的遍历器 .entries():返回键值对的遍历器.forEach():使用回调函数遍历每个成员
11、Proxy 代理 在目标对象之前架设一层“拦截”,外界对这个对象的访问,必须先通过这层拦截,
12、Symbol.iterator for...of Array、DOM NodeList 对象、arguments对象、Set、Map
完成遍历操作,依次处理数据结构的所有成员
作用有三个:一是 ES6 创造了一种新的遍历命令for...of循环;二是使数据结构的成员能够按某种次序排列;三是为各种数据结构提供一个统一的、简便的访问接口
for of循环可以与break、continue 和 return 配合使用,跳出循环
async/await
Set
Proxy
Symbol.iterator
兼容性
1、移动端click事件300ms延迟
移动端会有双击和长按的操作,所以浏览器在click之后要等待300ms,看用户有没有下一次点击,是不是双击;禁用缩放,head标签设置<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>,将延迟缩短在100ms内
2、新版本google 浏览器 监听touch类事件报错:无法被动侦听事件preventDefault,Unable to preventDefault inside passive event listener
preventDefault是取消默认事件,移动端浏览器为了快速相应touch事件,取消了对默认事件的检查,直接执行滑动操作
touch-action: none;//触摸事件都不会产生默认行为,但是 touch 事件照样触发。
1、移动端适配
移动端的屏幕尺寸非常多,rem + 媒体查询适配 @media screen and (min-width:100px) and (max-width:200px) {html元素的font-size属性}
2、移动端事件穿透,移动端touchstart关闭遮罩层触发底层元素事件
e.preventDefault();
统一使用click事件
//移动端遮罩层滑动touch-action: none
2、点击穿透到下面一层,不点击上层
上层元素css添加 pointer-events: none; //应用在网站logo上
2、移动端1像素边框问题
首先要了解设备物理像素和逻辑像素,两个含义其实是不一样的,UI设计师要求的1px是指设备的物理像素1px,而CSS里记录的像素是逻辑像素,它们之间存在一个比例关系,移动端比列一般是2倍、3倍,css里写的1px长度映射到物理像素上就有2px或3px那么长,可以用javascript中的window.devicePixelRatio来获取(媒体查询的-webkit-min-device-pixel-ratio),
.div { position: relative; }
.div::after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 200%;
height: 200%;
border: 1px solid #bfbfbf;
border-radius: 4px;
-webkit-transform: scale(0.5,0.5);
transform: scale(0.5,0.5);
-webkit-transform-origin: top left;
}
3、安卓与苹果处理日期的兼容
苹果处理日期不支持 “点”、“横杠”,只支持”斜杠“运算
4、对非可点击元素如(label,span)监听click事件,部分ios下不会触发
css增加 -- cursor:pointer;
6、ios和android下点击元素时出现难看的的高亮效果(半透明灰色遮罩)
-webkit-tap-highlight-color:rgba(255,255,255,0);/*备注:transparent的属性值在android下无效。*/
5、iphone及ipad下输入框默认内阴影
-webkit-appearance:none;
2、ios 伪类 :active 失效
body添加ontouchstart onmousemove两个空事件
4、上下拉动滚动条时卡顿、慢
body { -webkit-overflow-scrolling:touch; overflow-scrolling: touch; }
4、CSS动画页面闪白,动画卡顿
尽可能地使用合成属性transform和opacity来设计CSS3动画,少使用position的left和top来定位。
开启硬件加速 transform: translate3d(0, 0, 0);
7、Cannot use import statement outside a module
用了es6的语法, 浏览器默认将它作为js解析会出现问题,需要将它作为模块导入,script标签默认type="text/javascript",需要改为type="module"
8、微信小程序后台报错 APP-SERVICE-SDK:setStorageSync:fail write DB data fail
存储数据失败,将存储和读取数据的代码封装成模块,定义一个全局变量,存储数据时先保存一份在全局变量中,然后try-wx.setStorageSync catch-wx.setStorage,保存两次。读取时同样的。
let storageObj = {};
function getKey(key) {
if (storageObj[key]) {
return storageObj[key];
} else {
try {
return wx.getStorageSync(key);
} catch (err) {
return wx.getStorage({
key: key,
success: function(res) {
return res.data;
}
});
}
}
}
function setKey(key, value) {
storageObj[key] = value;
try {
wx.setStorageSync(key, value);
} catch (e) {
wx.setStorage({
key: key,
data: value
});
}
}
9、微信小程序后台 Object.values is not a function in onShow
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。