HTML5与移动端web学习笔记

概述

HTML5 提供了很多新的功能,主要有:

新的 HTML 元素,例如 section, nav, header, footer, article 等
用于绘画的 Canvas 元素
用于多媒体播放的 video 和 audio 元素
用于定位的 Geolocation API
本地存储以及离线应用
Web Workers、Web WebSocket API

移动前端开发可分为:

  1. 手机网页开发。这部分跟web前端开发差别不大,使用的技术都是html+css+js。区别为手机浏览器是webkit的天下,pc端是IE的天下。
  2. app前端开发。使用的技术也是html+css+js,但它需要基于PhoneGapReact Native等开发平台调用手机核心功能接口(包括地理定位,加速器,联系人,声音和振动等)模拟native app,这部分跟web前端开发完全不同。最终代码发布要分别编译成各系统平台的app

canvas

canvas部分请参考:http://segmentfault.com/a/119...

drag and drop(拖拽)

拖拽元素事件 : 事件对象为被拖拽元素

dragstart :  拖拽前触发 
drag :拖拽前、拖拽结束之间,连续触发
dragend  : 拖拽结束触发

目标元素事件 : 事件对象为目标元素

dragenter :  进入目标元素触发,相当于mouseover
dragover : 进入目标、离开目标之间,连续触发
dragleave :  离开目标元素触发,相当于mouseout
drop  :  在目标元素上释放鼠标触发

事件的执行顺序 :drop不触发的时候

dragstart  >  drag >  dragenter >  dragover >  dragleave > dragend 

事件的执行顺序 :drop触发的时候(dragover的时候阻止默认事件)

dragstart  >  drag >  dragenter >  dragover >  drop > dragend

解决火狐下的问题

火狐浏览器下必须设置dataTransfer对象的setData方法才可以拖拽除图片外的其他标签。

dataTransfer属性和方法

    属性                描述
    dropEffect         设置或获取拖曳操作的类型和要显示的光标类型。
    effectAllowed      设置光标样式(none, copy, copyLink, copyMove, link, linkMove, move, all 和 uninitialized)

    setDragImage    三个参数:指定的元素,坐标X,坐标Y
    files           获取外部拖拽的文件,返回一个filesList列表。filesList下有个type属性,返回文件的类型


    方法              描述
    clearData     通过 dataTransfer 或 clipboardData 对象从剪贴板删除一种或多种数据格式。
    
    setData() : 设置数据 key和value(必须是字符串)

    getData() : 获取数据,根据key值,获取对应的value

只有加阻止默认事件才可以触发drop

 oDiv.ondragover = function(ev){  //只有加阻止默认事件才可以触发drop
        ev.preventDefault();
    };   

drag and drop的浏览器支持情况:
图片描述

HTML5实现拖拽上传预览图片:

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>无标题文档</title>
    <style type="text/css">
        #div1{
            margin: 0 auto;
            width:200px;
            height:200px;
            background:#ccc;
            color: white;}
        #div1 p{
            position: relative;
            top: 90px;
            left: 50px;
        }
        li{ width:200px; height:200px; margin:5px; float:left; list-style:none;}
        li img{ width:500px;height: auto}
    </style>
    <script type="text/javascript">

        window.onload = function(){

            var oUl = document.getElementById('ul1');
            var oDiv = document.getElementById('div1');

            oDiv.ondragenter = function(){
                this.innerHTML = '可以释放';
            };

            oDiv.ondragover = function(ev){
                ev.preventDefault();
            };

            oDiv.ondragleave = function(){
                this.innerHTML = '请拖拽到此区域';
            };

            oDiv.ondrop = function(ev){

                ev.preventDefault();

                var fs = ev.dataTransfer.files;

                for(var i=0;i<fs.length;i++){

                    var fr = new FileReader();

                    if( fs[i].type.indexOf('image')!=-1 ){

                        fr.readAsDataURL( fs[i] );

                        fr.onload = function(){
                            var oLi = document.createElement('li');
                            var oImg = document.createElement('img');
                            oImg.src = this.result;
                            oLi.appendChild( oImg );
                            oUl.appendChild( oLi );
                        };
                    }
                    else{
                        alert('亲,请拖拽图片格式');
                    }

                }

            };

        };
    </script>
</head>
<body>
<div id="div1"><p>请拖拽到此区域</p></div>
<ul id="ul1"></ul>
</body>

FileReader(读取文件信息)

| 属性名 | 描述 |
| ------------- |:-------------:|
| error | 在读取文件时发生的错误. 只读. |
| readyState | 表明FileReader对象的当前状态. |
| result | 读取到的文件内容。这个属性只在读取操作完成之后才有效 |

<br/>

| 方法名 | 描述 |
| ------------- |:----------:|
| abort | 中止该读取操作.在返回时,readyState属性的值为DONE. |
| readAsArrayBuffer |将File对象F读取为一个 ArrayBuffer 对象。|
| readAsBinaryString | 将File对象F读取为一个二进制字符串。 |
|readAsDataURL |将File对象F读取为编码过的数据URL。|
|readAsText(File f, [encoding])|读取 File对象F并赋予一个字符串。|

创建一个FileReader对象:

var reader = new FileReader();

Web Worker和缓存

Web Worker的基本原理就是在当前js的主线程中,使用Worker类加载一个js文件来开辟一个新的线程,起到互不阻塞执行的效果,并且提供主线程和新线程之间数据交换的接口:postMessage,onmessage

主机 workerworker 脚本可以通过 postMessage 发送消息并使用 onmessage 事件侦听响应。消息的内容作为事件的数据属性进行发送。

var worker = new Worker('worker.js');
worker.onmessage = function(e) {
  alert(e.data);
};

worker主线程:

1.通过 worker = new Worker( url ) 加载一个JS文件来创建一个worker,同时返回一个worker实例。

2.通过worker.postMessage( data ) 方法来向worker发送数据。

3.绑定worker.onmessage方法来接收worker发送过来的数据。

4.可以使用 worker.terminate() 来终止一个worker的执行。

worker新线程:

1.通过postMessage( data ) 方法来向主线程发送数据。

2.绑定onmessage方法来接收主线程发送过来的数据。

例子:计数功能

首先创建一个index.html文件

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script type="text/javascript" src="index.js"></script>
</head>
<body>
<div id="numDiv">0</div>
<button type="button" id="start">start</button>
<button type="button" id="stop">stop</button>
</body>
</html>

其次,创建一个count.js文件:

var countNum = 0;
function count(){
    postMessage(countNum);
    countNum++;
    setTimeout(count,1000);
}

count();

再创建一个index.js文件

var numDiv;
var work = null;
window.onload = function () {
    numDiv = document.getElementById('numDiv');

    document.getElementById('start').onclick = startWorker;
    document.getElementById('stop').onclick = function () {
        if(work){
            work.terminate();//停止,释放掉资源
            work = null;//work重新初始化
        }
    };

};
function startWorker(){
    if(work){
        return;
    }
    work = new Worker('count.js');
    work.onmessage = function (e) {
        numDiv.innerHTML = e.data;
    };
}

图片描述

Web SQL

三个核心方法:

1、openDatabase:这个方法使用现有数据库或创建新数据库创建数据库对象。

2、transaction:这个方法允许我们根据情况控制事务提交或回滚。

3、executeSql:这个方法用于执行真实的SQL查询。 

浏览器的本地数据库占用资源少,处理速度快。
openDatabase方法打开一个已经存在的数据库,如果数据库不存在,它还可以创建数据库,创建并打开数据库的语法如下:

var db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);

参数为:数据库名(mydb)、版本号(1.0)、描述(Test DB)和数据库大小(2*1024*1024)以及创建回调函数

WebSockets

TCP是因特网的基础传输协议,而WebSocketWeb应用程序的传输协议,它提供了双向的,按序到达的数据流。WebSocket连接的是URL,而非因特网上的主机和端口。

 // 创建一个Socket实例
var socket = new WebSocket('ws://localhost:8080');

// 打开Socket
socket.onopen = function(ev) {

    // 发送一个初始化消息
    socket.send('hello HTML5');

    // 监听消息
    socket.onmessage = function(ev) {
        console.log('Client received a message',ev);
    };

    // 监听Socket的关闭
    socket.onclose = function(ev) {
        console.log('Client notified socket has closed',ev);
    };

    // 关闭Socket....
    socket.close()
};

http协议使用http://开头一样,WebSocket协议的URL使用ws://开头,而安全的WebSocket协议使用wss://开头。

HTTP协议通常承载于TCP协议之上,有时也承载于TLSSSL协议层之上,这个时候,就成了我们常说的HTTPS
图片描述
默认HTTP的端口号为80HTTPS的端口号为443

getUserMedia API

navigator.getUserMedia可以提示用户需要权限去使用像摄像头或麦克风之类的媒体设备.
下面是一个获取用户摄像头并提供拍照功能的例子:

<body>
<video id="video" width="640" height="480" autoplay></video>
<button id="snap">Snap Photo</button>
<canvas id="canvas" width="640" height="480"></canvas>
<script type="text/javascript">

    // 添加事件监听器
    window.addEventListener("DOMContentLoaded", function() {
        // 获取元素,创建设置等等
        var canvas = document.getElementById("canvas"),
                context = canvas.getContext("2d"),
                video = document.getElementById("video"),
                videoObj = { "video": true },
                errBack = function(error) {
                    console.log("Video capture error: ", error.code);
                };

        // 添加video 监听器
        if(navigator.getUserMedia) { // 标准
            navigator.getUserMedia(videoObj, function(stream) {
                video.src = stream;
                video.play();
            }, errBack);
        } else if(navigator.webkitGetUserMedia) { // WebKit 前缀
            navigator.webkitGetUserMedia(videoObj, function(stream){
                video.src = window.webkitURL.createObjectURL(stream);
                video.play();
            }, errBack);
        }
        else if(navigator.mozGetUserMedia) { // Firefox 前缀
            navigator.mozGetUserMedia(videoObj, function(stream){
                video.src = window.URL.createObjectURL(stream);
                video.play();
            }, errBack);
        }

        document.getElementById("snap").addEventListener("click", function() {
            context.drawImage(video, 0, 0, 640, 480);
        });

    }, false);

</script>
</body>

下面是浏览器兼容性的写法:

<script type = 'text/javascript'>
    navigator.getMedia = ( navigator.getUserMedia ||
        navigator.webkitGetUserMedia ||
        navigator.mozGetUserMedia ||
        navigator.msGetUserMedia);
</script>

浏览器对象

图片描述

audio和video

下图是audiovideo的属性及其浏览器的兼容性:
图片描述

Fullscreen API

进入全屏模式

// 找到正确的方法  
function launchFullScreen(element) {  
  if(element.requestFullScreen) {  
    element.requestFullScreen();  
  } else if(element.mozRequestFullScreen) {  
    element.mozRequestFullScreen();  
  } else if(element.webkitRequestFullScreen) {  
    element.webkitRequestFullScreen();  
  }  
}  
  
// 启动全屏模式  
launchFullScreen(document.documentElement); // 整个页面  
launchFullScreen(document.getElementById("videoElement")); // 单独元素 

退出全屏模式

function cancelFullscreen() {  
  if(document.cancelFullScreen) {  
    document.cancelFullScreen();  
  } else if(document.mozCancelFullScreen) {  
    document.mozCancelFullScreen();  
  } else if(document.webkitCancelFullScreen) {  
    document.webkitCancelFullScreen();  
  }  
}  
  
// 取消全屏  
cancelFullscreen();   

全屏属性和事件

document.fullScreenElement:当前全屏显示的元素。
document.fullScreenEnabled:判断浏览器是否支持全屏。
fullscreenchange事件:全屏状态改变事件。

History API

HTML5 更新了两个API,无刷新更新地址 history.pushState方法和history.replaceState 方法

Geolocation API

Geolocation API 是通过window.navigator.geolocation 获得对地理定位的访问的。该对象有如下三个方法:

getCurrentPosition()
watchPosition()
clearWatch()

图片描述

表单元素

HTML5 新增了很多表单元素让开发者构建更优秀的 Web 应用程序。以下是HTML5新增的表单元素

datalist
datetime
output
keygen 
date 
month 
week
time
color
number 
range 
email 
url

图片描述

html5移动端优化

PC端的优化对于移动端同样适用,Android同时支持4个并发请求,iOS 5后可支持6个,所以,应尽量减少http请求数

图片描述

1. PC优化手段在Mobile侧同样适用
2. 在Mobile侧我们提出三秒种渲染完成首屏指标
3. 基于第二点,首屏加载3秒完成或使用Loading
4. 基于联通3G网络平均338KB/s(2.71Mb/s),所以首屏资源不应超过1014KB
5. Mobile侧因手机配置原因,除加载外渲染速度也是优化重点
6. 基于第五点,要合理处理代码减少渲染损耗
7. 基于第二、第五点,所有影响首屏加载和渲染的代码应在处理逻辑中后置
8. 加载完成后用户交互使用时也需注意性能

图片描述

不滥用Float

Float在渲染时计算量比较大,尽量减少使用

不滥用Web字体

Web字体需要下载,解析,重绘当前页面,尽量减少使用

不声明过多的Font-size

过多的Font-size引发CSS树的效率

减少重绘和回流

a) 避免不必要的Dom操作
b) 尽量改变Class而不是Style,使用classList代替className
c) 避免使用document.write
d) 减少drawImage

Viewport可以加速页面的渲染,请使用以下代码

< meta name=”viewport” content=”width=device-width, initial-scale=1″>

动画优化

a) 尽量使用CSS3动画
b) 合理使用requestAnimationFrame动画代替setTimeout
c) 适当使用Canvas动画 5个元素以内使用css动画,5个以上使用Canvas动画(iOS8可使用webGL)


GPU加速

CSS中以下属性(CSS3 transitions、CSS3 3D transforms、Opacity、Canvas、WebGL、Video)来触发GPU渲染,请合理使用
PS:过渡使用会引发手机过耗电增加
资料参考:
如何做到一秒渲染一个移动页面
HTML5与CSS3语法提供浏览器兼容性测试及使用建议:http://html5please.com/

meta相关总结

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

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

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

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

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

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

当网站添加到主屏幕快速启动方式,可隐藏地址栏,仅针对iossafari

    <meta name="apple-mobile-web-app-capable" content="yes" />
    <!-- ios7.0版本以后,safari上已看不到效果 -->

将网站添加到主屏幕快速启动方式,仅针对iossafari顶端状态条的样式

<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<!-- 可选default、black、black-translucent -->

移动端touch事件(区分webkit 和 winphone)

当用户手指放在移动设备在屏幕上滑动会触发的touch事件

以下支持webkit

touchstart——当手指触碰屏幕时候发生。不管当前有多少只手指
touchmove——当手指在屏幕上滑动时连续触发。通常我们再滑屏页面,会调用event的preventDefault()可以阻止默认情况的发生:阻止页面滚动
touchend——当手指离开屏幕时触发
touchcancel——系统停止跟踪触摸时候会触发。例如在触摸过程中突然页面alert()一个提示框,此时会触发该事件,这个事件比较少用

以下支持windows phone 8

MSPointerDown——当手指触碰屏幕时候发生。不管当前有多少只手指
MSPointerMove——当手指在屏幕上滑动时连续触发。通常我们再滑屏页面,会调用css的html{-ms-touch-action: none;}可以阻止默认情况的发生:阻止页面滚动
MSPointerUp——当手指离开屏幕时触发

手机拍照和上传图片

<input type="file">accept 属性

<!-- 选择照片 -->
<input type=file accept="image/*">
<!-- 选择视频 -->
<input type=file accept="video/*">

使用总结:

ios 有拍照、录像、选取本地图片功能
部分android只有选取本地图片功能
winphone不支持
input控件默认外观丑陋


移动端手势总结

主要用户操作

图片描述

手势的具体操作

图片描述

触摸屏手势

图片描述

手势的具体操作

图片描述

to be continued。。。


30.2k 声望
4.7k 粉丝
0 条评论
推荐阅读
谈谈react hooks UI与业务逻辑分离的必要性与技术方案
当前端业务复杂度上升到一定程度的时候,如何提升前端代码质量便成了老生常谈的话题。似乎前端总逃不开改他人代码,重构,修复bug的宿命。那么,我们要如何从项目代码层面,改变这一局面呢?才能保证项目A之于开...

trigkit41阅读 729

CSS transition 小技巧!如何保留 hover 的状态?
欢迎关注我的公众号:前端侦探通常情况下,hover 是无法保存状态的。鼠标移入触发额外样式,一旦移出就还原了 {代码...} 这就意味着,如果需要保留hover的状态,可能就不得不借助JS了,比如下面是某某书院的首页...

XboxYan30阅读 4k评论 2

封面图
由小见大!不规则造型按钮解决方案
今天,有个群友在群里提问,使用 CSS 能否实现下述这个图形:emmm,中间这个酷似三次贝塞尔曲线的造型,使用 CSS 不太好实现。我的建议是切图实现,然而群友要求一定要用 CSS 实现。虽然麻烦,但是这个图形勉强也...

chokcoco17阅读 1.3k

封面图
CSS 如何让auto height完美支持过渡动画?
欢迎关注我的公众号:前端侦探众所周知,高度在设置成auto关键词时是不会触发transition过渡动画的,下面是伪代码 {代码...} 效果如下如果希望展开时有过渡动画,例如这样通常是借助 JS 动态去获取元素的高度(还...

XboxYan17阅读 1.3k评论 2

封面图
vh 存在问题?试试动态视口单位之 dvh、svh、lvh
大部分同学都知道,在 CSS 世界中,有 vw、vh、vmax、vmin 这几个与视口 Viewport 相关的单位。正常而言:1vw 等于1/100的视口宽度 (Viewport Width)1vh 等于1/100的视口高度 (Viewport Height)vmin — vmin ...

chokcoco13阅读 1.4k评论 2

CSS 奇思妙想之酷炫倒影
在 CSS 中,倒影是一种比较常见的效果。今天,我们就将尝试,使用 CSS 完成各类不同的倒影效果,话不多说,直接进入主题。实现倒影的两种方式首先,快速过一下在 CSS 中,实现倒影的 2 种方式。使用 -webkit-box-...

chokcoco14阅读 1.9k评论 1

那些不用js也能实现的效果
本文首发于公众号:GitWeb,欢迎关注,接收首发推文本文列举几个不需要使用js也能实现的效果一、页面回到顶部回到顶部是页面开发中很常见的一个功能,一般的做法是对回到顶部组件做一个监听,当用户点击的时候,...

阿山10阅读 632评论 4

封面图
30.2k 声望
4.7k 粉丝
宣传栏