queryURLParams:获取一个URL地址问号传递的参数的值.
问号传参:
- 在页面跳转的时候,可以基于问号传参传递不同的信息,这样在跳转过去的页面中,就可以基于传递的不同参数信息展示不同的内容(例如:列表页面跳转到详情页面,详情页面展示不同的信息)
- 在以后我们的vue/react组件开发中,我们也可以基于问号参数实现不同组件之间的信息传递
- 客户端想要从服务器获取不一样的数据,也可以把一些值基于问号参数的方式传递给服务器端
- ...
需求:有一个URL地址 "www.yunduo.cn/index.html?…" , 需要我们编写一个方法 queryURLParams,执行这个方法可以获取指定的问号参数信息.
- 方法:
- queryURLParams:解析URL地址中的问号参数以及哈希值信息
- @params
- url[string]:要解析的URL地址.
- key[string]:在解析出来的结果中,获取到指定属性的属性值.
- @return
-
[object|string]全部解析出来的信息或者单一属性的信息. 方法一:
-
- @params
- queryURLParams:解析URL地址中的问号参数以及哈希值信息
//若当前url中不包括#,这种方法会出问题
function queryURLParams(url, key)
{
// 获取?和#的索引
var askIndex = url.indexOf('?'),
weiIndex = url.indexOf('#');
// 分别获取URL地址中?后面的信息以及#后面的信息
var askText = url.substring(askIndex + 1, weiIndex);
var weiText = url.substring(weiIndex + 1);
// 处理最后的结果
var obj = {};
obj['_hash'] = weiText; //往obj这个对象里增加一项
// askText => "lx=0&from=weixin" 先按照&拆成一个数组 ["lx=0", "from=weixin"];
// 遍历数组中的每一项,每一项继续按照 = 来拆,第一项变为数组["lx","0"] ,第二项变为数组["from","weixin"]
// 再把每一项拆成的数组中,第一项作为属性名,第二项作为属性值;
askText.split('&').forEach(function (item) //item是每次遍历数组中的当前项
//forEach遍历数组中的每一项时,触发function (item)执行,
// 每一项都执行function (item)函数中的语句,完成每一项按照 = 来拆,
// 再把每一项拆成的数组中,第一项作为属性名,第二项作为属性值.
{
item = item.split('=');//每一项继续按照 = 来拆,每一项都会变为数组["lx","0"] ["from","weixin"]
obj[item[0]] = item[1];//将item数组中第一项作为属性名,第二项作为属性值.
});
return obj;
}
var url = "http://www.yunduo.cn/index.html?lx=0&from=weixin#video";
var res1 = queryURLParams(url);
console.log(res1); // { lx:"0",from:'weixin',_hash:'video' }
结果为:
进阶1:容错处理 ,若当前url中不包括#时这种方法不会有问题
function queryURLParams(url, key)
{
//获取?和#的索引及内容
var askIndex = url.indexOf('?'),
weiIndex = url.indexOf('#'),
askText = '',
weiText = '',
obj = {};
//若#不存在,weiIndex === -1,我们让其等于最末尾的索引(最大索引还要+1)
//因为当从?往后截的时候,要截取到最后一项并且包含这一项,所以这时weiIndex = url.length-1+1.
weiIndex === -1 ? weiIndex = url.length : null;
//若#存在
if (weiIndex !== url.length)
{
//#存在则获取哈希值
weiText = url.substring(weiIndex + 1); //从#后面一项截到末尾
obj['_hash'] = weiText; //往obj这个对象里增加一项
}
//若?不存在就不处理了 askIndex == -1
//若?存在则处理?传参信息
if (askIndex > -1)
{
//存在?则处理?传参信息
askText = url.substring(askIndex + 1, weiIndex);
askText.split('&').forEach(function (item) {
item = item.split('=');
obj[item[0]] = item[1];
});
}
// A||B:A如果是假返回B的值,A如果是真返回A的值(只有五个值是假,其余都是真).
// A&&B:A如果是假返回A的值,A如果是真返回B的值.
//若传指定key的值了,则obj对象里返回的只是类型后面的值.
//如果定义了形参,但执行的时候没有传实参,默认形参的结果是undefined,
若传实参了则形参的结果就是传进来的实参.
//如果没有传实参,则返回obj,若传实参了则返回obj对象里key属性对应的属性值.
return typeof key !== "undefined" ?(obj[key] || '' ) : obj;
//obj[key] || '' 表示如果传进来的key不存在,会返回undefined,若不想让返回undefined,可以让返回空字符串,
//undefined代表假,当obj[key]为假时即传进来的key不存在,则返回空字符串.
}
var url = "http://www.yunduo.cn/index.html?lx=0&from=weixin#video";
var res1 = queryURLParams(url);
console.log(res1); // { lx:"0",from:'weixin',_hash:'video' }
var res2 = queryURLParams(url, 'lx');
console.log(res2); // "0"
结果为:
进阶2:简化获取内容的逻辑
function queryURLParams(url, key) {
var askText = '',
weiText = '',
obj = {};
// 简化获取?和#后面值的操作:利用a元素对象,会把一个URL的各部分解析出来.
(没有某部分信息,结果是空字符串,如果有这部分信息,则就可以获取这部分内容,对于search是带着?的,hash是带着#的)
var linkTemp = document.createElement('a'); //<a></a> 动态创建一个a元素标签
linkTemp.href = url; //把url的地址给a标签的href
askText = linkTemp.search; //=>?lx=0&from=weixin
weiText = linkTemp.hash; //=>#video
//此时得到的结果中是带着?和#号的,我们需要把#和?拿掉.
// #存在则获取哈希值,从索引1开始截.当weiText存在即为1(因为weiText如果不存在返回undefined即为假),
if(weiText) //当weiText存在即为1时,
{
obj['_hash'] = weiText.substring(1) : null;
}
//weiText ? obj['_hash'] = weiText.substring(1) : null;
// ?存在则处理问号传参信息.
if (askText) //当askText存在即为1(因为askText如果不存在返回undefined即为假)
{
askText = askText.substring(1);//从索引1开始截取 =>"lx=0&from=weixin"这种格式.
//简化逻辑:基于URLSearchParams简化(这个类就是获取一个问号参数的信息的)
var usp = new URLSearchParams(askText);
usp = [...usp.entries()];
usp.forEach(function (item) {
obj[item[0]] = item[1];
});
}
return typeof key !== "undefined" ?
obj[key] || '' :
obj;
}
var url = "http://www.yunduo.cn/index.html?lx=0&from=weixin#video";
var res1 = queryURLParams(url);
console.log(res1); // { lx:"0",from:'weixin',_hash:'video' }
var res2 = queryURLParams(url, 'lx');
console.log(res2); // "0"
结果为:
终极进阶:使用正则几行代码就搞定
function queryURLParams(url, key) {
var obj = {};
//想获得#后面的1到多位的值,只要不是?,=和#.
url.replace(/#([^?=&#]+)/g, function (_, hash) //一般定义下划线的形参只是为了占位
//用function (_, hash){}函数生成的的文本替换了/#([^?=&#]+)/g正则表达式匹配的值.
{
obj['_hash'] = hash;
});
url.replace(/([^?=&#]+)=([^?=&#]+)/g, function (_, key, value) {
obj[key] = value;
});
return typeof key !== "undefined" ?
obj[key] || '' :
obj;
}
var url = "http://www.yunduo.cn/index.html?lx=0&from=weixin#video";
var res1 = queryURLParams(url);
console.log(res1); // { lx:"0",from:'weixin',_hash:'video' }
var res2 = queryURLParams(url, 'lx');
console.log(res2); // "0"
结果为: