【前端:Html】--5.进阶:APIs

发布于:2025-09-08 ⋅ 阅读:(14) ⋅ 点赞:(0)

目录

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; // 海拔(米),可能为 null
      const 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") {
  // Store
  localStorage.setItem("lastname", "Smith");
  // Retrieve
  document.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 对象,类型为 JavaScript
      const blob = new Blob([workerScript], { type: 'application/javascript' });

      // 创建一个指向该 Blob 的 URL
      const workerUrl = URL.createObjectURL(blob);

      // 使用这个 URL 创建 Worker
      w = 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>


网站公告

今日签到

点亮在社区的每一天
去签到