ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

HTML5 详解(二):拖拽、History、Geolocation 与全屏 API 实战指南

HTML5 详解(二):拖拽、History、Geolocation 与全屏 API 实战指南 文档教程前端【免费下载链接】Web千古前端图文教程超详细的前端入门到进阶知识库。从零开始学前端做一名精致优雅的前端工程师。项目地址https://gitcode.com/gh_mirrors/we/Web点击查看免费下载本篇文章是「千古前端图文教程」HTML5 系列的第二篇聚焦 HTML5 为 Web 应用带来的四个交互能力拖拽Drag and Drop、历史状态管理History、地理定位Geolocation与全屏Fullscreen。通过本篇文章你将学会用draggable属性与拖拽事件实现元素搬运用window.history打造无刷新的单页应用用navigator.geolocation获取用户经纬度并接入地图服务以及用全屏 API 让任意元素铺满屏幕。本文内容承接 01-HTML/08-HTML5详解.md并与 01-HTML/11-HTML5详解三.md 共同构成 HTML5 核心能力全景。一、拖拽Drag and Drop在传统网页中元素是无法被鼠标抓起来移动的。HTML5 规范引入了原生的拖拽能力只要为元素增加draggabletrue属性该元素就可以被用户拖拽。其中图片、链接默认就是开启拖拽的例如博客园网站里的图片和超链接可以直接拖拽而普通元素如div默认不可拖拽需要显式声明。1、拖拽元素Draggable页面中设置了draggabletrue属性的元素就是拖拽元素。最简单的例子!DOCTYPE html html langen head meta charsetUTF-8 titleTitle/title link relstylesheet hrefcss/font-awesome.min.css style .box1{ width: 200px; height: 200px; background-color: green; } /style /head body !--给 box1 增加拖拽的属性-- div classbox1 draggabletrue/div /body /html给box1加上draggabletrue之后它就变得可以拖拽了。但拖拽之后要做什么事情才是关键这就涉及事件监听。拖拽元素可以监听的四个事件应用于拖拽元素本身事件触发时机ondragstart当拖拽开始时调用ondragleave当鼠标离开拖拽元素时调用ondragend当拖拽结束时调用ondrag整个拖拽过程都会调用代码演示!DOCTYPE html html head langen meta charsetUTF-8 title/title style .box { width: 200px; height: 200px; background-color: green; } /style /head body div classbox draggabletrue/div script var box document.querySelector(.box); // 绑定拖拽事件 // 拖拽开始 box.ondragstart function () { console.log(拖拽开始.); } // 拖拽离开鼠标拖拽时离开被拖拽的元素时触发 box.ondragleave function () { console.log(拖拽离开..); } // 拖拽结束 box.ondragend function () { console.log(拖拽结束...); console.log(---------------); } box.ondrag function () { console.log(拖拽); } /script /body /html这里用到了document.querySelector(.box)这个 DOM 查询方法它是 HTML5 DOM 操作的核心 API 之一配合classList.add/remove可以完成丰富的交互相关用法在 01-HTML/08-HTML5详解.md 的「DOM 操作」小节有系统讲解。另外注意示例中事件处理函数里的this指向绑定事件的对象即.box关于事件函数中this的指向规则可参考 04-JavaScript基础/25-this指向.md。2、目标元素Drop Target想把元素 A 拖拽到元素 B 里元素 B 就是目标元素。页面中任何一个元素都可以成为目标元素。目标元素可以监听的四个事件应用于目标元素事件触发时机ondragenter当拖拽元素进入时调用ondragover当拖拽元素停留在目标元素上时会连续一直触发不管拖拽元素此时是移动还是不动的状态ondrop当在目标元素上松开鼠标时调用ondragleave当鼠标离开目标元素时调用代码演示!DOCTYPE html html head langen meta charsetUTF-8 title/title style .one { width: 100px; height: 100px; border: 1px solid #000; background-color: green; } .two { position: relative; width: 200px; height: 200px; left: 300px; top: 100px; border: 1px solid #000; background-color: red; } /style /head body div classone draggabletrue/div div classtwo/div script var two document.querySelector(.two); //目标元素的拖拽事件 // 当被拖拽元素进入时触发 two.ondragenter function () { console.log(来了.); } // 当被拖拽元素离开时触发 two.ondragleave function () { console.log(走了..); } // 当拖拽元素在 目标元素上时连续触发 two.ondragover function (e) { //阻止拖拽事件的默认行为 e.preventDefault(); //【重要】一定要加这一行代码否则后面的方法 ondrop() 无法触发。 console.log(over...); } // 当在目标元素上松开鼠标是触发 two.ondrop function () { console.log(松开鼠标了....); } /script /body /html关键点event.preventDefault()必不可少。示例中在ondragover里调用了e.preventDefault()来阻止拖拽的默认行为。如果没有这一行浏览器默认不允许把元素放下后面的ondrop()方法根本无法触发——此时连光标形状都会提示无法在此处放置。总结如果想让拖拽元素在目标元素里做点事情就必须在ondragover()里加event.preventDefault()这一行代码。preventDefault()是事件对象Event提供的标准方法用来阻止浏览器的默认行为它与事件绑定的多种方式如addEventListener配合使用的细节可参考 04-JavaScript基础/41-事件的绑定和事件对象Event.md。3、拖拽练习把方块拖进目标盒子理解了拖拽元素与目标元素两套事件体系之后就可以实现拖入容器的完整功能。下面这个完整案例左侧盒子内有 8 个圆形小方块每个都可拖拽拖到右侧的目标盒子中时方块会被收纳进去。!DOCTYPE html html head langen meta charsetUTF-8 title/title style .one { width: 400px; height: 400px; border: 1px solid #000; } .one div, .two div { width: 98px; height: 98px; border: 1px solid #000; border-radius: 50%; background-color: red; float: left; text-align: center; line-height: 98px; } .two { width: 400px; height: 400px; border: 1px solid #000; position: absolute; left: 600px; top: 200px; } /style /head body div classone div draggabletrue1/div div draggabletrue2/div div draggabletrue3/div div draggabletrue4/div div draggabletrue5/div div draggabletrue6/div div draggabletrue7/div div draggabletrue8/div /div div classtwo/div script var boxs document.querySelectorAll(.one div); // 临时的盒子 用于存放当前拖拽的元素 var two document.querySelector(.two); var temp null; // 给8个小盒子分别绑定拖拽事件 for (var i 0; i boxs.length; i) { boxs[i].ondragstart function () { // 保持当前拖拽的元素 temp this; console.log(temp); } boxs[i].ondragend function () { // 当拖拽结束 清空temp temp null; console.log(temp); } } // 目标元素的拖拽事件 two.ondragover function (e) { // 阻止拖拽的默认行为 e.preventDefault(); } // 当在目标元素上松开鼠标是触发 two.ondrop function () { // 将拖拽的元素追加到 two里面来 this.appendChild(temp); } /script /body /html这个案例的核心技巧在于用一个临时变量temp在拖拽元素与目标元素之间传递数据在ondragstart中把当前被拖拽的元素保存到temptemp this这里的this正是触发事件的那个小方块在ondragend中清空temp避免残留引用在目标元素的ondrop中通过this.appendChild(temp)把暂存的元素追加为目标盒子的子节点完成搬运。这正是 HTML5 原生拖拽实现跨容器搬运元素的典型范式无需 jQuery 等第三方库纯原生即可实现类似购物车、选课列表等交互。二、历史History界面上的所有 JS 操作不会被浏览器记住刷新或跳转后就无法回到之前的状态。在 HTML5 中可以通过window.history操作访问历史状态让一个页面可以有多个历史状态。window.history对象让我们可以管理历史记录常用于单页面应用Single Page ApplicationSPA——无刷新地改变网页内容。常用方法如下方法作用window.history.forward()前进window.history.back()后退window.history.go()刷新window.history.go(n)n1表示前进n-1后退n0刷新。如果移动的位置超出了访问历史的边界会静默失败但不会报错history.pushState通过 JS 加入一个访问状态放入历史中的状态数据可设置 title但当前浏览器并不支持通过它改变历史状态标题pushState是 SPA 路由方案的核心底层能力它可以在不刷新页面的情况下向浏览器历史栈中压入一条新的状态记录配合popstate事件实现地址与内容的同步切换。关于 Vue 生态下的路由实践可进一步参考 12-Vue基础/13-Vue-router路由.md。三、地理定位Geolocation在 HTML5 规范中增加了获取用户地理信息的 API使得我们可以基于用户位置开发互联网应用即基于位置服务 LBSLocation Base Service例如周边商家推荐、路线规划、打卡签到等场景。1、获取地理信息的方式浏览器获取用户地理信息主要有以下几种途径会自动以最优方式去获取1IP 地址根据用户的公网 IP 粗略推断所在区域精度较低。2三维坐标精度较高主要包括以下几种定位技术GPSGlobal Positioning System全球定位系统依靠卫星定位精度高室外可用。Wi-Fi 定位通过扫描附近 Wi-Fi 热点反推位置仅限于室内。手机信号定位通过运营商的信号塔基站定位。这里顺带介绍一下当前全球在用的第二代全球卫星导航系统GNSS美国 Global Positioning System全球定位系统简称GPS苏联/俄罗斯 GLOBAL NAVIGATION SATELLITE SYSTEM全球卫星导航系统简称GLONASS格洛纳斯欧盟 Galileo satellite navigation system伽利略卫星导航系统简称GALILEO伽利略欧洲的说法并不准确包括中国在内的诸多国家也参与其中中国 BeiDou(COMPASS) Navigation Satellite System北斗卫星导航系统简称BDS日本 Quasi-Zenith Satellite System准天顶卫星系统简称QZSS印度 India Regional Satellite Navigation System印度区域卫星导航系统简称IRNSS。以上 6 个系统在中国都能使用。3用户自定义数据由用户手动输入或应用自行维护的位置数据。浏览器会对不同获取方式的优缺点进行比较自动选择最优方式。2、隐私机制HTML5 Geolocation地理位置定位规范提供了一套保护用户隐私的机制必须先得到用户明确许可才能获取用户的位置信息。当页面调用定位 API 时浏览器会弹出授权询问框用户拒绝后定位将无法进行。这是 Web 平台对用户隐私的基本尊重开发者在设计定位类应用时要提前考虑用户拒绝授权的降级方案。3、API 详解地理位置相关 API 挂在navigator.geolocation对象上核心有两个navigator.getCurrentPosition(successCallback, errorCallback, options)获取一次当前地理信息navigator.watchPosition(successCallback, errorCallback, options)重复获取当前地理信息可用于持续跟踪位置变化。回调参数说明当成功获取地理信息后会调用successCallback并返回一个包含位置信息的对象positioncoords即坐标position.coords.latitude纬度position.coords.longitude经度。当获取地理信息失败后会调用errorCallback并返回错误信息error。可选参数options对象可以调整位置信息数据收集方式常用的配置项包括enableHighAccuracy是否开启高精度模式、timeout超时时间与maximumAge允许缓存的最长时间等。完整代码演示!DOCTYPE html html head langen meta charsetUTF-8 title/title /head body script /*navigator 导航*/ //geolocation: 地理定位 // window.navigator.geolocation // 兼容处理 if(navigator.geolocation){ // 如果支持获取用户地理信息 // successCallback 当获取用户位置成功的回调函数 // errorCallback 当获取用户位置失败的回调函数 navigator.geolocation.getCurrentPosition(successCallback,errorCallback); }else{ console.log(sorry,你的浏览器不支持地理定位); } // 获取地理位置成功的回调函数 function successCallback(position){ // 获取用户当前的经纬度 // coords坐标 // 纬度latitude var wdposition.coords.latitude; // 经度longitude var jdposition.coords.longitude; console.log(获取用户位置成功); console.log(wd----------------jd); // 40.05867366972477----------------116.33668634275229 } // 获取地理位置失败的回调函数 function errorCallback(error){ console.log(error); console.log(获取用户位置失败) } /script /body /html代码要点先通过if(navigator.geolocation)做兼容性判断支持才调用getCurrentPosition成功回调里从position.coords.latitude / longitude取出经纬度。需要注意的是不同地图服务对同一地理位置的坐标展示存在坐标系差异即坐标偏移示例代码中的注释给出了对照谷歌地图40.0601398850,116.3434224706、百度地图40.0658210000,116.3500430000、腾讯/高德40.0601486487,116.3434373643。因此在对接具体地图厂商时通常需要做坐标系的转换或直接使用对方提供的定位能力。百度地图 API 举例全景图展示!DOCTYPE html html head title普通地图全景图/title meta http-equivContent-Type contenttext/html; charsetutf-8 / script typetext/javascript srchttp://api.map.baidu.com/api?v2.0akNsGTBiDpgGQpI7KDmYNAPGuHWGjCh1zk/script style typetext/css body, html{width: 100%;height: 100%;overflow: hidden;margin:0;font-family:微软雅黑;} #panorama {height: 100%;overflow: hidden;} /style /head body div idpanorama/div script typetext/javascript //全景图展示 // 谷歌获取的经纬度 40.05867366972477----------------116.33668634275229 // 百度地图40.0658210000,116.3500430000 var jd116.350043; var wd40.065821; var panorama new BMap.Panorama(panorama); panorama.setPosition(new BMap.Point(jd, wd)); //根据经纬度坐标展示全景图 panorama.setPov({heading: -40, pitch: 6}); panorama.addEventListener(position_changed, function(e){ //全景图位置改变后普通地图中心点也随之改变 var pos panorama.getPosition(); map.setCenter(new BMap.Point(pos.lng, pos.lat)); marker.setPosition(pos); }); /script /body /html这里演示了把 Geolocation 得到的经纬度交给百度地图 SDKnew BMap.Point(jd, wd)构造坐标点BMap.Panorama展示全景图并通过position_changed事件联动普通地图与标记点。这展示了浏览器定位 地图服务的经典组合定位负责拿坐标地图负责呈现。四、全屏FullscreenHTML5 规范允许用户自定义网页上任一元素全屏显示——不限于视频任何div、图片、图表容器都可以铺满整个屏幕。1、开启/关闭全屏显示方法如下注意规范写法中screen是小写requestFullscreen() //让元素开启全屏显示 cancelFullscreen() //让元素关闭全屏显示考虑到兼容性问题不同浏览器需要在此基础之上添加私有前缀注意带前缀的写法中screen是大写webkitRequestFullScreen webkitCancelFullScreen mozRequestFullScreen mozCancelFullScreen其中webkit前缀对应 Chrome、Safari 等 WebKit/Blink 内核浏览器moz前缀对应 Firefox。2、检测当前是否处于全屏状态document.fullScreen不同浏览器需要加私有前缀document.webkitIsFullScreen document.mozFullScreen3、全屏的伪类当元素进入全屏状态后可以通过全屏伪类改变它的样式:full-screen .box {} :-webkit-full-screen {} :-moz-full-screen {}例如当元素处于全屏状态时改变它的背景色就可以用到这些伪类。4、代码举例!DOCTYPE html html head langen meta charsetUTF-8 title/title style .box { width: 250px; height: 250px; background-color: green; margin: 100px auto; border-radius: 50%; } /*全屏伪类当元素处于全屏时改变元素的背景色*/ .box:-webkit-full-screen { background-color: red; } /style /head body div classbox/div script var box document.querySelector(.box); // box.requestFullscreen(); //直接这样写是没有效果的。之所以无效应该是浏览器的机制必须要点一下才可以实现全屏功能。 document.querySelector(.box).onclick function () { // 开启全屏显示的兼容写法 if (box.requestFullscreen) { //如果支持全屏那就让元素全屏 box.requestFullscreen(); } else if (box.webkitRequestFullScreen) { box.webkitRequestFullScreen(); } else if (box.mozRequestFullScreen) { box.mozRequestFullScreen(); } } /script /body /html这个例子有两个值得注意的工程细节全屏必须由用户手势触发直接调用box.requestFullscreen()是无效的浏览器安全机制要求全屏操作必须发生在用户交互如点击的回调中所以示例把调用放在了onclick里。兼容性分支判断依次判断requestFullscreen→webkitRequestFullScreen→mozRequestFullScreen哪个存在就调用哪个这是处理浏览器前缀 API 的标准写法。全屏伪类联动进入全屏后圆形的绿色盒子通过:-webkit-full-screen伪类变成红色直观展示全屏状态可单独定制样式。5、全屏 API 的综合应用视频播放器全屏 API 最典型的实战场景是视频播放器。仓库中的 01-HTML/09-HTML5举例简单的视频播放器.md 就实现了一个完整的 H5 播放器用video.play()/video.pause()控制播放暂停用video.ontimeupdate同步进度条与当前时间并在点击全屏按钮时调用// 全屏 extend.onclickfunction(){ // 全屏的h5代码 video.webkitRequestFullScreen(); }这正好是本节全屏 API 的实际落地把video元素全屏展示获得沉浸式观影体验。可见全屏 API 与 HTML5 多媒体标签video、audio是天然的搭档关于多媒体标签的更多属性controls、autoplay、loop、preload及多格式兼容写法可回顾 01-HTML/08-HTML5详解.md 的「多媒体」小节。五、小结四大 API 的适用场景速查API核心入口典型场景关键注意事项拖拽draggabletrueondrag*系列事件卡片搬运、拖拽排序、文件拖放目标元素的ondragover里必须preventDefault()否则ondrop不触发历史window.history单页应用SPA的页面切换go(n)超出边界会静默失败pushState不改变标题定位navigator.geolocation.getCurrentPosition/watchPositionLBS 应用、地图导航、打卡签到必须先获得用户授权不同地图厂商坐标系存在偏移全屏requestFullscreen()含 webkit/moz 前缀视频播放器、图表大屏、沉浸式演示必须由用户手势触发可用:full-screen伪类定制全屏样式本文讲解的四个能力都强调事件驱动 用户交互是 HTML5 从静态文档走向富客户端应用的重要标志。它们与 01-HTML/11-HTML5详解三.md 中讲解的 Web 存储localStorage/sessionStorage、网络状态监听、应用缓存一起构成了开发现代 Web 应用所需的基础能力栈。建议读者把本文中的示例逐行敲一遍再结合 01-HTML/08-HTML5详解.md 中的语义标签、智能表单与多媒体内容以及 01-HTML/09-HTML5举例简单的视频播放器.md 的完整工程形成对 HTML5 的体系化认知。赞分享文档教程前端【免费下载链接】Web千古前端图文教程超详细的前端入门到进阶知识库。从零开始学前端做一名精致优雅的前端工程师。项目地址https://gitcode.com/gh_mirrors/we/Web点击查看免费下载相关推荐如何在React Boilerplate中实现拖拽功能React DnD与HTML5拖拽API完整指南如何在React Boilerplate中实现拖拽功能React DnD与HTML5拖拽API完整指南 React Boilerplate是一个高度可扩展、离前端示例工程开发工具ngx-admin 拖拽功能实现原生 HTML5 拖拽 APIngx admin 拖拽功能实现原生 HTML5 拖拽 API 你还在为实现后台管理系统中的拖拽交互而烦恼吗本文将深入解析 ngx admin 项目中如何利前端UI组件终极指南AngularJS嵌套列表拖拽全实现HTML5原生API终极指南AngularJS嵌套列表拖拽全实现HTML5原生API angular drag and drop lists是一个轻量级的AngularJS指UI库/组件上一篇lingo.dev/_logging 日志基础设施演进实录Pino 轮转日志、容错设计与供应链安全实践下一篇eSearch 开发环境搭建指南从源码克隆、依赖安装到打包编译创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表