/*
queryURLParams: 获取一个URL地址问号传递的参数的值
问号传参:
+ 在页面跳转的时候,可以基于问号传参传递不同的信息,这样在跳转过去的页面中,就可以基于传递不同的内容(例如:
列表页面跳转到详情页面,详情页面展示不同的信息)
+ 在以后我们的vue/react组件开发中,我们也可以基于问号参数实现不同组件之间的信息传递
+ 客户端想要从服务器获取不一样的数据,也可以把一些值基于问号参数的方式传递给服务器端
+ ...
*/
// 面试题:
// 有一个URL地址 "http://www.zhufengpeixun.cn/index.html?lx=0&from=weixin#video",需要我们编写一个方法
// queryURLParams,执行这个方法可以获取指定的问号参数信息
/*
queryURLParams: 解析URL地址中的问号参数已经哈希值信息
@params
* url[string]:要解析的URL地址
key[string]:在解析出来的结果中,获取到指定属性的属性值
@return
[object | string]全部解析出来的信息或者单一属性的信息
by zhouxiaotian on 2020/08/14 10:03
*/
// 最初版 (未传key)
/* function queryURLParams(url, key) {
// 获取?和#的索引
var askIndex = url.indexOf("?"),
weiIndex = url.indexOf('#')
// 分别获取URL地址中问号后面的信息以及#后面的信息s
var aksText = url.substring(askIndex + 1, weiIndex)
var weiText = url.substring(weiIndex + 1)
// console.log(askIndex, weiIndex, aksText, weiText); // 38 55 'lx=0&from=weixin' 'video'
// 处理最后的结果
var obj = {}
obj['_hash'] = weiText
// aksText => "lx=0&from=weixin" 先按照&拆成一个数组 ["lx=0","from=weixin"];遍历数据中的每一项,
// 每一项继续按照 = 来拆,每一项都会变为数组(["lx","0"]) ; 把每一项拆成数组中,第一项作为属性名,第二项作为属性值
aksText.split('&').forEach((item) => {
item = item.split('=')
obj[item[0]] = item[1]
});
return obj
} */
// var url = "http://www.zhufengpeixun.cn/index.html?lx=0&from=weixin#video"
// var res1 = queryURLParams(url)
// 传key ↓
// {;x:0,from:'weixin',_hash:'video'}
// console.log(res1); // 未传key
// 进阶1:容错处理
function queryURLParams(url, key) {
// 获取?和#的索引及内容
var askIndex = url.indexOf("?"),
weiIndex = url.indexOf('#'),
aksText = '',
weiText = '',
obj = {}
// #不存在,我们让其等于末尾的索引(最大索引还要+1 就是length)
weiIndex === -1 ? weiIndex = url.length : null
if (weiIndex !== url.length) {
// 存在#则获取哈希值
weiText = url.substring(weiIndex + 1)
obj['_hash'] = weiText
}
// ?不存在就不处理了
if (askIndex > -1) {
// 存在?则处理问号传参
var aksText = url.substring(askIndex + 1, weiIndex)
aksText.split('&').forEach((item) => {
item = item.split('=')
obj[item[0]] = item[1]
});
}
// A||B:A如果是假返回B的值,A如果是真返回A的值(只有五个值是假,其余都是真)
// A&&B:A如果是假返回A的值,A如果是真返回B的值
return typeof key !== "undefined" ? obj[key] || '' : obj
}
var url = "http://www.zhufengpeixun.cn/index.html?lx=1#a"
console.log(res1);
var res2 = queryURLParams(url, 'lx') // 0
console.log(res2);
简单方法:
function queryURLParams(url, key) {
var aksText = '',
weiText = '',
obj = {}
// 简化获取?和#后面值的操作: 利用A元素对象,会把一个URL的各部分解析出来(没有某部分信息,
// 结果是空字符串, 如果有这部分信息,则就可以获取这部分内容,对于search/hash是带着?和#的)
var linkTemp = document.createElement('a')
linkTemp.href = url
aksText = linkTemp.search
weiText = linkTemp.hash
linkTemp = null // 释放内存
// console.log(aksText, weiText);
// 存在#则获取哈希值
weiText ? obj['_hash'] = weiText.substring(1) : null
// 存在?则处理问号传参
if (aksText) {
aksText = aksText.substring(1)
// 简化逻辑: 基于URLSearchParams简化(这个类就是获取一个问号参数的信息的
var usp = new URLSearchParams(aksText)
console.log(...usp.values()); // 0 weixin
console.log(...usp.entries()); // (2) ['lx', '0'] (2) ['from', 'weixin']
usp = [...usp.entries()]
console.log(usp);
usp.forEach((item) => {
obj[item[0]] = item[1]
})
}
return typeof key !== "undefined" ? obj[key] || '' : obj
}
var url = "http://www.zhufengpeixun.cn/index.html?lx=0&from=weixin#video"
var res2 = queryURLParams(url, 'lx') // 0
console.log(res2);
终极方案(正则):
// 终极进阶: 使用正则几行代码就搞定
function queryURLParams(url, key) {
var obj = {}
url.replace(/#([^?=&#]+)/g, function(_, hash) {
obj['_hash'] = hash
})
url.replace(/([^?=&#]+)/g, function(_, key, value) {
obj[key] = value
})
return typeof key !== "undefined" ? obj[key] || '' : obj
}
var url = "http://www.zhufengpeixun.cn/index.html?lx=0&from=weixin#video"
var res1 = queryURLParams(url) // 0
console.log(res1);
var res2 = queryURLParams(url, 'from')
console.log(res2);