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

yizhihongxing

标题:小发现之浅谈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的问题 - Python技术站

(0)
上一篇 2023年6月11日
下一篇 2023年6月11日

相关文章

  • javascript中String类的subString()方法和slice()方法

    当我们需要对字符串进行裁剪或切片操作时,JavaScript中的String类提供了两个常用的方法:substring()和slice()。这两种方法都能够将一个字符串切分为多个子串,但它们有一些不同之处。 substring()方法 substring()方法用于将字符串中的一部分截取出来,返回一个新的字符串。其接受两个参数,分别代表子字符串的起始位置和终…

    JavaScript 2023年5月28日
    00
  • 怎么限制input的text里输入的值只能是数字(正则、js)

    限制 input 标签的 text 输入只能是数字,可以通过正则表达式和 JavaScript 实现。 方法1:使用正则表达式限制输入 在 html 中 input 标签内使用 pattern 属性来设置正则表达式,如下所示: <input type="text" pattern="[0-9]*" placeho…

    JavaScript 2023年6月10日
    00
  • JavaScript深拷贝的几种实现方法实例

    为什么需要深拷贝? 在 JavaScript 中,对象和数组是通过引用赋值的方式传递的。如果直接将一个对象或数组赋值给另一个变量,那么这两个变量其实指向的是同一个对象或数组。因此,如果修改其中一个变量所指向的对象或数组的值,那么另一个变量也会受到影响。这就是浅拷贝的特点。为了避免这种情况的发生,我们需要进行深拷贝,即创建一个新的对象或数组,其中所有的值都是原…

    JavaScript 2023年5月27日
    00
  • js制作轮播图效果

    下面是详细讲解“js制作轮播图效果”的完整攻略: 1. 确定需求 首先确定需求,也就是轮播图的要求。比如需要自动播放、可以手动切换、需要圆点分页器等等。根据不同的需求,我们会采用不同的实现方法。 在这里,我们暂定轮播图的基本要求为:自动播放、手动切换、圆点分页器。 2. HTML结构 根据需求,确定好HTML结构的基本框架,比如轮播图盒子、轮播图图片、圆点分…

    JavaScript 2023年6月11日
    00
  • js验证电话号码与手机支持+86的正则表达式

    要验证电话号码与手机是否支持+86,我们需要使用正则表达式。 以下是一个通用的正则表达式,用于检查电话号码或手机号是否正确: /^((0\d{2,3}-\d{7,8})|(1[34578]\d{9}))$/ 让我们详细分析这个正则表达式: ^表示字符串开头。 (表示一个捕获分组的开始。 0\d{2,3}-\d{7,8}匹配固定电话号码,其中0后面是2或3个数…

    JavaScript 2023年6月10日
    00
  • JavaScript在控件上添加倒计时功能的实现代码

    下面是关于“JavaScript在控件上添加倒计时功能的实现代码”的完整攻略。 1. 实现思路 要在控件上添加倒计时功能,需要实现以下几步: 获取需要显示倒计时的控件对象; 设置倒计时的总时间(例如60秒)和时间间隔(例如每一秒钟); 创建一个计时器,定时更新控件上显示的倒计时时间; 到达倒计时结束时间后,清除计时器。 2. 实现代码示例 以下是两个实现倒计…

    JavaScript 2023年6月11日
    00
  • JavaScript数组对象实现增加一个返回随机元素的方法

    实现一个返回随机元素的方法,我们可以通过 JavaScript 的数组对象原型添加一个静态方法实现。 下面是实现步骤: 1.首先,在数组对象原型上添加一个随机获取数组元素的方法。 Array.prototype.getRandomItem = function() { return this[Math.floor(Math.random() * this.l…

    JavaScript 2023年6月10日
    00
  • JS中call apply bind函数手写实现demo

    下面是关于“JS中call apply bind函数手写实现demo”的攻略: 理解call、apply、bind函数 在手写这三个函数的过程中,我们必须先清楚地理解这三个函数的作用: call函数:调用一个函数,将一个对象作为第一个参数,以及多个参数传入该函数。 apply函数:调用一个函数,将一个对象作为第一个参数,以及一个参数数组传入该函数。 bind…

    JavaScript 2023年6月10日
    00
合作推广
合作推广
分享本页
返回顶部