文章目录
- autofocus自动聚焦
- 语义化标签
- DOCTYPE声明
- meta
- meta http-equiv
- meta charset的指定
- viewport移动端视口
- 不允许写结束标记的元素
- 可以省略结束标记的标签
- 属性值的简写
- 废弃标签
- contenteditable规定元素内容是否可编辑
- hidden属性
- data-* 属性
- draggable拖拽属性
- dataTranfer数据传输
- requestAnimationFrame请求动画帧
- 会话跟踪和本地存储
- history,hash路由
- classList
- Worker
- FileReader
- WebSocket
- geolocation地理位置
- 设备加速度,设备方向
- tounch事件
- Fetch
- canvas
- 只有矩形,文本,图片可直接绘制
- 路径-线,三角,贝塞尔曲线
- 原点,状态,变换
- 渐变,模糊,透明度
- 圆
- getImageData,putImageData
- globalCompositeOperation
- SVG
- audio,video
autofocus自动聚焦
<form>
<input type="text" id="user" autofocus>
</form>
<script>
// 之前传统js自动聚焦的方法
// document.getElementById('user').focus()
</script>
语义化标签
- 使用语义化标签能够提升可访问性(Accessibility);
- 使用语义化标签有助于 SEO;
- 使用语义化标签利于代码维护。
<header></header>
<!-- 头部 -->
<nav></nav>
<!-- 导航栏 -->
<section></section>
<!-- 区块(有语义化的div) -->
<main></main>
<!-- 主要区域 -->
<article></article>
<!-- 主要内容 -->
<aside></aside>
<!-- 侧边栏 -->
<footer></footer>
<!-- 底部 -->
- article和section的区别
- https://blog.csdn.net/u013205165/article/details/90518020
- article元素代表文档、页面或应用程序中独立的、完整的、可以独自被外部引用的内容。
- article元素可以是一篇博客或报刊中的文章、一篇论坛帖子、一段用户评论 或独立的插件,或其他任何独立的内容。
- 除了内容部分,一个article元素通常有它自己的标题(一般放在一个header元素里面),有时还有自己的脚 注。
- article元素是可以嵌套使用的,内层的内容在原则上需要与外层的内容相关联。例如,一篇博客文章中,针对该文章的评论就可以使用嵌套article元素的方式
- section元素的作用是对页面上的内容进行分块,或者说对文章进行分段
- 一个section元素通常由内容及其标题组成。通常不推荐为那些没有标题的内容使用section元素
<section><h1>PRC</h1><p>The People's Republic of China was born in 1949...</p>
</section><article><header><h1>计算机各类语言介绍</h1></header><p>本文列举了部分计算机语言的一些介绍</p><section><h2>JavaScript</h2><p>js是一门……</p></section><section><h2>HTML</h2><p>HTML是一门……</p></section><footer>版权所有</footer>
</article>
DOCTYPE声明
- 在 HTML 4.01 中,<!DOCTYPE> 声明需引用 DTD (文档类型声明),因为 HTML 4.01 是基于 SGML
- HTML5 不是基于 SGML,因此不要求引用 DTD。
- 提示:总是给您的 HTML 文档添加 <!DOCTYPE> 声明,确保浏览器能够预先知道文档类型。
- 注释:<!DOCTYPE> 标签没有结束标签。
- 提示:<!DOCTYPE> 声明不区分大小写。
<!DOCTYPE html>
meta
meta http-equiv
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<!-- 另外写法 -->
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
X-UA-Compatible确实是为了我们定义浏览器的渲染方式的;
如果存在客户端Chrome Frame并启用,那么浏览器访问页面会被Chrome内核渲染
(这一点没太大意义,因为你开发的项目不能要求用户在客户端来安装Chrome Frame);也就是说IE浏览器变身Chrome是可以的,但前提是客户端安装了Chrome Frame,呵呵;
使用IE内核浏览器来访问,会渲染至该浏览器的最高版本,比如你使用IE9浏览器,那么就算在兼容模式切换至IE7,但仍会渲染成IE9的样子(当然IE7浏览器是不会渲染成IE9的,不然想想都好美丽)。
比如现在我在客户端装了Chrome Frame,然后我的IE浏览器是IE11,也就是说我服务器端已经设置了X-UA-Compatible属性的值为IE=edge,chrome=1,客户端已经安装并启用Chrome Frame。我现在用IE浏览器打开指定网页。
竟然在IE浏览器下看到了审查元素,而且点击审查元素出现了在Chrome下几乎一样的控制台
https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/meta
https://www.cnblogs.com/dreamaker/p/10576750.html
http-equiv顾名思义,相当于http的文件头作用,它可以向浏览器传回一些有用的信息,以帮助正确和精确地显示网页内容,与之对应的属性值为content,content中的内容其实就是各个参数的变量值。
引用
meat标签的http-equiv属性语法格式是:<meta http-equiv=“参数” content="参数变量值"> ;其中http-equiv属性主要有以下几种参数:
meta charset的指定
<head>
<meta charset="UTF-8">
</head>
charset 属性是 HTML5 中的新属性,且替换了:
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
仍然允许使用 http-equiv 属性来规定字符集,但是使用新方法可以减少代码量。
viewport移动端视口
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0,minimum-scale=1.0,user-scalable=0" />
- width 设置layout viewport 的宽度,为一个正整数,使用字符串”width-device”表示设备宽度
- initial-scale 设置页面的初始缩放值,为一个数字,可以带小数
- minimum-scale 允许用户的最小缩放值,为一个数字,可以带小数
- maximum-scale 允许用户的最大缩放值,为一个数字,可以带小数
- height 设置layout viewport 的高度,这个属性对我们并不重要,很少使用
- user-scalable 是否允许用户进行缩放,值为”no”或”yes”, no 代表不允许,yes代表允许
不允许写结束标记的元素
- br
- img
- hr
- input
项目中这两个在head中经常会写/>,实际上没必要写 - link
- meta
可以省略结束标记的标签
- li
如果一个li元素之后紧跟另一个li元素,或在父元素中没有其他更多内容,则结束标签可以省略。
属性值的简写
<p>选中,checked属性只要存在,就会选中,无论其值是什么</p>
<input type="checkbox" checked>
<input type="checkbox" checked="true">
<input type="checkbox" checked="checked">
<input type="checkbox" checked="false">
<p>未选中</p>
<input type="checkbox">
废弃标签
<big> HTML5不再支持。 定义大号文本。
<center> HTML5不再支持。 HTML 4.01 已废弃。定义居中文本。
<font> HTML5不再支持。 HTML 4.01 已废弃。 定义文本的字体、尺寸和颜色
<strike> HTML5不再支持。 HTML 4.01 已废弃。 定义加删除线的文本。
<frame> HTML5不再支持。 定义框架集的窗口或框架。
<frameset> HTML5不再支持。定义框架集。
<noframes> HTML5不再支持。 定义针对不支持框架的用户的替代内容。
<iframe> 定义内联框架。这个仍旧支持
contenteditable规定元素内容是否可编辑
hidden属性
- =display:none
- hidden 属性是 HTML5 中的新属性。
data-* 属性
-
使用 data-* 属性来嵌入自定义数据:
-
data-* 属性由以下两部分组成:
- 属性名不要包含大写字母,在 data- 后必须至少有一个字符。
- 该属性可以是任何字符串
- 注意: 自定义属性前缀 “data-” 会被客户端忽略。
-
js获取dataset
// 获取data-*属性值
// 1. 按照普通属性获取
document.getElementsByTagName('div')[0].getAttribute('data-myattr')
// 2. 通过dom.dataset
document.getElementById('demo2').dataset.myattr
- css属性选择器
/* <div data-myattr="myattrname">hello</div> 不生效 */
div[myattr='myattrname'] {width: 80px;height: 40px;background: pink;
}
/* <div data-myattr="myattrname">hello</div> 生效 */
div[data-myattr='myattrname'] {width: 80px;height: 40px;background: pink;
}
draggable拖拽属性
拖放是 HTML5 中非常常见的功能。
- 注意: 为了让元素可拖动,需要使用 HTML5 draggable 属性。
- 提示: 链接和图片默认是可拖动的,不需要 draggable 属性。
- 在拖放的过程中会触发以下事件:
-
在拖动目标上触发事件 (源元素):
- ondragstart - 用户开始拖动元素时触发
- ondrag - 元素正在拖动时触发
- ondragend - 用户完成元素拖动后触发
-
释放目标时触发的事件:
- ondragenter - 当被鼠标拖动的对象进入其容器范围内时触发此事件
- ondragover - 当某被拖动的对象在另一对象容器范围内拖动时触发此事件
- ondragleave - 当被鼠标拖动的对象离开其容器范围内时触发此事件
- ondrop - 在一个拖动过程中,释放鼠标键时触发此事件
-
// 目标元素开始拖动document.addEventListener("dragstart", function (event) {//dataTransfer.setData()方法设置数据类型和拖动的数据event.dataTransfer.setData("Text", event.target.id);
});
// ........
// 拖动区域鼠标释放目标元素
document.addEventListener("drop", function (event) {event.preventDefault();if (event.target.className == "droptarget") {var data = event.dataTransfer.getData("Text");event.target.appendChild(document.getElementById(data));// 将目标元素放在在拖拽容器}
});
dataTranfer数据传输
- dataTransfer 对象用于保存拖动并放下(drag and drop)过程中的数据。
- DragEvent.dataTransfer 在拖放交互期间传输的数据。
requestAnimationFrame请求动画帧
在Web应用中,实现动画效果的方法比较多,JavaScript 中可以通过定时器 setTimeout 来实现,css3 可以使用 transition 和 animation 来实现,html5 中的 canvas 也可以实现。除此之外,html5 还提供一个专门用于请求动画的 API,即 requestAnimationFrame(rAF),顾名思义就是 “请求动画帧”。
- 屏幕刷新频率:屏幕每秒出现图像的次数。普通笔记本为60Hz
- 动画原理:计算机每16.7ms刷新一次,由于人眼的视觉停留,所以看起来是流畅的移动。
- setTimeout:通过设定间隔时间来不断改变图像位置,达到动画效果。但是容易出现卡顿、抖动的现象;原因是:
- 1、settimeout任务被放入异步队列,只有当主线程任务执行完后才会执行队列中的任务,因此实际执行时间总是比设定时间要晚;
- 2、settimeout的固定时间间隔不一定与屏幕刷新时间相同,会引起丢帧。
http://caibaojian.com/requestanimationframe.html
-
requestAnimationFrame:优势:由系统决定回调函数的执行时机。60Hz的刷新频率,那么每次刷新的间隔中会执行一次回调函数,不会引起丢帧,不会卡顿
- rAF 的执行步伐跟着系统的绘制频率走。它能保证回调函数在屏幕每一次的绘制间隔中只被执行一次,这样就不会引起丢帧现象,也不会导致动画出现卡顿的问题。
除此之外,rAF 还有以下两个优势: - CPU节能(电池节电模式下优化):使用 setTimeout 实现的动画,当页面被隐藏或最小化时,setTimeout 仍然在后台执行动画任务,由于此时页面处于不可见或不可用状态,刷新动画是没有意义的,而且还浪费 CPU 资源。而 rAF 则完全不同,当页面处理未激活的状态下,该页面的屏幕绘制任务也会被系统暂停,因此跟着系统步伐走的 rAF 也会停止渲染,当页面被激活时,动画就从上次停留的地方继续执行,有效节省了 CPU 开销。
- 函数节流:在高频率事件(resize,scroll 等)中,为了防止在一个刷新间隔内发生多次函数执行,使用 rAF 可保证每个绘制间隔内,函数只被执行一次,这样既能保证流畅性,也能更好的节省函数执行的开销。一个绘制间隔内函数执行多次时没有意义的,因为显示器每16.7ms 绘制一次,多次绘制并不会在屏幕上体现出来。
- rAF 的执行步伐跟着系统的绘制频率走。它能保证回调函数在屏幕每一次的绘制间隔中只被执行一次,这样就不会引起丢帧现象,也不会导致动画出现卡顿的问题。
-
requestAnimationFrame使用一个回调函数作为参数。这个回调函数会在浏览器重绘之前调用。
requestID = window.requestAnimationFrame(callback);
function myAnimate(){// 动画代码// 动画降频requestAnimationFrame(myAnimate)//再次设置下次浏览器重绘之前的动画事件
}
requestAnimationFrame(myAnimate)//下一次浏览器重绘之前调用myAnimate
// 通过requestID可以取消
会话跟踪和本地存储
http协议是无状态的
-
cookies,session HTML4存储 会话跟踪
- cookies
- 可以设置生命周期,这是与webStorage最大的区别;如果不在浏览器中设置过期时间,cookie被保存在内存中,生命周期随浏览器的关闭而结束,这种cookie简称会话cookie。如果在浏览器中设置了cookie的过期时间,cookie被保存在硬盘中,关闭浏览器后,cookie数据仍然存在,直到过期时间结束才消失。
- cookie是服务器发给客户端的特殊信息,cookie是以文本的方式保存在客户端,每次请求时都带上它
- 单个cookie保存的数据不能超过4kb
- 获取:document.cookie
- cookie具有不可跨域名性。
//获取 var cookieAll = document.cookie; console.log(cookieAll);//存储Cookie let username = 'Javan'; document.cookie = "name=" + username; //只能逐条追加cookie,相同key名会覆盖// 过期时间 document.cookie = 'name=xiaoxiong;max-age=30' //30s后cookie过期删除 var d = new Date(); d.setDate(d.getDate()+10) //10天后过期 document.cookie = 'name=xiaoxiong;expires='+d // 'name=xiaoxiong;expires=Thu Jan 13 2022 08:34:15 GMT+0800 (中国标准时间)'// 设置过期时间进行删除 let exp = new Date() exp.setTime(exp.getTime() - 1); document.cookie= "test=xiao;expires=" + exp.toGMTString();//格林威治时间,比exp少8个小时
- session
- Session用于保存每个用户的专用信息,变量的值保存在服务器端,通过SessionID来区分不同的客户
- session与cookie不同,是由服务器端创建并存储的会话,相对于cookie来说要安全的多,也没有长度的限制。
- 服务器创建session出来后,会把session的id号,以cookie的形式回写到客户端,这样,只要客户端的浏览器不关,再去访问服务器时,都会带着session的id号去,服务器发现客户机浏览器带session id过来了,就会使用内存中与之对应的session为之服务。
- tomcat的将session存储在内存中,也可以持久化到redis中。客户端只保存sessionid到cookie中,而不会保存session
@WebServlet("/testServlet") public class testServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response){request.setCharacterEncoding("utf-8");HttpSession session = request.getSession();String[] bookNames = request.getParameterValues("book");response.sendRedirect(request.getContextPath()+"/shopping/step-2.jsp");} } //jsp 中获取session String[] bookNames = (String[])session.getAttribute("bookNames");
- cookies
-
HTML5 Web 存储(localStorage和sessionStorage)
HTML5 Web 存储(webStorage)是本地存储,存储在客户端,包括localStorage和sessionStorage。
HTML5 Web 存储是以键/值对的形式存储的,以字符串形式存储。- localStorage
- localStorage生命周期是永久,除非主动清除localStorage信息,否则这些信息将永远存在。
- 存放数据大小为一般为5MB,而且它仅在客户端(即浏览器)中保存,不参与和服务器的通信。
- 操作:setItem;getItem;removeItem;clear;key(index)
- sessionStorage。
- 与localStorage 相似,不同之处在于 localStorage生命周期是永久的,而sessionStorage的数据只在当前会话有效
- 页面会话在浏览器打开期间一直保持,并且重新加载或恢复页面仍会保持原来的页面会话。
- 在新标签或窗口打开一个页面时会复制顶级浏览会话的上下文作为新会话的上下文,这点和 session cookies 的运行方式不同。
- 打开多个相同的URL的Tabs页面,会创建各自的sessionStorage。
- 关闭对应浏览器窗口(Window)/ tab,会清除对应的sessionStorage。
- 复杂数据存储
- 存储数据前:利用JSON.stringify将对象转换成字符串
- 获取数据后:利用JSON.parse将字符串转换成对象
- localStorage
history,hash路由
history.back() = history.go(-1)
history.forward() = history.go(1)
history.lengthhistory.pushState()
// pushState只会在当前history中添加一条记录,地址栏发生变化,但不会加载网页
history.pushState({name:'xx'}, "my title", "/test.html")
history.state //获取history.replaceState()
// replaceState会替换当前的history中的记录,并且刷新浏览器
history.replaceState({}, "my title", "/test.html")
- popstate事件
- 在每一次活动的history发生变化的时候就会触发这个事件
- 需要注意的是,仅仅调用pushState方法或replaceState方法 ,并不会触发该事件,
- 只有用户点击浏览器倒退按钮和前进按钮,
- 或者使用JavaScript调用back、forward、go方法时才会触发。
- 另外,该事件只针对同一个文档,如果浏览历史的切换,导致加载不同的文档,该事件也不会触发。
- hashchange事件
- window.location.hash.substring(1)
classList
原生js——操作类名(HTML5新增classList)
- classList.add( newClassName );
添加新的类名,如已经存在,取消添加 - classList.contains( oldClassName );
确定元素中是否包含指定的类名,返回值为true 、false; - classList.remove( oldClassName );
移除已经存在的类名; - classList.toggle( className );
如果classList中存在给定的值,删除它,否则,添加它; - classList.replace( oldClassName,newClassName );
类名替换
Worker
- 如何证明js是单线程的?
setTimeout()的回调函数是在主线程执行的
定时器回调函数只有在运行栈中的代码全部执行完后才能执行 - 为什么js要用单线程模式而不用多线程
JavaScript的单线程与它的用途有关
作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作dom
这决定了它只能是单线程,否则会带来负责的同步问题。
假如多个线程同时操作同一个dom,其中一个线程把dom删除了,其他线程就无法操作,这里涉及到同步问题
- Worker接口是 Web Workers API 的一部分,指的是一种可由脚本创建的后台任务
- 任务执行中可以向其创建者收发信息。
- 要创建一个 Worker ,只须调用 Worker(URL) 构造函数,函数参数
URL
为指定的脚本。 - Worker 也可以创建新的 Worker,当然,所有 Worker 必须与其创建者同源。
- worker.postMessage({add:{a:1,b:2}});
- worker.onmessage = function(e){console.log(e.data);}
- Worker 可以使用 XMLHttpRequest 发送请求,但有一些限制
- fetch 仍可正常使用,没有类似的限制
- H5规范 提供了js分线程的实现,取名为web workers
- 相关api
- Worker:构造函数,加载分享程执行的js文件
- Worker.prototype.onmessage: 用于接收另一个线程的回调函数
- Worker.prototype.postmessage: 向另一个线程发送消息
- 不足
- worker内代码不能操作DOM(更新UI)
- 不能跨域加载js
- 不是每个浏览器都支持这个新特性
web workers 是html5提供的一个JavaScript多线程解决方案
我们可以将一些大计算量的代码交由web worker运行而不冻结用户界面
但是子线程完全受主线程控制,且不能操作dom
所以这个新标准并没有改变JavaScript单线程的本质
- 使用:
- 创建在分线程执行的js文件
- 在主线程的js中发消息并设置回调
<p>计数: <output id="result"></output></p>
<button onclick="startWorker()">开始工作</button>
<button onclick="stopWorker()">停止工作</button>
<script>
var w;
function startWorker() {if(typeof(Worker) !== "undefined") {if(typeof(w) == "undefined") {w = new Worker("demo_workers.js");//Worker 加载分线程中的js文件}//向分线程发生消息w.postMessage('hello')//绑定接收分线程返回的消息//回调代码必须在初始化之后才可以进行,所以它的位置没有要求w.onmessage = function(event) {//event.data 接收的数据console.log('主线程接收到的分线程的数据',event.data)document.getElementById("result").innerHTML = event.data;};} else {document.getElementById("result").innerHTML = "抱歉,你的浏览器不支持 Web Workers...";}
}function stopWorker()
{ w.terminate();w = undefined;
}
</script>
分线程demo_workers.js 文件代码
//分线程接收到主线程的数据
var message = function(event){//不能用函数声明console.log('分线程接收到主线程的数据',event.data)
}
//复杂计算
var i=0;
function timedCount()
{i=i+1;postMessage(i);//分线程向主线程发送数据//postMessage也可以是主线程向分线程发送消息,他们是互相的//onmessage 同理setTimeout("timedCount()",500);
}
timedCount();
FileReader
https://www.cnblogs.com/leejersey/p/4772504.html
-
FileReader
对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。- 其中File对象可以是来自用户在一个input元素上选择文件后返回的FileList对象,
- 也可以来自拖放操作生成的 DataTransfer对象
-
事件处理
- FileReader.onabort
该事件在读取操作被中断时触发。 - FileReader.onerror
该事件在读取操作发生错误时触发。 - FileReader.onload
该事件在读取操作完成时触发。 - FileReader.onloadstart
该事件在读取操作开始时触发。 - FileReader.onloadend
该事件在读取操作结束时(要么成功,要么失败)触发。 - FileReader.onprogress
该事件在读取Blob时触发。
- FileReader.onabort
WebSocket
WebSocket 对象提供了用于创建和管理 WebSocket 连接,以及可以通过该连接发送和接收数据的 API。
-
构造函数
WebSocket()构造函器会返回一个 WebSocket 对象。var aWebSocket = new WebSocket(url [, protocols]);
-
事件和对应属性
使用 addEventListener() 或将一个事件监听器赋值给本接口的 oneventname 属性,来监听下面的事件。- close
当一个 WebSocket 连接被关闭时触发。
也可以通过 onclose 属性来设置。 - error
当一个 WebSocket 连接因错误而关闭时触发,例如无法发送数据时。
也可以通过 onerror 属性来设置. - message
当通过 WebSocket 收到数据时触发。
也可以通过 onmessage 属性来设置。 - open
当一个 WebSocket 连接成功时触发。
也可以通过 onopen 属性来设置。
- close
-
方法
- 关闭当前链接。WebSocket.close([code[, reason]])
- 对要传输的数据进行排队。WebSocket.send(data)
-
常量
- WebSocket.CONNECTING 0
- WebSocket.OPEN 1
- WebSocket.CLOSING 2
- WebSocket.CLOSED 3
-
https://socket.io/
-
在线聊天室
-
场景: 股票交易系统、多人聊天室 、前后端实时系统、服务器消息推送、、
-
HTML5只专注于客户端的API, 而服务器端是各个语言自己去实现
-
WebSocket的服务端和客户端可以双向进行通讯,并且允许跨域通讯。
geolocation地理位置
- window.navigator.geolocation.getCurrentPosition(success,failure)
function success(e){console.log('获取位置成功',e)}function failure(e){console.log('获取位置失败',e)}window.navigator.geolocation.getCurrentPosition(success,failure)// 谷歌浏览器中当允许获取位置时,因为电脑没有gps,所有会去从谷歌地图获取,需要科学上网// edge浏览器中可以正常获取
设备加速度,设备方向
-
DeviceOrientation将底层的方向传感器和运动传感器进行了高级封装,提供了DOM事件的支持。
这个特性包括两个事件:- deviceMotion:
封装了运动传感器的事件,可以获取手机运动状态下的运动加速度等数据。
可以实现重力感应、摇一摇.
if (window.DeviceMotionEvent) {window.addEventListener("devicemotion", function(event) {// DeviceMotionEvent.acceleration 只读// 提供了设备在X,Y,Z轴方向上加速度的对象。加速度的单位为 m/s2// DeviceMotionEvent.accelerationIncludingGravity 只读// 提供了设备在X,Y,Z轴方向上带重力的加速度的对象。加速度的单位为 m/s2console.log(event.acceleration.x + ' m/s2');}, true); }
- deviceOrientation:
封装了方向传感器数据的事件,可以获取手机静止状态下的方向数据(手机所处的角度、方位和朝向等)。
可以实现指南针功能。
if (window.DeviceOrientationEvent) {window.addEventListener("deviceorientation", function(event) {//alpha范围 0-360 beta -180至180 gamma -90至90// alpha: 在Z轴上的角度var rotateDegrees = event.alpha;// alpha为0°时表示设备的顶部正指北极方向,当设备向左旋转时,alpha将增加。// gamma: 从左到右var leftToRight = event.gamma;// beta: 从前到后的运动var frontToBack = event.beta;handleOrientationEvent(frontToBack, leftToRight, rotateDegrees);}, true); }
- deviceMotion:
tounch事件
- 300ms延迟问题
背景: 2007 年初。苹果公司在发布首款iPhone前夕,遇到一个问题:当时的网站都是为大屏幕设备所设计的。于是苹果的工程师们做了一些约定,应对iPhone这种小屏幕浏览桌面端站点的问题。
这当中最出名的,当属双击放大。即用手指在屏幕上快速点击两次,iOS自带的Safari浏览器会将网页放大。
这是一个很好的设计啊!那它和延迟有什么关系呢? 我们假定一个场景。当用户看到一张图片,而此时图标又刚好是一个链接地址。用户点击到图片之后,并不能立即判断用户是要打开链接,还是说想观看图片的细节。因此Safari 就等待300毫秒,判断用户是否再次点击了屏幕。这也是会有上述 300 毫秒延迟的主要原因。
由于iPhone的这一成功,许多浏览器厂商开始支持这一功能。但是随着技术的发展,性能的提升。慢慢的出现了混合开发,web应用在某些场景一开始逐渐替代了原生开发。此时所有的单击事件都有300毫秒延迟,必然是不可接受的,那怎么去解决这个问题呢?
-
解决
- 禁用缩放
既然大家都觉得缩放没有意义,那就提供一个属性去控制它。在HTML文档头部添加如下meta标签
<meta name="viewport" content="user-scalable=no"> <meta name="viewport" content="initial-scale=1,maximum-scale=1">
有一个小小的缺点需要说一下,由于图片和文字都是一比一的比例显示的,而且禁用了缩放功能。在某些情况下,需要放大某张图片或者某段文字,就是无法实现图片的双击放大了。(除非js脚本)
- 更改默认的视口宽度
还是在HTML文档头部添加如下meta标签
<meta name="viewport" content="width=device-width">
这个方法跟方法一有些许不一样,他将页面的宽度设置成了,与显示屏同宽。需要网站做响应式布局。否则显示效果极易受到影响。还有他没有禁止缩放功能,所以,你可以用双指操作来放大页面。
- CSS touch-action
html {touch-action: none }
这是个CSS属性,如果值为 none 的话, 就表示禁用掉该元素上的浏览器代理的任何默认行为(缩放,移动, 拖拽),无300ms延迟。你也可以在html标签上面设置该属性,虽然该方法实现了禁用缩放。但是其他的触摸类型交互事件都被禁用了。导致页面无法滚动。
- tounchstart事件穿透问题和解决
- 禁用缩放
Fetch
fetch(url, config)
返回一个Promise对象。
-
fetch 函数返回一个 Promise 对象。
- 当收到服务器的返回结果后,Promise 进入 resolved 状态,状态数据为 Response对象。
- 当网络发生错误(或其他导致无法完成交互的错误)时,Promise 进入 rejected 状态,状态数据为错误信息。
-
Response 对象:
- ok:boolean,当响应消息码在 200~299 之间时为 true,其他未 false。
- status:number,响应的状态码。
- text():用于处理文本格式的 Ajax 响应。它从响应中获取文本流,将其读完,然后返回一个被解决为 string 对象的 Promise。
- blob():用于处理二进制文件格式,(比如图片或电子表格)的 Ajax 响应。它读取文件的原始数据,一旦读取完整个文件,就返回一个被解决为 blob 对象的 Promise。
- json():用于处理 JSON 格式的 Ajax 的响应,它将 JSON 数据流转换为一个被解决为 JavaScript 对象的 Promise。
- redirect():可以用于重定向到另一个 URL。它会创建一个新的 Promise,以解决来自重定向的 URL 的响应。
-
Request 对象 new Request(url地址,配置)
-
https://developer.mozilla.org/zh-CN/docs/Web/API/fetch
-
请注意,fetch 规范与 jQuery.ajax() 主要有以下的不同
- 当接收到一个代表错误的 HTTP 状态码时,从 fetch() 返回的 Promise 不会被标记为 reject,即使响应的 HTTP 状态码是 404 或 500。相反,它会将 Promise 状态标记为 resolve (如果响应的 HTTP 状态码不在 200 - 299 的范围内,则设置 resolve 返回值的 ok 属性为 false ),仅当网络故障时或请求被阻止时,才会标记为 reject。
- fetch 不会发送跨域 cookies,除非你使用了 credentials 的初始化选项。
const config = {method: "GET",// headers: {// "Content-Type": "application/json",// a: 1// }
}
const req = new Request(url, config);
try{const resp = await fetch(req);const pro = await resp.json();console.log(pro);
}catch(err) {console.log(err);
}
- 请求某个网页:
fetch('http://localhost/index.html').then(response => response.text()).then(data => console.log(data));
// es6
const result = await fetch(url, config);
const respText = await result.text();
- 请求某个JSON接口:
fetch('http://localhost/test.json').then(response => response.json()).then(data => console.log(data));
const result = await fetch(url, config);
const respJson = await result.json();
- 请求某个图片:
fetch('http://localhost/test.jpg').then(response => response.blob()).then(data =>{var img = new Image();img.src = URL.createObjectURL(data); // 这个data是blob对象document.body.appendChild(img);});
const result = await fetch(url, config);
const respBlob = await result.blob();
canvas
- CanvasRenderingContext2D即canvas.getContext(‘2d’)返回的对象类型,几乎所有作图操作基于这个“上下文对象”而非canvas dom
只有矩形,文本,图片可直接绘制
fillRect(x, y, width, height)
绘制一个填充的矩形strokeRect(x, y, width, height)
绘制一个矩形的边框clearRect(x, y, width, height)
清除指定矩形区域,让清除部分完全透明。fillText(text, x, y [, maxWidth])
在(x,y)位置绘制(填充)文本。strokeText(text, x, y [, maxWidth])
在(x,y)位置绘制(描边)文本。drawImage
图片绘制drawImage(image, dx, dy)
我把一张图片image放到canvas中,坐标是dx,dy,以canvas左上角为坐标原点,图片的大小以自己为主,如果大于canvas则显示一部分drawImage(image, dx, dy [, dWidth, dHeight])
这个比上一个多的一个控制图片的大小,就是因为有时候可能canvas的大小不满于图片的大小,或者你要对图片进行缩放,多了2个坐标参数dw和dh,这两个参数我们用来控制图片在canvas中显示的大小
应用场景:image为坐标系背景图,可以用作报表展示drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)
主要是用来对于图片进行裁剪;我这边使用的地方在于对css sprite图的裁剪,也可以用于截图工具
- canvas默认只能绘制3种矩形
<style>
#canvas{border: 1px solid #000;
}
</style>
<body><!-- 单位默认是px --><canvas id="canvas" width="300" height="180"></canvas>
</body>
<script>const canvas = document.getElementById('canvas');const ctx = canvas.getContext('2d');// 1. 画填充矩形ctx.fillStyle = 'orange';//背景色ctx.fillRect(50,50,100,100);// 2. 画透明矩形 清除ctx.clearRect(75,75,50,50);// 3. 画边框矩形ctx.strokeStyle = 'red';//边框颜色ctx.strokeRect(50,50,80,80)
</script>
- 绘制图片
const img= new Image();
img.onload = function(){const pattern = ctx.createPattern(img,'no-repeat');//const pattern = ctx.createPattern(canvas2,'no-repeat'); //canvas2作为图片源ctx.fillStyle = pattern;ctx.fillRect(0,0,400,300);
}
img.src = 'http://visitjapan-photocontest2016.people.cn/NMediaFile/2017/0112/MAIN201701121021000257100783409.jpg'
const img= new Image();
img.onload = function(){ctx.drawImage(img,20,20,300,200)
}
img.src = 'https://gitee.com/jingyu7/pic/raw/master/202201041158200.jpeg'
- 利用canvas中toDataURL()将图片转为dataURL(base64)
const dataURL=canvas.toDataURL('image/jpeg'); //转换图片为dataURL
- 文字
ctx.font = '50px sans-serif';
ctx.fillText('Hello World',10,50)
ctx.strokeText('Hello World',10,100)
路径-线,三角,贝塞尔曲线
绘制其他形状均需要路径
beginPath()
新建一条路径closePath()
闭合路径(即路径没有闭合时,从当前点生成一条直线路径连到起始点,使其闭合)
只会闭合最后一条子路径stroke()
绘制路径(即描边)fill()
(根据设置)填充路径内部moveTo(x, y);
画笔抬起并移动到指定地点
- 绘制直线
ctx.beginPath();
ctx.strokeStyle = 'red';
ctx.moveTo(50,50); //起始点
ctx.lineTo(100,100);//线 终止点
ctx.lineWidth= 10; //线宽
ctx.stroke()
- lineCap给线加帽子
ctx.beginPath();
ctx.moveTo(30,30);
ctx.lineWidth = 20;
ctx.lineCap = 'round';
ctx.lineTo(150,30);
ctx.stroke()
- lineJoin 线的连接点样式
- 'miter’默认尖角
- ‘bevel’ 平角
- ‘round’ 圆角
ctx.beginPath();
ctx.moveTo(30,200);
ctx.lineWidth = 20;
ctx.lineJoin = 'bevel';
// round
ctx.lineTo(150,30);
ctx.lineTo(200,200);
ctx.stroke()
- miterLimit 设置斜接面限制比例的属性,默认值是10
- lineJoin为miter时生效
ctx.lineWidth=5;
// ctx.lineJoin="miter";
ctx.miterLimit=5;
ctx.moveTo(20,20);
ctx.lineTo(50,27);
ctx.lineTo(20,34);
ctx.stroke();
- 绘制三角形
ctx.beginPath();
ctx.strokeStyle = 'red';
ctx.lineWidth= 5; //线宽
ctx.moveTo(50,50); //起始点
ctx.lineTo(150,70);//线 终止点
ctx.lineTo(100,100);//线 终止点
ctx.closePath(); //闭合路径 最后一个点和第一个点连接
ctx.stroke()
- 二次贝塞尔曲线路径ctx.quadraticCurveTo(cpx, cpy, x, y)
它需要2个点。 第一个点是控制点,第二个点是终点。
起始点是当前路径最新的点,当创建二次贝赛尔曲线之前,可以使用 moveTo() 方法进行改变。
// 曲线从moveTo()指定的点开始: (20, 110)。 控制点位于(230, 150)。 曲线在(250, 20)处结束。
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(20, 110);
ctx.quadraticCurveTo(230, 150, 250, 20);
ctx.stroke();
- 三次贝赛尔曲线路径bezierCurveTo
该方法需要三个点。 第一、第二个点是控制点,第三个点是结束点。
起始点是当前路径的最后一个点,绘制贝赛尔曲线前,可以通过调用 moveTo() 进行修改。
ctx.beginPath();
ctx.moveTo(50,20);
ctx.bezierCurveTo(230, 30, 150, 60, 50, 100);
ctx.stroke();ctx.fillStyle = 'blue';
// start point
ctx.fillRect(50, 20, 10, 10);
// end point
ctx.fillRect(50, 100, 10, 10);ctx.fillStyle = 'red';
// control point one
ctx.fillRect(230, 30, 10, 10);
// control point two
ctx.fillRect(150, 70, 10, 10);
- ctx.isPointInPath(80,80):判断点是否在上面路径的区域内。
- ctx.isPointInStroke(80,50):判断点是否在上面路径的边缘线上。
原点,状态,变换
ctx.translate(x, y);
设置canvas原点;默认原点在左上角ctx.save()
将当前状态放入栈中,保存canvas全部状态的方法。
ctx.restore()
还原到上次保存的默认状态ctx.scale(x,y)
如果您对绘图进行缩放,所有之后的绘图也会被缩放。定位也会被缩放。ctx.rotate(angle);
旋转- 顺时针旋转的弧度。如果你想通过角度值计算,可以使用公式: degree * Math.PI / 180 。
- 旋转中心点一直是 canvas 的起始点。 如果想改变中心点,我们可以通过 translate() 方法移动 canvas 。
ctx.transform(a, b, c, d, e, f);
- ace水平缩放倾斜移动
- bdf垂直倾斜缩放移动
ctx.setTransform(a, b, c, d, e, f);
重新设置(覆盖)当前的变换并调用变换的方法- transform() 方法,这个方法不会覆盖当前的变换矩阵,会多次叠加变换。
// <canvas id="canvas" width="400" height="300"></canvas>
ctx.fillStyle = "green";
ctx.fillRect(10, 10, 50, 50);
ctx.save(); // 暂存当前的状态ctx.fillStyle = "orange";
ctx.fillRect(150, 75, 100, 100);ctx.restore(); //还原到上次保存的状态 fillStyle = "green
ctx.scale(2,2);//放大到 200%再绘制:
ctx.fillRect(40, 10, 50, 50);ctx.fillStyle = "red";
ctx.scale(0.5,0.5)
// 缩放到初始大小
// 如果您对绘图进行缩放,所有之后的绘图也会被缩放。定位也会被缩放。
ctx.rotate(45 * Math.PI / 180);
ctx.fillRect(70,0,100,100);// 旋转之后的绘图也会被旋转。
ctx.rotate(-45 * Math.PI / 180);
ctx.fillStyle = "black";
ctx.transform(1,1,0,1,300,0);
ctx.fillRect(0,0,100,100);ctx.fillStyle = "yellow";
// ctx.transform(1,1,0,1,300,0); //这个会叠加上次的transform变换
ctx.setTransform(1,1,0,1,300,0); //不会叠加上次的transform变换
ctx.fillRect(10,10,50,100);
渐变,模糊,透明度
- 渐变
// const gradien = ctx.createLinearGradient(0,0,300,300) //45度渐变
const gradien = ctx.createLinearGradient(0,0,300,0) //x方向渐变
gradien.addColorStop(0,'lightblue');
gradien.addColorStop(0.5,'lightpink');
gradien.addColorStop(1,'orange')ctx.fillStyle = gradien;
ctx.fillRect(0,0,300,300)
- 模糊
ctx.shadowColor = 'black';
ctx.shadowOffsetX = 25;
ctx.shadowOffsetY = 15;
ctx.shadowBlur = 15; //模糊半径ctx.fillStyle = 'red';
ctx.fillRect(0,0,150,100)
- globalAlpha透明度
ctx.globalAlpha = 0.2; //透明度
圆
- ctx.arc(x, y, r, startAngle, endAngle, anticlockwise);
- startAngle 圆弧的起始点,0
- endAngle 圆弧的终点,2*Math.PI, 6.28; Math.PI/180 * 60 = 60deg圆
- anticlockwise 如果为 true,逆时针绘制圆弧,反之,顺时针绘制。
- ctx.arcTo(x1, y1, x2, y2, radius);xy都是控制点
// ctx.globalAlpha = 0.2; //透明度
ctx.beginPath();
ctx.arc(100,100,80,0,2*Math.PI,false)
// ctx.fill()//填充
ctx.stroke()//描边
ctx.clip();//剪贴ctx.fillStyle = 'blue';
ctx.fillRect(0,0,100,100)
getImageData,putImageData
- ImageData ctx.getImageData(sx, sy, sw, sh);
返回一个ImageData对象,用来描述canvas区域隐含的像素数据,这个区域通过矩形表示,起始点为(sx, sy)、宽为sw、高为sh。- 如果图片是外部连接,当用到getImageData方法获取图片信息时,会碰到跨域无法获取的情况
- 解决:外链图片转为base64
- 问题:
canvas.toDataURL('image/jpeg');
也有此问题
Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
- void ctx.putImageData(imagedata, dx, dy);
数据从已有的 ImageData 对象绘制到位图的方法。
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.fillStyle="red";
ctx.fillRect(10,10,50,50);
function copy(){var imgData=ctx.getImageData(10,10,50,50);ctx.putImageData(imgData,10,70);
}
// <button οnclick="copy()">复制</button>
globalCompositeOperation
https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation
设置图像重叠部分的处理
- source-over 默认值,在现有画布上下文之上绘制新图形。
- source-in 新图形只在新图形和目标画布重叠的地方绘制。其他的都是透明的。
- source-out 在不与现有画布内容重叠的地方绘制新图形。
- destination-over 在现有的画布内容后面绘制新的图形。
SVG
-
canvas 是位图放大会失真,SVG为了解决这个问题,SVG是矢量图
-
可缩放矢量图形(Scalable Vector Graphics,SVG),是一种用于描述二维的矢量图形,基于 XML 的标记语言
-
元素的渲染顺序。SVG文件全局有效的规则是“后来居上”,越后面的元素越可见。
-
web上的svg文件可以直接在浏览器上展示,或者通过以下几种方法嵌入到HTML文件中:
- 可以通过 object 元素引用SVG文件:
<object data="image.svg" type="image/svg+xml" />
- 类似的也可以使用 iframe 元素引用SVG文件:
<iframe src="image.svg"></iframe>
- div@background: url(demo.svg);
- 可以通过 object 元素引用SVG文件:
-
SVG文件类型:推荐使用“.svg”(全部小写)作为此类文件的扩展名。
-
基本形状
- https://developer.mozilla.org/zh-CN/docs/Web/SVG/Tutorial/Basic_Shapes
- 矩形rect 圆形circle 椭圆ellipse 线条line 折线polyline 多边形polygon 路径path
-
常用应用场景:小图标,边框动画,图片加文字
audio,video
Flash player 插件 安全问题-> HTML5提供的音视频接口
- video
- width pixels 设置视频播放器的宽度。
- height 设置视频播放器的高度。
- src url 要播放的视频的 URL。
- source子标签,此时不能在video中出现src属性
- autoplay 如果出现该属性,则视频在就绪后马上播放。
- controls 如果出现该属性,则向用户显示控件,比如播放按钮。
- loop 如果出现该属性,则当媒介文件完成播放后再次开始播放。
- muted 规定视频的音频输出应该被静音。
- poster 规定视频下载时显示的图像,或者在用户点击播放按钮前显示的图像。
- preload如果出现该属性,则视频在页面加载时进行加载,并预备播放。如果使用 “autoplay”,则忽略该属性。
- 视频格式
- OGG MPEG4 WEBM