JS拼接字符串的过程中将JSON对象存到某个标签的属性中,encodeURIComponent(),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/

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

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
JavaScript,处理JSON字符串时,如果其包含文字符,有时可能会遇到乱码问题。这是因为默认情况下,浏览器或JavaScript引擎可能使用的是ASCII编码或者其他单字节编码,而JSON是基于UTF-8编码的,文字符占用两个字节。 解决这个问题有几种方法: 1. **换编码**:在读取或写入JSON字符串之前,确保其已经被正确地换为UTF-8编码。你可以使用`TextDecoder`或`JSON.parse()`的`reviver`函数来实现。例如: ```javascript let utf8String = unescape(encodeURIComponent(jsonStr)); // 先义再解码 let decodedJson = JSON.parse(utf8String, (key, value) => { if (typeof value === 'string') { return decodeURIComponent(escape(value)); } return value; }); ``` 2. **设置Content-Type**:如果你是在服务器端处理JSON,确保你的响应头包含了正确的`Content-Type: application/json; charset=utf-8`,这样浏览器会知道接收的数据是UTF-8编码。 3. **使用ES6的`JSON.stringify()`和`JSON.parse()`**:它们自动处理了字符编码问题,你不需要手动换。但是,如果你在使用其他库或者不支持这些特性的环境,上述方法就适用。 4. **使用第三方库**:一些库,如`json-stringify-safe`,可以帮助处理JSON字符串的编码问题。 相关问题: 1. JavaScript内置的哪些方法可以处理JSON字符串的编码问题? 2. 如果在Node.js环境处理,如何设置响应头来指定编码? 3. 除了`JSON.parse()`,还有哪些方法可以在JavaScript解析JSON时保持文字符正确显示?
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值