小发现之浅谈location.search与location.hash的问题

标题:小发现之浅谈location.search与location.hash的问题

标题:小发现之浅谈location.search与location.hash的问题

背景介绍

location.search与location.hash是前端开发中常用的两个属性,它们分别用于获取当前url中带的查询参数和锚点参数。这两个属性的使用方式不同,而且在某些情况下会出现一些问题,需要特别注意。

location.search与location.hash的区别

location.search

location.search是获取当前url中的查询参数,格式为?key=value。当出现多个查询参数时,每个参数之间用&符号分隔开来。这个属性返回的值是一个字符串,不包含?符号。举个例子:

当前url:https://www.example.com/search?keyword=apple&category=fruit&page=2
则 location.search 的值为:keywork=apple&category=fruit&page=2

location.hash

location.hash是获取当前url中的锚点参数,格式为#value。锚点参数用于在网页中内部跳转定位,点击链接时可以滚动到相应位置。它不会触发页面刷新。举个例子:

当前url:https://www.example.com/about#contact
则 location.hash 的值为:#contact

使用注意事项

获取查询参数时注意转义问题

当使用location.search获取查询参数时,需要注意参数中可能包含特殊字符(如&、?、=等),这时就需要进行encodeURIComponent编码,否则可能会出现解析错误的问题。比如:

假设跳转到了如下url,其中keyword参数包含了&和=符号:
https://www.example.com/search?keyword=apple&banana=100g=red
则 location.search 的值为:?keyword=apple&banana=100g=red
显然这个值是不正确的,因为&和=符号既用来分隔参数,但也是参数内容中可能出现的字符。
正确的做法是先进行编码,再进行解析:
let params = location.search.substring(1);
let parsedParams = new URLSearchParams(params);
let keyword = decodeURIComponent(parsedParams.get('keyword'));

在锚点参数中使用中文

在锚点参数中使用中文时,需要使用encodeURI进行编码,否则浏览器可能会出现不同的解析结果:

假设跳转到了如下url,其中锚点参数为中文:
https://www.example.com/about#联系我们
则在某些浏览器中,location.hash的值为:#%E8%81%94%E7%B3%BB%E6%88%91%E4%BB%AC
而在另外一些浏览器中,location.hash的值为:#联系我们
为了解决这个问题,需要在跳转时先进行编码:
let anchor = encodeURI('联系我们');
window.location.href = `https://www.example.com/about#${anchor}`;

示例说明

示例1

假设我们需要在页面中显示当前url中的查询参数,可以使用如下代码:

<ul id="query-params"></ul>

<script>
  let params = location.search.substring(1);
  let parsedParams = new URLSearchParams(params);

  parsedParams.forEach((value, key) => {
    let li = document.createElement('li');
    li.textContent = `${key}: ${value}`;
    document.getElementById('query-params').appendChild(li);
  });
</script>

当跳转到https://www.example.com/search?keyword=apple&category=fruit&page=2时,会在页面中显示如下内容:

- keyword: apple
- category: fruit
- page: 2

示例2

假设我们需要在页面中实现跳转到不同章节的功能,当用户点击“目录”中的某个链接时,页面会自动滚动到相应的章节。可以使用如下代码:

<ul id="toc">
  <li><a href="#chapter1">第一章</a></li>
  <li><a href="#chapter2">第二章</a></li>
  <li><a href="#chapter3">第三章</a></li>
</ul>

<h1 id="chapter1">第一章</h1>
<p>这里是第一章的内容</p>

<h1 id="chapter2">第二章</h1>
<p>这里是第二章的内容</p>

<h1 id="chapter3">第三章</h1>
<p>这里是第三章的内容</p>

<script>
  let toc = document.getElementById('toc');
  toc.addEventListener('click', (e) => {
    e.preventDefault();
    let target = e.target.getAttribute('href');
    let anchor = encodeURI(target.substring(1));
    window.location.href = `https://www.example.com/book${target}`;
    window.location.reload();
    // 在加载完成后进行页面滚动
    window.addEventListener('load', () => {
      window.scrollTo({top: document.querySelector(target).offsetTop, behavior: 'smooth'});
    });
  });
</script>

在用户点击“目录”中的某个链接时,页面会跳转到对应的章节,并自动滚动到该章节的位置。

本文标题为:小发现之浅谈location.search与location.hash的问题

基础教程推荐