当前位置: 代码迷 >> 综合 >> JS拼接字符串的过程中将JSON对象存到某个标签的属性中,encodeURIComponent(),btoa()用法介绍
  详细解决方案

JS拼接字符串的过程中将JSON对象存到某个标签的属性中,encodeURIComponent(),btoa()用法介绍

热度:4   发布时间:2023-12-22 11:28:20.0

JS拼接字符串的过程中将JSON对象存到某个标签的属性中

  • JS拼接字符串的过程中将JSON对象存到某个标签的属性中,encodeURIComponent(),btoa()用法介绍
    • 案例描述
    • 实现方法
      • 方法1
      • 方法2
      • 方法3
        • JS拼接li标签,JSON对象转字符串,双引号引发的问题
        • 解决方法1:JSON.stringfy()后再使用encodeURIComponent()方法进行编码
        • 解决方法2:JSON.stringfy()后再使用btoa()方法进行编码

JS拼接字符串的过程中将JSON对象存到某个标签的属性中,encodeURIComponent(),btoa()用法介绍

最近在做前端项目的时候频繁使用JS拼接HTML代码,然后使用InnerHTML将内容填充到网页中,在循环拼接ul的列表项li的时候需要将不同的JSON对象绑定到相应的li上,后面再给每一个li动态绑定点击事件,最后在事件中获取被点击的li上绑定的JSON对象。下面举例说明在这个问题上我踩的坑,也给大家提供参考方案。

案例描述

这里只是为了演示解决方法,对html和js的代码做了精简,方便大家阅读

假设我通过AJAX从后端获取到了如下JSON数组:

var friends = [{
    friendUserId: "111",friendUsername: "zhangsan",friendNickname: "zhangsan111",friendFaceImage: "image/1.jpg",},{
    friendUserId: "222",friendUsername: "lisi222",friendNickname: "lisi",friendFaceImage: "image/1.jpg",},{
    friendUserId: "333",friendUsername: "wangwu333",friendNickname: "wangwu",friendFaceImage: "image/1.jpg",},
]

然后我页面上有一个ul标签,我现在需要遍历这个JSON数组,将每一个JSON对象的friendNickname和friendFaceImage取出来用于渲染一个li标签,类似下面这样一个列表。

ul联系人列表

拼接li标签的js代码如下所示:(为了方便大家看清这个li标签的结构,我去掉了class属性和一些样式的代码,只是保留了最基本的结构。)

var lis = [];
for(var i = 0; i < friends.length; i++) {
    var friend = friends[i];var liHtml =  '<li>' +'<img src="' + friend.friendFaceImage + '">' +'<div>' +friend.friendNickname +'</div>' +'</li>';lis.push(liHtml);
}
// 将li标签的HTML代码动态添加到ul标签中
document.getElementById("ul_friends").innerHTML = lis.join('');

除此之外,我还需要把这个JSON对象绑定到这个li标签上,以便后期我为所有li标签添加点击事件的时候,可以获取到对应的JSON对象。为此我想到了三种方法。

实现方法

方法1

首先我最先想到的方法是:遍历JSON数组拼接li标签的时候,在每一个li标签上面自定义属性,每一个属性对应JSON对象中的属性。基于上面的代码修改之后如下所示:

var lis = [];
for(var i = 0; i < friends.length; i++) {
    var friend = friends[i];var liHtml =  '<li friendUserId="' + friendUserId + ' friendUsername="' + friendUsername + ' friendNickname="' + friendNickname + ' friendFaceImage="' + friendFaceImage + '>' +'<img src="' + friend.friendFaceImage + '">' +'<div>' +friend.friendNickname +'</div>' +'</li>';lis.push(liHtml);
}
// 将li标签的HTML代码动态添加到ul标签中
document.getElementById("ul_friends").innerHTML = lis.join('');

后面遍历li标签为其绑定点击事件的时候,只需要通过被点击的li标签的getAttrbute('属性名')方法获取对应到对应的属性即可。

方法2

第一种方法虽然能够实现功能,但是太麻烦,需要自定义JSON对象中的所有属性,如果是只是自定义一两个属性还好,如果自定义的属性十几二十个甚至更多,那么这种做法简直就是噩梦,所以我想到了第二种方法:

将这个JSON数组设置成全局变量,然后在循环遍历JSON数组,拼接li标签的时候,为每个li标签添加一个自定义属性index,index的值就是循环变量的值,比如遍历第0个JSON对象,index=0

var lis = [];
for(var i = 0; i < friends.length; i++) {
    var friend = friends[i];// 将循环变量(JSON数组的下标)存到每一个li标签的index属性中var liHtml =  '<li index="' + i + '">' +'<img src="' + friend.friendFaceImage + '">' +'<div>' +friend.friendNickname +'</div>' +'</li>';lis.push(liHtml);
}
// 将li标签的HTML代码动态添加到ul标签中
document.getElementById("ul_friends").innerHTML = lis.join('');

后面遍历所有的li标签,添加点击事件的时候,可以取出li标签的index的值,根据index的值就可以找到JSON数组中的对应的JSON对象。

方法3

第二种方法很简单,但是不够直观,难道就不能在每次循环的时候把JSON对象转成字符串,直接存到li标签的自定义属性中去吗?想到这里我就进行了尝试,也就是第三种方法,代码如下:

var lis = [];
for(var i = 0; i < friends.length; i++) {
    var friend = friends[i];// 在li中添加friend属性,将JSON对象转成字符串之后存到该属性下var liHtml =  '<li friend="' + JSON.stringify(friend) + '">' +'<img src="' + friend.friendFaceImage + '">' +'<div>' +friend.friendNickname +'</div>' +'</li>';lis.push(liHtml);
}
// 将li标签的HTML代码动态添加到ul标签中
document.getElementById("ul_friends").innerHTML = lis.join('');

JS拼接li标签,JSON对象转字符串,双引号引发的问题

不过在后续获取所有的li标签,绑定点击事件,获取li标签的friend属性的值的时候出现了问题,我打印了这个值,只有一个{ ,经过仔细观察之后我找到了问题,原来是JSON对象通过JSON.stringfy()方法转成字符串之后,会有一堆双引号,例如:

// 现有一个friend对象
var friend = {
    friendUserId: "111",friendUsername: "zhangsan",friendNickname: "zhangsan111",friendFaceImage: "image/1.jpg"
}
// 通过JSON.stringfy()方法转成字符串
console.log(JSON.stringfy(friend));
// 控制台的输出结果
{
    "friendUserId":"111","friendUsername":"zhangsan","friendNickname":"zhangsan111","friendFaceImage":"image/1.jpg"}

可以看到JSON.stringfy(friend)后的字符串中包含了很多双引号,而直接将这个字符串通过拼接,存到li标签的friend属性中去,就会破坏原li标签的结构。所以这里在转成字符串之后还需要对双引号进行转义或者将编码。

经过查阅资料,我再次找到了好方法,下面提供两种解决方法:

解决方法1:JSON.stringfy()后再使用encodeURIComponent()方法进行编码

console.log(encodeURIComponent(JSON.stringfy(friend)))
// 控制台的输出结果为
%7B%22friendUserId%22%3A%22111%22%2C%22friendUsername%22%3A%22zhangsan%22%2C%22friendNickname%22%3A%22zhangsan111%22%2C%22friendFaceImage%22%3A%22image%2F1.jpg%22%7D

可以看到{ 被编码成了%7B,}被编码成了%7D,双引号被编码成了%22,冒号被编码成了%3A,经过编码后的字符串再丢到li中的某个属性中存起来,这样就不会出现问题了。

相应地,从li中取出这个经过编码的JSON.stringfy()后的字符串,同样还需要再解码后才能JSON.parse(),解码的方法是decodeURIComponent()

上面出问题的JS代码修改如下:

var lis = [];
for(var i = 0; i < friends.length; i++) {
    var friend = friends[i];// 在li中添加friend属性,将JSON对象转成字符串之后存到该属性下var liHtml =  '<li friend="' + encodeURIComponent(JSON.stringfy(friend)) + '">' +'<img src="' + friend.friendFaceImage + '">' +'<div>' +friend.friendNickname +'</div>' +'</li>';lis.push(liHtml);
}
// 将li标签的HTML代码动态添加到ul标签中
document.getElementById("ul_friends").innerHTML = lis.join('');

解决方法2:JSON.stringfy()后再使用btoa()方法进行编码

官方对btoa()方法的定义和用法作了如下解释:

btoa() 方法用于创建一个 base-64 编码的字符串。

该方法使用 “A-Z”, “a-z”, “0-9”, “+”, “/” 和 “=” 字符来编码字符串。

console.log(btoa(JSON.stringfy(friend)))
// 控制台的输出结果为
"eyJmcmllbmRVc2VySWQiOiIxMTEiLCJmcmllbmRVc2VybmFtZSI6InpoYW5nc2FuIiwiZnJpZW5kTmlja25hbWUiOiJ6aGFuZ3NhbjExMSIsImZyaWVuZEZhY2VJbWFnZSI6ImltYWdlLzEuanBnIn0="

相应地,从li中取出这个经过编码的JSON.stringfy()后的字符串,同样还需要再解码后才能JSON.parse(),解码的方法是atob()

上面出问题的JS代码修改如下:

var lis = [];
for(var i = 0; i < friends.length; i++) {
    var friend = friends[i];// 在li中添加friend属性,将JSON对象转成字符串之后存到该属性下var liHtml =  '<li friend="' + btoa(JSON.stringfy(friend)) + '">' +'<img src="' + friend.friendFaceImage + '">' +'<div>' +friend.friendNickname +'</div>' +'</li>';lis.push(liHtml);
}
// 将li标签的HTML代码动态添加到ul标签中
document.getElementById("ul_friends").innerHTML = lis.join('');

我在碰到相应问题的时候参考了这篇博客:https://www.codenong.com/8542746/

到这里所描述的问题就彻底解决了,博客中有什么不对的地方还请大家评论区指正!!!

  相关解决方案