【前端:Html】--5.进阶:APIs
目录
1.Html--地理定位
1.1.地理位置
1.2.地图显示
1.3.特定位置
2.Html--拖放
第一步:设置元素可拖拽--draggable
第二步:设置元素拖拽事件--ondragstart 和 setData()
第三步:设置拖到位置 - ondragover
第四步:进行放置 - ondrop
3.Html--本地存储
3.1.localStorage 对象
3.2.sessionStorage 对象
4.Html--Web Workers API
5.Html--SSE
1.Html--地理定位
HTML 地理位置 API
定位用户位置
HTML 地理位置 API 用于获取用户的地理位置。
鉴于该特性可能侵犯用户的隐私,除非用户同意,否则用户位置信息是不可用的。
用于定位用户的位置。
注释: 地理定位是最准确的设备与全球定位系统,如智能手机。
注释: 从 Chrome50 开始,地理位置 API 只在诸如 HTTPS 这样的安全上下文上工作。如果站点托管在非安全源(例如 HTTP)上,则获取用户位置的请求将不再起作用。
1.1.地理位置
getCurrentPosition()
方法用于返回用户的位置。
这里测试全部使用Edge浏览器,谷歌或者qq浏览器获取位置信息可能需要设置权限
<!DOCTYPE html>
<html>
<body><p>点击按钮获取您的坐标。</p><button onclick="getLocation()">试一试</button><p id="demo"></p><script>
var x = document.getElementById("demo");function getLocation() {if (navigator.geolocation) {navigator.geolocation.getCurrentPosition(showPosition, showError);} else { x.innerHTML = "此浏览器不支持地理定位。";}
}function showPosition(position) {x.innerHTML = "Latitude: " + position.coords.latitude + "<br>Longitude: " + position.coords.longitude;
}function showError(error) {switch(error.code) {case error.PERMISSION_DENIED:x.innerHTML = "用户拒绝了地理定位请求。"break;case error.POSITION_UNAVAILABLE:x.innerHTML = "位置信息不可用。"break;case error.TIMEOUT:x.innerHTML = "获取用户位置的请求超时。"break;case error.UNKNOWN_ERROR:x.innerHTML = "出现未知错误。"break;}
}
</script></body>
</html>
1.2.地图显示
要在地图中显示结果,您需要访问地图服务,如 Google 地图。
在下面的实例中,返回的纬度和经度用于在 Google 地图中显示位置(使用静态图像):
function showPosition(position) {var latlon = position.coords.latitude + "," + position.coords.longitude;var img_url = "https://maps.googleapis.com/maps/api/staticmap?center="+latlon+"&zoom=14&size=400x300&sensor=false&key=YOUR_KEY";document.getElementById("mapholder").innerHTML = "<img src='"+img_url+"'>";
}
1.3.特定位置
本页演示了如何在地图上显示用户的位置。
地理定位对于特定位置的信息也非常有用,例如:
- 最新本地信息
- 显示用户附近的兴趣点
- 逐段导航(GPS)
getCurrentPosition()
方法在成功时返回一个对象。始终返回纬度、经度和精度属性。如果可用,则返回其他属性:
属性 | 返回数据 |
---|---|
coords.latitude | 以十进制数表示的纬度(始终返回) |
coords.longitude | 以十进制数表示的经度(始终返回) |
coords.accuracy | 位置的准确性(始终返回) |
coords.altitude | 平均海平面以上的海拔高度(如有返回) |
coords.altitudeAccuracy | 位置的高度精度(如有返回) |
coords.heading | 航向为从北顺时针方向的度数(如有返回) |
coords.speed | 以米/秒为单位的速度(如果可用,返回) |
timestamp | 响应的日期/时间(如果可用,则返回) |
地理定位对象还有其他有趣的方法:
watchPosition()
- 返回用户当前位置,并在用户移动时继续返回更新位置(如车内的GPS)。clearWatch()
- 停止watchPosition()
方法。
下面的实例显示watchPosition()
方法。您需要一个精确的GPS设备来测试(如智能手机),并且可以根据位置变化实时获取位置信息
<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>自动实时定位</title><style>body {font-family: Arial, sans-serif;text-align: center;padding: 20px;margin: 0;}#demo {font-size: 15px;line-height: 1.8;color: #333;text-align: left;max-width: 500px;margin: 20px auto;padding: 15px;border-radius: 8px;background-color: #f9f9f9;}.loading {color: #007acc;font-style: italic;}.error {color: red;}h2 {color: #007acc;}</style>
</head>
<body><h2>📍 自动实时定位</h2><p>打开页面即自动获取您的位置,移动时信息会实时更新。</p><div id="demo">正在加载位置信息...</div><script>const x = document.getElementById("demo");let watchId = null;// 页面加载完成后自动执行定位window.onload = function () {startLocation();};function startLocation() {x.innerHTML = '<span class="loading">正在获取您的位置...</span>';if (navigator.geolocation) {watchId = navigator.geolocation.watchPosition(showPosition,showError,{enableHighAccuracy: true, // 使用 GPS 高精度timeout: 10000,maximumAge: 0,distanceFilter: 5 // 每移动 5 米更新一次(部分设备支持)});} else {x.innerHTML = '<span class="error">此浏览器不支持地理定位。</span>';}}function showPosition(position) {const lat = position.coords.latitude;const lng = position.coords.longitude;const accuracy = position.coords.accuracy; // 定位精度(米)const speed = position.coords.speed; // 速度(m/s)const altitude = position.coords.altitude; // 海拔(米),可能为 nullconst timestamp = new Date(position.timestamp).toLocaleTimeString();x.innerHTML = `<strong>📍 当前位置</strong><br>纬度: <strong>${lat.toFixed(6)}</strong><br>经度: <strong>${lng.toFixed(6)}</strong><br>精度: ±${accuracy} 米<br>海拔: ${altitude ? altitude.toFixed(1) + ' 米' : '不可用'}<br>速度: ${speed ? (speed * 3.6).toFixed(1) + ' km/h' : '0 km/h'}<br>更新时间: ${timestamp}`;}function showError(error) {let message = "";switch (error.code) {case error.PERMISSION_DENIED:message = "位置访问被拒绝,请检查浏览器权限设置。";break;case error.POSITION_UNAVAILABLE:message = "无法获取位置信息,请检查 GPS 或网络。";break;case error.TIMEOUT:message = "获取位置超时,请稍后重试。";break;default:message = "未知错误,请重试。";break;}x.innerHTML = `<span class="error">❌ ${message}</span>`;}// 可选:页面关闭或隐藏时停止监听,节省电量window.addEventListener('beforeunload', function () {if (watchId !== null) {navigator.geolocation.clearWatch(watchId);}});</script></body>
</html>
这里测试使用手机版qq浏览器测试。
2.Html--拖放
拖放是 HTML5 标准的组成部分:任何元素都是可拖放的。
拖放(Drag 和 Drop)是很常见的特性。它指的是您抓取某物并拖入不同的位置。
<!DOCTYPE HTML>
<html>
<head>
<style>
#div1 {width: 350px;height: 70px;padding: 10px;border: 1px solid #aaaaaa;
}
</style>
<script>
function allowDrop(ev) {ev.preventDefault();
}function drag(ev) {ev.dataTransfer.setData("text", ev.target.id);
}function drop(ev) {ev.preventDefault();var data = ev.dataTransfer.getData("text");ev.target.appendChild(document.getElementById(data));
}
</script>
</head>
<body><p>将 W3Schools 图像拖到矩形中:</p><div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<br>
<img id="drag1" src="img_logo.gif" draggable="true" ondragstart="drag(event)" width="336" height="69"></body>
</html>
这可能看起来很复杂,让我们来看看拖放事件的不同部分。
第一步:设置元素可拖拽--draggable
首先:要使元素可拖动,请将 draggable
属性设置为 true:
<img draggable="true">
第二步:设置元素拖拽事件--ondragstart 和 setData()
然后,规定当元素被拖动时发生的事情。
在上面的例子中,ondragstart
属性调用了一个 drag(event) 函数,规定拖动什么数据。
dataTransfer.setData()
方法设置拖动数据的数据类型和值:
function drag(ev) {ev.dataTransfer.setData("text", ev.target.id);
}
在本例中,数据类型是 "text",而值是这个可拖动元素的 id ("drag1")。
第三步:设置拖到位置 - ondragover
ondragover
件规定被拖动的数据能够被放置到何处。
默认地,数据/元素无法被放置到其他元素中。为了实现拖放,我们必须阻止元素的这种默认的处理方式。
这个任务由 ondragover 事件的 event.preventDefault()
方法完成:
event.preventDefault()
第四步:进行放置 - ondrop
当放开被拖数据时,会发生 drop 事件。
在上面的实例中,ondrop 属性调用了一个函数 drop(event):
function drop(ev) {ev.preventDefault();var data = ev.dataTransfer.getData("text");ev.target.appendChild(document.getElementById(data));
}
代码说明:
- 调用 preventDefault() 来阻止数据的浏览器默认处理方式(drop 事件的默认行为是以链接形式打开)
- 通过 dataTransfer.getData() 方法获得被拖的数据。该方法将返回在 setData() 方法中设置为相同类型的任何数据
- 被拖数据是被拖元素的 id("drag1")
- 把被拖元素追加到放置元素中
如何在两个 <div>元素之间来回拖放图像:
<!DOCTYPE HTML>
<html>
<head>
<style>
#div1, #div2 {float: left;width: 100px;height: 35px;margin: 10px;padding: 10px;border: 1px solid black;
}
</style>
<script>
function allowDrop(ev) {ev.preventDefault();
}function drag(ev) {ev.dataTransfer.setData("text", ev.target.id);
}function drop(ev) {ev.preventDefault();var data = ev.dataTransfer.getData("text");ev.target.appendChild(document.getElementById(data));
}
</script>
</head>
<body><h2>拖放</h2>
<p>在两个 div 元素之间来回拖动图像。</p><div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"><img src="img_w3slogo.gif" draggable="true" ondragstart="drag(event)" id="drag1" width="88" height="31">
</div><div id="div2" ondrop="drop(event)" ondragover="allowDrop(event)"></div></body>
</html>
3.Html--本地存储
HTML 本地存储:优于 cookies。
通过本地存储(Local Storage),web 应用程序能够在用户浏览器中对数据进行本地的存储。
在 HTML5 之前,应用程序数据只能存储在 cookie 中,包括每个服务器请求。本地存储则更安全,并且可在不影响网站性能的前提下将大量数据存储于本地。
与 cookie 不同,存储限制要大得多(至少5MB),并且信息不会被传输到服务器。
本地存储经由起源地(origin)(经由域和协议)。所有页面,从起源地,能够存储和访问相同的数据。
HTML 本地存储对象
HTML 本地存储提供了两个在客户端存储数据的对象:
window.localStorage
- 存储没有截止日期的数据window.sessionStorage
- 针对一个 session 来存储数据(当关闭浏览器标签页时数据会丢失)
在使用本地存储时,请检测 localStorage 和 sessionStorage 的浏览器支持:
if (typeof(Storage) !== "undefined") {// localStorage/sessionStorage 的代码。
} else {// Sorry! 没有网络存储支持..
}
3.1.localStorage 对象
localStorage 对象存储的是没有截止日期的数据。当浏览器被关闭时数据不会被删除,在下一天、周或年中,都是可用的。
<!DOCTYPE html>
<html>
<body><div id="result"></div><script>
// Check browser support
if (typeof(Storage) !== "undefined") {// StorelocalStorage.setItem("lastname", "Smith");// Retrievedocument.getElementById("result").innerHTML = localStorage.getItem("lastname");
} else {document.getElementById("result").innerHTML = "抱歉,您的浏览器不支持网络存储...";
}
</script></body>
</html>
示例说明:
- 创建 localStorage 名称/值对,其中:name="lastname",value="Gates"
- 取回 "lastname" 的值,并把它插到 id="result" 的元素中
下面的例子对用户点击按钮的次数进行计数。在代码中,值字符串被转换为数值,依次对计数进行递增:
<!DOCTYPE html>
<html>
<head>
<script>
function clickCounter() {if (typeof(Storage) !== "undefined") {if (localStorage.clickcount) {localStorage.clickcount = Number(localStorage.clickcount)+1;} else {localStorage.clickcount = 1;}document.getElementById("result").innerHTML = "You have clicked the button " + localStorage.clickcount + " time(s).";} else {document.getElementById("result").innerHTML = "抱歉,您的浏览器不支持网络存储...";}
}
</script>
</head>
<body><p><button onclick="clickCounter()" type="button">单击我!</button></p>
<div id="result"></div>
<p>点击按钮可以看到计数器增加。</p>
<p>关闭浏览器选项卡(或窗口),重试,计数器会继续计数(不会重置)。</p></body>
</html>
3.2.sessionStorage 对象
sessionStorage
对象等同 localStorage 对象,不同之处在于只对一个 session 存储数据。如果用户关闭具体的浏览器标签页,数据也会被删除。
下例在当前 session 中对用户点击按钮进行计数:
<!DOCTYPE html>
<html>
<head>
<script>
function clickCounter() {if (typeof(Storage) !== "undefined") {if (sessionStorage.clickcount) {sessionStorage.clickcount = Number(sessionStorage.clickcount)+1;} else {sessionStorage.clickcount = 1;}document.getElementById("result").innerHTML = "You have clicked the button " + sessionStorage.clickcount + " time(s) in this session.";} else {document.getElementById("result").innerHTML = "抱歉,您的浏览器不支持网络存储...";}
}
</script>
</head>
<body><p><button onclick="clickCounter()" type="button">单击我!</button></p>
<div id="result"></div>
<p>点击按钮可以看到计数器增加。</p>
<p>关闭浏览器选项卡(或窗口),然后重试,计数器重置。</p></body>
</html>
4.Html--Web Workers API
web Workers 是在后台运行的 JavaScript,不会影响页面的性能。
在 HTML 页中执行脚本时,该页将变得无响应,直到脚本完成。
Web worker 是运行在后台的 JavaScript,独立于其他脚本,不会影响页面的性能。您可以继续做任何愿意做的事情:点击、选取内容等等,而此时 web worker 运行在后台。
<!DOCTYPE html>
<html>
<body><p>计数:<output id="result"></output></p>
<button onclick="startWorker()">开始工作</button>
<button onclick="stopWorker()">停止工作</button><p><strong>注意:</strong>Internet Explorer 9 及更早版本不支持 Web Workers。</p><script>
var w;function startWorker() {if (typeof(Worker) !== "undefined") {if (typeof(w) == "undefined") {// 使用 Blob 将 Worker 代码作为内联脚本const workerScript = `let count = 0;setInterval(() => {count++;postMessage(count);}, 500);`;// 创建一个 Blob 对象,类型为 JavaScriptconst blob = new Blob([workerScript], { type: 'application/javascript' });// 创建一个指向该 Blob 的 URLconst workerUrl = URL.createObjectURL(blob);// 使用这个 URL 创建 Workerw = new Worker(workerUrl);}w.onmessage = function(event) {document.getElementById("result").innerHTML = event.data;};} else {document.getElementById("result").innerHTML = "Sorry, your browser does not support Web Workers...";}
}function stopWorker() { if (w) {w.terminate();w = undefined;}
}
</script></body>
</html>
注释: web worker 通常不用于如此简单的脚本,而是用于更耗费 CPU 资源的任务。
由于 web worker 位于外部文件中,它们无法访问下例 JavaScript 对象:
- window 对象
- document 对象
- parent 对象
5.Html--SSE
什么是 SSE(Server-Sent Events)?
SSE 是一种让服务器主动向浏览器推送数据的技术。它建立一个长期连接,服务器可以随时发送数据,浏览器通过 EventSource
API 接收。
✅ 特点:单向通信(服务器 → 浏览器)
对比:
- Ajax:浏览器请求,服务器响应(拉取)
- WebSocket:双向通信
- SSE:服务器主动推送,浏览器接收(推送)
const express = require('express');
const app = express();// 静态文件服务(加载 public 文件夹下的 index.html)
app.use(express.static('public'));// SSE 接口
app.get('/api/sse', (req, res) => {res.writeHead(200, {'Content-Type': 'text/event-stream','Cache-Control': 'no-cache','Connection': 'keep-alive','Access-Control-Allow-Origin': '*'});// 每3秒发送一条普通消息const messageInterval = setInterval(() => {res.write(`data: 当前时间 ${new Date().toLocaleTimeString()}\n\n`);}, 3000);// 每5秒发送一个自定义事件(server-time)const timeInterval = setInterval(() => {res.write(`event: server-time\ndata: ${new Date().toISOString()}\nid: ${Date.now()}\n\n`);}, 5000);// 客户端断开时清理资源req.on('close', () => {console.log('客户端断开连接');clearInterval(messageInterval);clearInterval(timeInterval);res.end();});
});// 启动服务器
const PORT = 3000;
app.listen(PORT, () => {console.log(`🚀 服务器已启动:http://localhost:${PORT}`);console.log(`👉 请在浏览器中访问:http://localhost:${PORT}`);
});
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8" /><title>SSE 测试</title>
</head>
<body><h1>🎉 SSE 实时消息</h1><div id="messages"></div><script>if (typeof EventSource !== 'undefined') {const es = new EventSource('/api/sse');es.onmessage = function(event) {const p = document.createElement('p');p.textContent = '📩 ' + event.data;document.getElementById('messages').appendChild(p);};} else {document.body.innerHTML = '<p style="color:red;">❌ 浏览器不支持 SSE</p>';}</script>
</body>
</html>