html的使用

# html基础

# 简介

# HTML、XML、XHTML 有什么区别

  • html: 超文本标记语言,显示信息,不区分大小写
  • xhtml: 升级版的html,区分大小写
  • xml: 可扩展标记语言被用来传输和存储数据

# 对WEB标准和W3C的理解认识

个人理解:

  • html - 表示人的光身体 ---结构
  • css - 表示给人穿的衣服 ---表现
  • js - 表示人的行为,走路等 ---行为

# 标签

# pre

预格式化标记; 保留预先编排好的格式;

# <dl><dt><dd>

使用场合 对列表条目进行简短的说明 格式

	<dl>
	<dt>软件说明:</dt>
	<dd>简单介绍软件的功能及基本应用</dd>
	<dt>软件界面</dt>
	<dd>用于选择软件的外观</dd>
	</dl>
1
2
3
4
5
6

# 超链接

<a> href="" target="打开方式" name="页面锚点名称" >链接文字或者图片</a>

![](~/19-51-43.jpg)

# table

<caption> 标记, 表头部;

<td><th> rowspan:设置单元格所占行数; colspan:设置单元格所占列数;

# div+css与table布局的比较

1,其实也是div+css布局的第一个特点,table标签被严格地定义为存放数据的一个区域,而不是布局工具,它的布局形式不符合W3C标准,没有实现结构和表现的分离,它既有css的表现功能,也有html的结构功能。

2,table布局加载网页时,必须整体加载完,降低了网页的呈现速度,而div+css布局是边加载边显示的。div+css加快了页面的加载速度(最重要的)(在IE中要将整个table加载完了才显示内容)。

3,table布局在网页代码编写时,有时需要嵌套多重表格才能实现,但使用div+css布局,相对而言会减少许多嵌套时的代码,更容易检查和维护。

4,table布局不方便表现的更换,使用div+css布局,大多只要更改css样式表就能变化表现形式。

5、易于维护和改版。

# form

示例:<form action="服务器端地址" name="表单名称" method="post|get">...</form>

常用属性

  • enctype:设置表单的资料的编码方式
  • target:和超链接的属于类似,用来指定目标窗口
  • action:表单数据的处理程序的URL地址; 如果为空则使用当前文档的URL地址; 如果表单中不需要使用action属性也要指定其属性为”no“
# Label的作用

label标签来定义表单控制间的关系,当用户选择该标签时,浏览器会自动将焦点转到和标签相关的表单控件上

<label for="Name">Number:</label>
<input type=“text“name="Name" id="Name"/>
<label>Date:<input type="text" name="B"/></label>
1
2
3
# <img> 的title和alt的区别

title是global attributes之一,用于为元素提供附加的advisory information。通常当鼠标滑动到元素上的时候显示。

alt是<img>的特有属性,是图片内容的等价描述,用于图片无法加载时显示、读屏器阅读图片。可提图片高可访问性,除了纯装饰图片外都必须设置有意义的值,搜索引擎会重点分析。

# input和textarea的区别

<input> 标记没有结束标记

1.是一个单行输入框,有value属性(value属性指定初始值),但是它不能自动换行

2.用来放置字数较少的单行文字内容;

3.通过size属性指定显示字符的长度,value属性指定初始值,Maxlength属性指定文本框可以输入的最长长度;

<textarea> 标签对中

1.是一个多行输入框,没有value属性,但是它能自动换行;一般让用户可以输入多行文字,输入的文字信息量相比较大;

2.使用row、col指定大小;

3.另一个与<input>的区别在于,不能给<textarea>设置最大字符数。

<input type="text" size="20" maxlength="50" value="initial value">
<textarea cols="25" rows="5">initial value</textarea>

//无论这两种文本框在标记中有区别,但它们都将用户输入的内容保存在value中。可通过这个属性读取和设置文本框的值
var textbox = documnet.getElementsByTagName("textarea").value;
textbox.value = "some new value"
1
2
3
4
5
6

用div模拟textarea

textarea有一个不足就是不能像普通div标签一样高度可以跟随内容自适应textarea总是很自信地显摆它的滚动条,高度固执地岿然不动。自定义可控制max-height,超过后才出现滚动条; 要解决这个问题很简单,一个普通的block元素上加个contenteditable="true" overflow-y: auto

  <style>
    .myTextarea {
      min-height: 50px;
      max-height: 300px;
      width: 300px;
      font-size: 14px;
      border: 1px solid #a0b3d6;
      overflow-y: auto;
    }
  </style>
</head>
<body>
  <div>
    input:<input value="samy" style="height:50px;width: 500px;">
  </div>
  <div style="margin-top: 20px;">
    textarea:<textarea value="z" style="height:50px;width: 500px;"> </textarea>
  </div>
  <div>
  myTextarea: <div class="myTextarea" contenteditable="true"></div><!--用div模拟textarea-->
  </div>
</body>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# <meta>标签

name="format-detection":当该 HTML 页面在手机上浏览时,该标签用于指定是否将网页内容中的手机号码显示为拨号的超链接。

format-detection —— 格式检测,用来检测html里的一些格式,主要有以下几个设置:

  • meta name=”format-detection” content=”telephone=no”
  • meta name=”format-detection” content=”email=no”
  • meta name=”format-detection” content=”adress=no”

或者直接写成(连写): meta name=”format-detection” content=”telephone=no,email=no,adress=no”

  1. telephone 主要作用是是否设置自动将你的数字转化为拨号连接 telephone=no 禁止把数字转化为拨号链接 telephone=yes 开启把数字转化为拨号链接,默认开启
  2. email 告诉设备不识别邮箱,点击之后不自动发送 email=no 禁止作为邮箱地址 email=yes 开启把文字默认为邮箱地址,默认情况开启
  3. adress adress=no 禁止跳转至地图 adress=yes 开启点击地址直接跳转至地图的功能, 默认开启

比如:

在 iPhone 上默认值是:

<meta name="format-detection" content="telephone=yes"/>

如果你不希望手机自动将网页中的电话号码显示为拨号的超链接【移动设备忽略将页面中的数字识别为电话号码的方法】,那么可以这样写:

<meta name="format-detection" content="telephone=no"/>

viewport 控制手机全屏:响应式页面

<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">

meta name="keyword" 告诉搜素引擎网页的关键词

meta name="description" 告诉搜素引擎站点的内容

mata name="author" content="name"站点制作人

# 完整示例

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>示例table&form</title>
  </head>
  <body>
    <table border="1" width="200" height="200">
      <caption align="top">th标记</caption>
      <tr bgcolor="blue" align="right" valign="top">
        <th bgcolor="red" align="left" width="50" rowspan="2" colspan="3">班级</th>
        <!-- <th bgcolor="red">班级</th> -->
        <th>姓名</th>
        <th>年龄</th>
        <th>成绩</th>
      </tr>
      <tr>
        <td>一班</td>
        <td>张三</td>
        <td>12</td>
        <td>60</td>
      </tr>
      <tr>
        <td>一班</td>
        <td>李四</td>
        <td>13</td>
        <td>80</td>
      </tr>
    </table>
    <form action="07form_next.html" method="get" target="_blank">
      <!--<form action="07form_next.html" method="post" target="_blank">-->
      账号:
      <input type="text" name="account" id="" value="请输入用户名" size="20" /><br /> 密码:
      <input type="password" name="pwd" id="" value="" size="10" maxlength="8" /><br />
      性别:
      <input type="radio" name="sex" id="sex" value="man" /><input type="radio" name="sex" id="sex" value="woman" checked="checked"/><br /> 
      爱好:
      <input type="checkbox" name="sport" id="sport" value="1" />运动
      <input type="checkbox" name="sing" id="sing" value="2"  />唱歌
      <input type="checkbox" name="read" id="read" value="3" checked="checked" />看书
      <br />
      <input type="hidden" name="hidden_pwd" id="hidden_pwd" value="" size="20"/>
      自我介绍:
      <br />
      <textarea name="introduce" rows="15" cols="10">samy</textarea><br />
      地址:
      <select name="address" size="2" multiple="multiple">
        <option value="bj">北京</option>
        <option value="sh">上海</option>
        <option value="gz">广州</option>
        <option value="sz" selected="selected">深圳</option>
      </select><br />
      <input type="submit" name="" id="" value="提交" />
      <input type="reset" name="" id="" value="重置" />
      <input type="button" name="" id="" value="按钮" />
    </form>
  </body>
</html>
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

# h5新增及删除元素

# 文档声明

文档类型,一个文档类型标记是一种标准通用标记语言的文档类型声明,它的目的是要告诉标准通用标记语言解析器,它应该使用什么样的文档类型定义(DTD)来解析文档

Doctype还会对浏览器的渲染模式产生影响,不同的渲染模式会影响到浏览器对于 CSS 代码甚至 JavaScript 脚本的解析,所以Doctype是非常关键的,尤其是在 IE 系列浏览器中,由DOCTYPE 所决定的 HTML 页面的渲染模式至关重要。

![](~/19-43-18.jpg)

# 分析

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

HTML4.01基于SGML , 所以需要对DTD进行引用,才能告知浏览器文档所使用的文档类型

HTML5 不基于 SGML,因此不需要对DTD进行引用,但是需要doctype来规范浏览器的行为(让浏览器按照它们应该的方式来运行); (html 5简化了这种声明,意在告诉浏览器使用统一的标准即可

# 作用

.<!DOCTYPE>声明位于HTML文档中的第一行,处于

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

文档声明的作用:让浏览器解析器知道需要用什么规范来解析文档

<!DOCTYPE> 的作用:使用html5标准来解析渲染页面,如果不写就进入混杂模式

# 标准模式与兼容模式的区别

# Doctype作用?标准模式与兼容模式各有什么区别?

  • **Standards (标准)模式(也就是严格呈现模式)**用于呈现遵循最新标准的网页,而 **Quirks(包容)模式(也就是松散呈现模式或者兼容模式)**用于呈现为传统浏览器而设计的网页。
  • 标准模式的排版 和 JS运作模式都是以该浏览器支持的最高标准运行
  • 在兼容模式中,页面以宽松的向后兼容的方式显示, 模拟老式浏览器的行为以防止站点无法工作。
//html4示例:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta charset="UTF-8" />
  </head> 
</html>

//html5示例:
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body> </body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 新增的元素

# 理解语义化

根据**内容的结构化(内容语义化),选择合适的标签(代码语义化)**便于开发者阅读和写出更优雅的代码的同时让浏览器的爬虫和机器很好地解析。

html5新增了一些语义化更好的标签元素。简单来说,能用 <header>, <footer>等 H5 新标签的就不用 <div class="header">,不要使用 <div> 来存放段落等……

HTML5 中新增标签大致有:<header>, <footer>, <aside> ,<nav> ,<video> , <audio>,<canvas> 等等。

# 结构元素

article元素,表示页面中的一块与上下文不相关的独立内容,比如博客中的一篇文章。 aside元素,表示article内容之外的内容,辅助信息。 header元素,表示页面中一个内容区块或整个页面的页眉。 hgroup元素,用于对页面中一个区块或整个页面的标题进行组合。 footer元素,表示页面中一个内容区块或整个页面的页脚。 figure元素,表示媒介内容的分组,以及它们的标题。 section元素,表示页面中一个内容区块,比如章节。 nav元素,表示页面中的导航链接。

# 其他元素

video元素,用来定义视频。 audio元素,用来定义音频。 canvas元素,用来展示图形,该元素本身没有行为,仅提供一块画布。 embed元素,用来插入各种多媒体,格式可以是Midi、Wav、AIFF、AU、MP3等。 mark元素,用来展示高亮的文字。 progress元素,用来展示任何类型的任务的进度。 meter元素,表示度量衡,定义预定义范围内的度量。 time元素,用来展示日期或者时间。 command元素,表示命令按钮。 details元素,用来展示用户要求得到并且可以得到的细节信息。 summary元素,用来为details元素定义可见的标题。 datalist元素,用来展示可选的数据列表,与input元素配合使用,可以制作出输入值的下拉列表。 datagrid元素,也用来展示可选的数据列表,以树形列表的形式来显示。 keygen元素,表示生成密匙。 output元素,表示不同类型的输出。 source元素,为媒介元素定义媒介资源。 menu元素,表示菜单列表。 ruby元素,表示ruby注释, rt元素表示字符的解释或发音。 rp元素在ruby注释中使用,以定义不支持ruby元素的浏览器所显示的内容。 wbr元素,表示软换行。与br元素的区别是:br元素表示此处必须换行,而wbr元素的意思是浏览器窗口或父级元素的宽度够宽时。不进行换行,而当宽度不够时,主动在此处进行换行。 bdi元素,定义文本的文本方向,使其脱离其周围文本的方向设置。 dialog元素,表示对话框或窗口。

新页面结构

<!DOCTYPE html>
<html>
<head lang="en">
   <meta charset="UTF-8">
   <title>新的网页结构</title>
</head>
<body>
  <header>...</header>
  <nav>...</nav>
  <article>...</article>
  <section>...</section>
  <aside>...</aside>
  <footer>...</footer>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 废除的元素

html5中废除了一些纯表现的元素,只有部分浏览器支持的元素还有一些会对可用性产生负面影响的元素。

移除的元素总括: 纯表现的元素:basefont,big,center,font, s,strike,tt,u; 对可用性产生负面影响的元素:frame,frameset,noframes; 只有部分浏览器支持的元素:applet、bgsound、blink、marquee等元素

# 纯表现元素

纯表现的元素就是那些可以用css替代的元素。basefont、big、center、font、s、strike、tt、u这些元素,他们的功能都是纯粹为页面展示服务的,html5提倡把页面展示性功能放在css样式表中统一处理,所以将这些元素废除,用css样式进行替代。

# 对可用性产生负面影响的元素

对于frameset元素、frame元素与noframes元素,由于frame框架对网页可用性存在负面影响,在html5中已不支持frame框架,只支持iframe框架,html5中同时将frameset、frame和noframes这三个元素废除。

# 只有部分浏览器支持的元素

对于applet、bgsound、blink、marquee等元素,由于只有部分浏览器支持,特别是bgsound元素以及marquee元素,只被IE支持,所以在html5中被废除。其中applet元素可由embed元素或object元素替代,bgsound元素可由audio元素替代,marquee可以由javascript编程的方式替代。

# iframe的缺点

  • iframe会阻塞主页面的Onload事件;搜索引擎的检索程序无法解读这种页面,不利于SEO;
  • iframe和主页面共享连接池,而浏览器对相同域的连接有限制,所以会影响页面的并行加载

使用iframe之前需要考虑这两个缺点。如果需要使用iframe,最好是通过javascript动态给iframe添加src属性值,这样可以绕开以上两个问题。现在html5还是保留iframe属性;

# h5新增的API

# Canvas API

利用Canvas API进行绘图,首先要获取canvas元素的上下文,然后用该上下文中封装的各种绘图功能进行绘图。

<canvas id="canvas">替代内容</canvas>
<script>
    var canvas = document.getElementById('canvas');
    var context =canvas.getContext("2d"); // 获取上下文
    //设置纯色
    context.fillStyle = "red";
    context.strokeStyle = "blue";
    // 实践表明在不设置fillStyle下的默认fillStyle为black
    context.fillRect(0, 0, 100, 100);
    // 实践表明在不设置strokeStyle下的默认strokeStyle为black
    context.strokeRect(120, 0, 100, 100);
</script>
1
2
3
4
5
6
7
8
9
10
11
12

# SVG

SVG是html5的另一项图形功能,它是一种标准的矢量图形,是一种文件格式,有自己的API。html5引入了内联SVG,使得SVG元素可以直接出现在html标记中。

<svg height=100 width=100><circle cx=50 cy=50 r=50 /></svg>
1

Canvas和SVG的比较;

|                Canvas             |                SVG                 |
| --------------------------------- | -----------------------------------|
|        位图技术,可以保存为.png      |      矢量图技术,不能保存为位图
| --------------------------------- | -----------------------------------|
|        善于表现颜色和线条细节        |      可以缩放,不善于表现细节
| --------------------------------- | -----------------------------------|
|        网页游戏,统计图             |       图标,统计图,地图              | 
| --------------------------------- | -----------------------------------|
|一个标签(canvas)+一个对象(getcontext),                                    |                                     
| 所有图形图像都靠ctx绘制              |   几十个标签---每个图形对应一个标签    |
| --------------------------------- | -----------------------------------|
| 不能被搜索引擎爬虫所访问                        可以
| --------------------------------- | -----------------------------------|
| 只能为整个 Canvas绑定监听函数        |    每个图形(标签)可以绑定事件监听函数  |
| --------------------------------- | -----------------------------------|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 音频和视频

audio和video元素的出现让html5的媒体应用多了新选择,开发人员不必使用插件就能播放音频和视频。对于这两个元素,html5规范提供了通用、完整、可脚本化控制的API。

html5规范出来之前,在页面中播放视频的典型方式是使用Flash、QuickTime或者Windows Media插件往html中嵌入音频视频,相对这种方式,使用html5的媒体标签有两大好处

  1. 作为浏览器原生支持的功能,新的audio和video元素无需安装。
  2. 媒体元素想Web页面提供了通用、集成和可脚本化控制的API。
<video src="video.webm" controls>
    <object data="videoplayer.swf" type="application/x-shockwave-flash">
        <param name="movie" value="video.swf" />
    </object>
    Your browser does not support HTML5 video.
</video>
1
2
3
4
5
6

# 浏览器支持性检测

浏览器检测是否支持audio元素或者video元素最简单的方式是用脚本动态创建它,然后检测特定函数是否存在。

var hasVideo = !!(document.createElement('video').canPlayType);
1

# 页面可见性(Page Visibility API) 可以有哪些用途?

通过 visibilityState 的值检测页面当前是否可见,以及打开网页的时间等;在页面被切换到其他后台进程的时候,自动暂停音乐或视频的播放

# Geolocation API

html5的Geolocation API(地理定位API),可以请求用户共享他们的位置。使用方法非常简单,如果用户同意,浏览器就会返回位置信息,该位置信息是通过支持html5地理定位功能的底层设备(如笔记本电脑或手机)提供给浏览器的。位置信息由纬度、经度坐标和一些其他元数据组成。

# 位置信息从何而来

Geolocation API不指定设备使用哪种底层技术来定位应用程序的用户。相反,它只是用于检索位置信息的API,而且通过该API检索到的数据只具有某种程度的准确性,并不能保证设备返回的位置是精确的设备可以使用下列数据源:

  1. IP地址
  2. 三维坐标
    1. GPS
    2. 从RFID、WiFi和蓝牙到WiFi的MAC地址
    3. GSM或CDMA手机的ID
  3. 用户自定义数据
// 一次更新
navigator.geolocation.getCurrentPosition(updateLocation, handleLocationEror);
function updateLocation(position) {
    var latitude = position.coords.latitude;     // 纬度
    var longitude = position.coords.longitude;   // 经度
    var accuracy = position.coords.accuracy;     // 准确度
    var timestamp = position.coords.timestamp;   // 时间戳
}
// 错误处理函数
function handleLocationEror(error) {
    ....
}
// 重复更新
navigator.geolocation.watchPosition(updateLocation, handleLocationEror);
// 不再接受位置更新
navigator.geolocation.clearWatch(watchId);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# Communication API

# 跨文档消息传递

出于安全方面的考虑,运行在同一浏览器中的框架、标签页、窗口间的通信一直都受到了严格的限制。然而,现实中存在一些合理的让不同站点的内容能在浏览器内进行交互的需求。这种情形下,如果浏览器内部能提供直接的通信机制,就能更好地组织这些应用。 html5中引入了一种新功能,**跨文档消息通信,可以确保iframe、标签页、窗口间安全地进行跨源通信。**postMessage API为发送消息的标准方式,发送消息非常简单:

window.postMessage('Hello, world', 'http://www.example.com/');
1

接收消息时,仅需在页面中增加一个事件处理函数。当某个消息到达时,通过检查消息的来源来决定是否对这条消息进行处理。

window.addEventListener("message", messageHandler, true);
function messageHandler(e) {
    switch(e.origin) {
        case "friend.example.com":
        processMessage(e.data);// 处理消息
        break;
    default: 
        // 消息来源无法识别
        // 消息被忽略
    }
}
1
2
3
4
5
6
7
8
9
10
11

消息事件是一个拥有data(数据)和origin(源)属性的DOM事件。data属性是发送方传递的实际消息,而origin属性是发送来源。

# 如何实现浏览器内多个标签页之间的通信?

WebSocketSharedWorker , postMessage;也可以调用localstorge、cookies等本地存储方式; localstorge另一个浏览上下文里被添加、修改或删除时,它都会触发一个事件,我们通过监听事件,控制它的值来进行页面信息通信; 注意:Safari 在无痕模式下设置localstorge值时会抛出 QuotaExceededError 的异常;

# XMLHttpRequest Level2

XMLHttpRequest API使得Ajax技术成为可能,作为XMLHttpRequest的改进版,XMLHttpRequest Level2在功能上有了很大的改进。主要两个方面:

  1. 跨源XMLHttpRequest
  2. 进度事件
# 跨源XMLHttpRequest

过去,XMLHttpRequest仅限于同源通信,XMLHttpRequest Level2通过CORS实现了跨源XMLHttpRequest。跨源HTTP请求包含一个Origin头部,它为服务器提供HTTP请求的源信息。

# WebSockets API

WebSockets是html5中最强大的通信功能,它定义了一个全双工通信信道,仅通过Web上的一个Socket即可进行通信。

# WebSockets握手

为了建立WebSockets通信,客户端和服务器在初始握手时,将HTTP协议升级到WebSocket协议。一旦连接建立成功,就可以在全双工模式下在客户端和服务器之间来回传递WebSocket消息。

# WebSockets接口

除了对WebSockets协议定义外,该规范还同时定义了用于JavaScript应用程序的WebSocket接口。WebSockets接口的使用很简单。要连接远程主机,只需要新建一个WebSocket实例,提供希望连接的对端URL。

# webSocket如何兼容低浏览器

Adobe Flash Socket 、ActiveX HTMLFile (IE) 、基于 multipart 编码发送 XHR基于长轮询的 XHR

# Forms API

# 新表单元素

tel元素,表示电话号码。 email元素,表示电子邮件地址文本框。 url元素,表示网页的url。 search元素,用于搜索引擎,比如在站点顶部显示的搜索框。 range元素,特定值范围内的数值选择器,典型的显示方式是滑动条。 number元素,只包含数值的字段。

# 未来的表单元素

color元素,颜色选择器,基于调色盘或者取色板进行选择。 datetime元素,显示完整的日期和时间,包括时区。 datetime-local,显示日期和时间。 time元素,不含时区的时间选择器和指示器。 date元素,日期选择器。 week元素,某年中的周选择器。 month元素,某年中的月选择器。

# 新的表单特性和函数

placeholder

当用户还没输入值的时候,输入型控件可以通过placeholder特性向用户显示描述性说明或者提示信息。

<input name="name" placeholder="First and last name">
1

autocomplete

浏览器通过autocomplete特性能够知晓是否应该保存输入值以备将来使用。

form关闭自动完成功能:给不想要提示的 form 或某个 input 设置为 autocomplete=off

autofocus

通过autofocus特性可以指定某个表单元素获得输入焦点,每个页面上只允许出现一个autofocus特性,如果设置了多个,则相当于未指定此行为。

spellcheck

可对带有文本内容的输入控件和textarea空间控制spellcheck属性。设置完后,会询问浏览器是否应该给出拼写检查结果反馈。spellcheck属性需要赋值。

list特性和datalist元素

通过组合使用list特性和datalist元素,开发人员能够为某个输入型控件构造一张选值列表。

<datalist id="contactList">
    <option value="a@qq.com"></option>
    <option value="b@qq.com"></option>
</datalist>
<input type="email" id="contatcs" list="contactList">
1
2
3
4
5

min和max

通过设置min和max特性,可以将range输入框的数值输入范围限定在最低值和最高值之间。可以只设置一个,也可以两个都设置,也可以都不设置。

step

对于输入型控件,设置其step特性能够指定输入值递增或者递减的粒度。

required

一旦为某输入型控件设置了required特性,那么此项必填,否则无法提交表单。

其他

# 拖放API

# draggable属性

如果网页元素的draggable元素为true,这个元素就是可以拖动的。

<div draggable="true">Draggable Div</div>
1

# 拖放事件

拖动过程会触发很多事件,主要有下面这些:

  • dragstart:网页元素开始拖动时触发。
  • drag:被拖动的元素在拖动过程中持续触发。
  • dragenter:被拖动的元素进入目标元素时触发,应在目标元素监听该事件。
  • dragleave:被拖动的元素离开目标元素时触发,应在目标元素监听该事件。
  • dragover:被拖动元素停留在目标元素之中时持续触发,应在目标元素监听该事件。
  • drap:被拖动元素或从文件系统选中的文件,拖放落下时触发。
  • dragend:网页元素拖动结束时触发。
draggableElement.addEventListener('dragstart', function(e) {
    console.log('拖动开始!');
});
1
2
3

# dataTransfer对象

拖动过程中,回调函数接受的事件参数,有一个dataTransfer属性,指向一个对象,包含与拖动相关的各种信息。

draggableElement.addEventListener('dragstart', function(event) {
    event.dataTransfer.setData('text', 'Hello World!');
});
1
2
3

属性有

  1. dropEffect:拖放的操作类型,决定了浏览器如何显示鼠标形状,可能的值为copy、move、link和none。
  2. effectAllowed:指定所允许的操作,可能的值为copy、move、link、copyLink、copyMove、linkMove、all、none和uninitialized(默认值,等同于all,即允许一切操作)。
  3. files:包含一个FileList对象,表示拖放所涉及的文件,主要用于处理从文件系统拖入浏览器的文件。
  4. types:储存在DataTransfer对象的数据的类型。

方法有

  1. setData(format, data):在dataTransfer对象上储存数据。第一个参数format用来指定储存的数据类型,比如text、url、text/html等。
  2. getData(format):从dataTransfer对象取出数据。
  3. clearData(format):清除dataTransfer对象所储存的数据。如果指定了format参数,则只清除该格式的数据,否则清除所有数据。
  4. setDragImage(imgElement, x, y):指定拖动过程中显示的图像。默认情况下,许多浏览器显示一个被拖动元素的半透明版本。参数imgElement必须是一个图像元素,而不是指向图像的路径,参数x和y表示图像相对于鼠标的位置。

# Web Workers API

Javascript是单线程的。因此,持续时间较长的计算,回阻塞UI线程,进而导致无法在文本框中填入文本,单击按钮等,并且在大多数浏览器中,除非控制权返回,否则无法打开新的标签页。该问题的解决方案是Web Workers,可以让Web应用程序具备后台处理能力,对多线程的支持性非常好。

但是在Web Workers中执行的脚本不能访问该页面的window对象,也就是Web Workers不能直接访问Web页面和DOM API。虽然Web Workers不会导致浏览器UI停止响应,但是仍然会消耗CPU周期,导致系统反应速度变慢。

# Web Storage API

Web Storage是html5引入的一个非常重要的功能,可以在客户端本地存储数据,类似html4的cookie,但可实现功能要比cookie强大的多。

# sessionStorage

sessionStorage将数据保存在session中,浏览器关闭数据就消失。

# localStorage

localStorage则一直将数据保存在客户端本地,除非手动删除,否则一直保存。 不管是sessionStorage,还是localStorage,可使用的API相同,常用的有如下几个(以localStorage为例):

  1. 保存数据:localStorage.setItem(key,value);
  2. 读取数据:localStorage.getItem(key);
  3. 删除单个数据:localStorage.removeItem(key);
  4. 删除所有数据:localStorage.clear();
  5. 得到某个索引的key:localStorage.key(index);
localStorage.getItem('name'); // 获取 name 的值
localStorage.setItem('name', 'jsliang'); // 设置 name 的值为 jsliang
localStorage.removeItem('name'); // 删除 name 的值
1
2
3
  • cookies:存储于浏览器端的数据。可以设置 cookies 的到期时间,如果不设置时间,则在浏览器关闭窗口的时候会消失。
  • session:存储于服务器端的数据。session 存储特定用户会话所需的属性和配置信息
  • cookiessession 的区别在于:
    • cookies 数据存放在客户的浏览器上,session 数据存放在服务器上。
    • cookies 可能会被黑客利用作数据欺骗。所以重要信息记得存 session。
    • session 如果在生效期内量过大,会占用服务器性能。
    • 单个 cookies 保存的数据不能超过 4 K,很多浏览器限制一个站点保存最多 20 个 cookies。

  • sessionStorage:生命周期存在于标签页或窗口,用于本地存储一个会话(session)中的数据,这些数据会随着窗口或者标签页的关闭而被清空。
  • localStorage:生命周期是永久的,除非用户主动清除浏览器上存储的 localStorage 信息,否则它将会永久存在。
  • sessionStoragelocalStorage 操作方法:setItemgetItem 以及 removeItem

cookies,sessionStorage和localStorage区别

名称 生命期 大小限制 与服务器通信
cookie 一般由服务器生成,可设置失效时间。如果在浏览器端生成Cookie,默认是关闭浏览器后失效 4KB 每次都会携带在HTTP头中,如果使用cookie保存过多数据会带来性能问题
sessionStorage 仅在当前会话下有效,关闭页面或浏览器后被清除 5MB 仅在浏览器中保存,不与服务器通信
localStorage 除非被清除,否则永久保存 5MB 仅在浏览器中保存,不与服务器通信
  • 相同点:存储在客户端
  • 存储大小: cookie数据大小不能超过4k。 sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大
  • 有期时间
    • cookie 设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭
    • localStorage 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据
    • sessionStorage 数据在当前浏览器窗口关闭后自动删除
  • 数据与服务器之间的交互方式
    • cookie的数据会自动的传递到服务器,服务器端也可以写cookie到客户端
    • sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存
  • 作用范围
    • cookie只属于某个路径下,需要设置路径,同源窗口共享,
    • sessionStorage不在不同的浏览器窗口中共享,localStorage 在所有同源窗口中都是共享的

![](~/20-32-06.jpg)

# 多个标签页之间的通信

# 如何实现浏览器内多个标签页之间的通信

  • localstorage、 cookies 等本地存储方式
  • 使用url带参数做页面间的跳转
  • 可以把数据传给后端,在另一个页面再去请求后端的接口拿数据

# 基于 Localstorage 设计一个 1M 的缓存系统,需要实现缓存淘汰机制

设计思路如下:详细实现见自己代码库;

  • 存储的每个对象需要添加两个属性:分别是过期时间和存储时间
  • 利用一个属性保存系统中目前所占空间大小,每次存储都增加该属性。当该属性值大于 1M 时,需要按照时间排序系统中的数据,删除一定量的数据保证能够存储下目前需要存储的数据。
  • 每次取数据时,需要判断该缓存数据是否过期,如果过期就删除
class Store {
  constructor() {
    let store = localStorage.getItem('cache')
    if (!store) {
      store = {
        maxSize: 1024 * 1024,
        size: 0
      }
      this.store = store
    } else {
      this.store = JSON.parse(store)
    }
  }
  set(key, value, expire) {
    this.store[key] = {
      date: Date.now(),
      expire,
      value
    }
    let size = this.sizeOf(JSON.stringify(this.store[key]))
    if (this.store.maxSize < size + this.store.size) {
      console.log('超了-----------');
      var keys = Object.keys(this.store);
      // 时间排序
      keys = keys.sort((a, b) => {
        let item1 = this.store[a], item2 = this.store[b];
        return item2.date - item1.date;
      });
      while (size + this.store.size > this.store.maxSize) {
        let index = keys[keys.length - 1]
        this.store.size -= this.sizeOf(JSON.stringify(this.store[index]))
        delete this.store[index]
      }
    }
    this.store.size += size
    localStorage.setItem('cache', JSON.stringify(this.store))
  }
  get(key) {
    let d = this.store[key]
    if (!d) {
      console.log('找不到该属性');
      return
    }
    if (d.expire > Date.now) {
      console.log('过期删除');
      delete this.store[key]
      localStorage.setItem('cache', JSON.stringify(this.store))
    } else {
      return d.value
    }
  }
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

# cookie处理

创建cookie的最简单方法是为document.cookie对象分配一个字符串值,如下所示:

document.cookie = "key1 = value1; key2 = value2; expires = date";
1
# 读取cookie

读取cookie就像写入cookie一样简单,因为document.cookie对象的值是cookie

  • document.cookie的值是由分号分隔的name=value对的列表,其中name是cookie的名称,value是其字符串值。
  • 可以使用split()方法将字符串分解为键和值。

如果要删除cookie以便后续尝试读取cookie,则只需将过期日期设置为过去的时间。 咱们应该定义cookie路径以确保删除正确的cookie。 如果未指定路径,某些浏览器将不允许咱们删除cookie

# HTML5的离线储存(Manifest)

在用户没有与因特网连接时,可以正常访问站点或应用,在用户与因特网连接时,更新用户机器上的缓存文件。

# 原理

HTML5的离线存储是基于一个新建的.appcache文件的缓存机制(不是存储技术),通过这个文件上的解析清单离线存储资源,这些资源就会像cookie一样被存储了下来。之后当网络在处于离线状态下时,浏览器会通过被离线存储的数据进行页面展示。

对HTML5的离线储存资源进行管理和加载

在线的情况下,浏览器发现html头部有manifest属性,它会请求manifest文件,如果是第一次访问app,那么浏览器就会根据manifest文件的内容下载相应的资源并且进行离线存储。如果已经访问过app并且资源已经离线存储了,那么浏览器就会使用离线的资源加载页面,然后浏览器会对比新的manifest文件与旧的manifest文件,如果文件没有发生改变,就不做任何操作,如果文件改变了,那么就会重新下载文件中的资源并进行离线存储。 离线的情况下,浏览器就直接使用离线存储的资源。 ![](~/18-29-30.jpg)

# 特点
  • 离线浏览: 用户可以在离线状态下浏览网站内容。
  • 更快的速度: 因为数据被存储在本地,所以速度会更快.
  • 减轻服务器的负载: 浏览器只会下载在服务器上发生改变的资源。
# 使用

1、页面头部像下面一样加入一个manifest的属性; <html lang="en" manifest="cache.manifest"> 2、在cache.manifest文件的编写离线存储的资源;

CACHE MANIFEST
#changelogdatestamp
/index.php/jsapi/analytics
/log/analytics.js

NETWORK:
*
1
2
3
4
5
6
7

3、在离线状态时,操作window.applicationCache进行需求实现。

cache = window.applicationCache;
window.applicationCache.addEventListener('updateready', function() {
  window.applicationCache.swapCache();
  console.log('swap cache has been called');
}, false);
1
2
3
4
5

# IndexedDB

# 简介

IndexedDB 就是浏览器提供的本地数据库,它可以被网页脚本创建和操作。IndexedDB 允许储存大量数据,提供查找接口,还能建立索引。这些都是 LocalStorage 所不具备的。就数据库类型而言,IndexedDB 不属于关系型数据库(不支持 SQL 查询语句),更接近 NoSQL 数据库。

IndexedDB 具有以下特点。

(1)键值对储存。 IndexedDB 内部采用对象仓库(object store)存放数据。所有类型的数据都可以直接存入,包括 JavaScript 对象。对象仓库中,数据以"键值对"的形式保存,每一个数据记录都有对应的主键,主键是独一无二的,不能有重复,否则会抛出一个错误。

(2)异步。 IndexedDB 操作时不会锁死浏览器,用户依然可以进行其他操作,这与 LocalStorage 形成对比,后者的操作是同步的。异步设计是为了防止大量数据的读写,拖慢网页的表现。

(3)支持事务。 IndexedDB 支持事务(transaction),这意味着一系列操作步骤之中,只要有一步失败,整个事务就都取消,数据库回滚到事务发生之前的状态,不存在只改写一部分数据的情况。

(4)同源限制 IndexedDB 受到同源限制,每一个数据库对应创建它的域名。网页只能访问自身域名下的数据库,而不能访问跨域的数据库。

(5)储存空间大 IndexedDB 的储存空间比 LocalStorage 大得多,一般来说不少于 250MB,甚至没有上限

(6)支持二进制储存。 IndexedDB 不仅可以储存字符串,还可以储存二进制数据(ArrayBuffer 对象和 Blob 对象)。

# 操作

# 打开数据库
var request = window.indexedDB.open(databaseName, version);
request.onerror = function (event) {
  console.log('数据库打开报错');
};
var db;
request.onsuccess = function (event) {
  db = request.result;
  console.log('数据库打开成功');
};
//如果指定的版本号,大于数据库的实际版本号,就会发生数据库升级事件upgradeneeded。
request.onupgradeneeded = function (event) {
  db = event.target.result;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
# 新建数据库

通常,新建数据库以后,第一件事是新建对象仓库(即新建表)。数据库新建成功以后,新增一张叫做person的表格,主键是id

request.onupgradeneeded = function (event) {
  db = event.target.result;
  var objectStore;
  if (!db.objectStoreNames.contains('person')) {
    objectStore = db.createObjectStore('person', { keyPath: 'id' });
  }
}
//如果数据记录里面没有合适作为主键的属性,那么可以让 IndexedDB 自动生成主键。
var objectStore = db.createObjectStore(
  'person',
  { autoIncrement: true }
);

//新建对象仓库以后,下一步可以新建索引。
request.onupgradeneeded = function(event) {
  db = event.target.result;
  var objectStore = db.createObjectStore('person', { keyPath: 'id' });
  objectStore.createIndex('name', 'name', { unique: false });
  objectStore.createIndex('email', 'email', { unique: true });
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 新增数据

新增数据指的是向对象仓库写入数据记录。这需要通过事务完成。

function add() {
  var request = db.transaction(['person'], 'readwrite')
    .objectStore('person')
    .add({ id: 1, name: '张三', age: 24, email: 'zhangsan@example.com' });
  request.onsuccess = function (event) {
    console.log('数据写入成功');
  };
  request.onerror = function (event) {
    console.log('数据写入失败');
  }
}
add();
1
2
3
4
5
6
7
8
9
10
11
12

上面代码中,写入数据需要新建一个事务。新建时必须指定表格名称和操作模式("只读"或"读写")。新建事务以后,通过IDBTransaction.objectStore(name)方法,拿到 IDBObjectStore 对象,再通过表格对象的add()方法,向表格写入一条记录。

写入操作是一个异步操作,通过监听连接对象的success事件和error事件,了解是否写入成功。

# 读取数据

读取数据也是通过事务完成。 objectStore.get()方法用于读取数据,参数是主键的值。

function read() {
   var transaction = db.transaction(['person']);
   var objectStore = transaction.objectStore('person');
   var request = objectStore.get(1);
   request.onerror = function(event) {
     console.log('事务失败');
   };
   request.onsuccess = function( event) {
      if (request.result) {
        console.log('Name: ' + request.result.name);
        console.log('Age: ' + request.result.age);
        console.log('Email: ' + request.result.email);
      } else {
        console.log('未获得数据记录');
      }
   };
}
read();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 遍历数据

遍历数据表格的所有记录,要使用指针对象 IDBCursor。新建指针对象的openCursor()方法是一个异步操作,所以要监听success事件。

function readAll() {
  var objectStore = db.transaction('person').objectStore('person');

   objectStore.openCursor().onsuccess = function (event) {
     var cursor = event.target.result;
     if (cursor) {
       console.log('Id: ' + cursor.key);
       console.log('Name: ' + cursor.value.name);
       console.log('Age: ' + cursor.value.age);
       console.log('Email: ' + cursor.value.email);
       cursor.continue();
    } else {
      console.log('没有更多数据了!');
    }
  };
}
readAll();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 更新数据

更新数据要使用IDBObject.put()方法。 put()方法自动更新了主键为1的记录。

function update() {
  var request = db.transaction(['person'], 'readwrite')
    .objectStore('person')
    .put({ id: 1, name: '李四', age: 35, email: 'lisi@example.com' });
  request.onsuccess = function (event) {
    console.log('数据更新成功');
  };
  request.onerror = function (event) {
    console.log('数据更新失败');
  }
}
update();
1
2
3
4
5
6
7
8
9
10
11
12
# 删除数据

IDBObjectStore.delete()方法用于删除记录。

function remove() {
  var request = db.transaction(['person'], 'readwrite')
    .objectStore('person')
    .delete(1);

  request.onsuccess = function (event) {
    console.log('数据删除成功');
  };
}
remove();
1
2
3
4
5
6
7
8
9
10
# 使用索引

索引的意义在于,可以让你搜索任意字段,也就是说从任意字段拿到数据记录。如果不建立索引,默认只能搜索主键(即从主键取值)。

假定建表的时候name字段建立了索引。 objectStore.createIndex('name', 'name', { unique: false });

现在,就可以从name找到对应的数据记录了。

var transaction = db.transaction(['person'], 'readonly');
var store = transaction.objectStore('person');
var index = store.index('name');
var request = index.get('李四');
request.onsuccess = function (e) {
  var result = e.target.result;
  if (result) {
    // ...
  } else {
    // ...
  }
}
1
2
3
4
5
6
7
8
9
10
11
12

# 与nedb的比较

db.js常用操作封装

const DB = require('nedb-promise')
const fse = require('fs-extra')
const routePath = `${process.cwd()}/db/route.db`
fse.ensureFileSync(routePath)
module.exports = app => {
  const Route = new DB({
    filename: routePath,
    timestampData: true,
    autoload: true
  })
  Route.ensureIndex({ fieldName: 'host' }, err => {
    if (err) {
      console.log('ensureIndex-error--:', err)
    }
  })
  Route.findOneOrUpdate = async function (query, data) {
    const doc = await Route.findOne(query)
    if (!doc) {
      return Route.insert(data)
    } else {
      delete data._id
      await Route.update(query, { $set: data })
      return doc
    }
  }
  app.db = {Route}
}
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

# html结构

HTML 属于结构层,负责描绘出内容的结构。 CSS 属于表示层,负责如何显示有关内容。 JavaScript 属于行为层,负责内容应如何对事件做出反应。

# 常见浏览器及其内核

Chrome Firefox Safari IE,TT, 360 Opera
内核 Blink(WebKit的分支) Gecko Webkit Trident 原为:Presto,现为:Blink
JS 引擎 V8 SpiderMonkey Nitro Chakra V8

国内一些浏览器使用较多的是 Webkit 内核(快速版本)

  • 针对不同浏览器内核,HTML 辨别:
  1. IE 内核浏览器识别:<!--[if IE]><![endif]-->
  2. 非 IE 内核浏览器识别:<!--[if !IE]><![endif]-->
  • 针对不同浏览器内核,CSS 辨别:
/* 设置文字不可选取 */
* {
  -moz-user-select: none; /* 火狐 浏览器 */
  -webkit-user-select: none; /* Webkit 浏览器 */
  -o-user-select: none; /* Opera 浏览器 */
  -ms-user-select: none; /* IE10 浏览器 */
  -khtml-user-select: none; /* 早期浏览器 */
  user-select: none; /* 默认 */
}
1
2
3
4
5
6
7
8
9

# 浏览器内核的理解

渲染引擎和JS引擎

  • 渲染引擎:负责取得网页的内容、整理讯息,以及计算网页的显示方式
  • JS引擎:解析和执行js来实现网页的动态效果

主要分成两部分:渲染引擎(layout engineer或Rendering Engine) 和 JS引擎

最开始渲染引擎和JS引擎并没有区分的很明确,后来JS引擎越来越独立,内核就倾向于只指渲染引擎

# 兼容性处理,兼容H5

# 支持HTML5新标签

  • IE8/IE7/IE6支持通过document.createElement方法产生的标签,可以利用这一特性让这些浏览器支持HTML5新标签,浏览器支持新标签后,还需要添加标签默认的样式。

  • 当然也可以直接使用成熟的框架、比如html5shim;

<!--[if lt IE 9]>
    <script> src="http://html5shim.googlecode.com/svn/trunk/html5.js"</script>
<![endif]-->
1
2
3

# 如何区分HTML5

DOCTYPE声明\新增的结构元素\功能元素

# 如何判断当前运行在浏览器还是 node 环境中

通过判断 Global 对象是否为 window ,如果不为 window ,当前脚本没有运行在浏览器中

# http-equiv = "X-UA-Compatible"的意思

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11

在IE8刚推出的时候,很多网页由于重构的问题,无法适应较高级的浏览器,所以使用X-UA-Compatible标签强制IE8采用低版本方式渲染。 使用下面这段代码后,开发者无需考虑网页是否兼容IE8浏览器,只要确保网页在IE6、IE7下的表现就可以了。

<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
1

使用下面这段代码使用的是Edge 。模式Edge 模式告诉 IE 以最高级模式渲染文档,也就是任何 IE 版本都以当前版本所支持的最高级标准模式渲染,避免版本升级造成的影响。简单的说**,就是什么版本 IE 就用什么版本的标准模式渲染。**

<meta http-equiv="X-UA-Compatible" content="IE=edge">
1

使用以下代码强制 IE 使用 Chrome Frame 渲染

<meta http-equiv="X-UA-Compatible" content="chrome=1">
1

最佳的兼容模式方案:

<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
1

# 移动端的兼容考虑

# 实践题

# webkit表单输入框placeholder的文字能换行么

ios可以,android不行~; 在textarea标签下都可以换行~

# 打电话发短信写邮件怎么实现

<a href="tel:0755-10086">打电话给:0755-10086</a> //打电话 
<a href="sms:10086">发短信给: 10086</a>  //发短信,winphone系统无 效    
<a href=“mailto:baidu@foxmail.com">baidu@foxmail.com</a>//写邮件   
1
2
3

# 开启硬件加速

1,解决页面闪白 2,保证动画流畅

.css {
    -webkit-transform: translate3d(0, 0, 0);
    -moz-transform: translate3d(0, 0, 0);
    -ms-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
}
1
2
3
4
5
6

# H5页面窗口自动调整到设备宽度,并禁止用户缩放页面

<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
1

# 忽略将页面中的数字识别为电话号码

<meta name="format-detection" content="telephone=no" />
1

# 忽略Android中对邮箱地址的识别

<meta name="format-detection" content="email=no" />
1

# ios系统中去掉元素被触摸时产生的半透明灰色遮罩

a,button,input,textarea{-webkit-tap-highlight-color: rgba(0,0,0,0;)}
1

# ios中去掉默认input默认样式

input,button,textarea{-webkit-appearance: none;}
1

# fixed在移动端的坑

  • fixed在某些情况下可能导致容器内的子元素的1px边框线消失,即使使用z-index也无法解决。 解决方法:可以使用translateZ属性来解决
  • fixed定位的容器内不能带有input,这是常见的bug。 解决方法: 在input聚焦的时候去掉fixed定位状态,改为absolute。
  • fixed+可滚动的容器内会导致fixed定位的子元素在滚动时定位失效,滚动完成后才正常回到fixed的位置。 解决方法:尽量不要在可滚动的容器内包含fixed定位的子元素。
  • ios不支持onresize事件

# 问题

# 参考链接

http://www.ruanyifeng.com/blog/2018/07/indexeddb.html

上次更新: 2022/04/15, 05:41:26
×