Getting an unexpected result when using JSON.stringify on an object within a literal template

问题: I am creating two links dynamically, one using template literals and another using document.createElement(), in both I need to pass as an attribute data-presentation an obj...

问题:

I am creating two links dynamically, one using template literals and another using document.createElement(), in both I need to pass as an attribute data-presentation an object as a string of characters. But I get different results.

When I inspect the link created using template literals I get the following result

<a href="#" data-presentations="[{" name":"cremas","measures":["5g","15g"]}]"="">Click</a>

And because it is badly formed when I need to parse it, I get an error return.

On the other hand, the link created using document.createElement () upon inspection returns the following result.

<a href="#" data-presentations="[{&quot;name&quot;:&quot;Cremas&quot;,&quot;measures&quot;:[&quot;5g&quot;,&quot;15g&quot;]}]">Another click</a>

And then when I need to parse it, it works properly.

Please take a look at the way are creatied the links

const root = document.querySelector('#root');
const object = {
    "id": 4,
    "name": "Medicine1",
    "code": "1234",
    "status": true,
    "location": "E4-2",
    "genericName": "SomeGenericName",
    "presentations": [
        {
            "name": "Cremas",
            "measures": [
                "5g",
                "15g"
            ]
        }
    ]
};

const link = `<a href="#" data-presentations="${JSON.stringify(object.presentations)}">Click</a>`

const anchor = document.createElement('a');

anchor.href = '#';
anchor.setAttribute('data-presentations', JSON.stringify(object.presentations));
anchor.textContent = 'Another click';

root.innerHTML = link;

document.body.appendChild(anchor)
<div id="root"></div>

What can I do so that the link created through template literals is correctly formed?


回答1:

You would need to escape your JSON according to the HTML context it’s used in. Double-quoted attribute value? Escape ampersands and double quotes:

const escapeDoubleQuoted = text =>
    text.replace(/&/g, '&amp;')
        .replace(/"/g, '&quot;');

Single-quoted attribute value? Escape ampersands and single quotes:

const escapeSingleQuoted = text =>
    text.replace(/&/g, '&amp;')
        .replace(/'/g, '&#39;');

If you wanted to include it in a <script>, you would need to escape < as x3c; and so on. So a correct version of the HTML-building approach would be:

const link = `<a href="#" data-presentations='${escapeSingleQuoted(JSON.stringify(object.presentations))}'>Click</a>`

The DOM is usually preferable when you don’t introduce HTML-building libraries because you don’t have to think about this.


回答2:

What can I do so that the link created through template literals is correctly formed?

Use single quotes ' surrounding JSON set as value of an HTML attribute

const root = document.querySelector('#root');
const object = {
    "id": 4,
    "name": "Medicine1",
    "code": "1234",
    "status": true,
    "location": "E4-2",
    "genericName": "SomeGenericName",
    "presentations": [
        {
            "name": "Cremas",
            "measures": [
                "5g",
                "15g"
            ]
        }
    ]
};

const link = `<a href="#" data-presentations='${JSON.stringify(object.presentations)}'>Click</a>`

const anchor = document.createElement('a');

anchor.href = '#';
anchor.setAttribute('data-presentations', JSON.stringify(object.presentations));
anchor.textContent = 'Another click';

root.innerHTML = link;

document.body.appendChild(anchor);

console.log(JSON.parse(root.firstElementChild.dataset.presentations));
<div id="root"></div>

  • 发表于 2019-02-25 18:52
  • 阅读 ( 222 )
  • 分类:sof

条评论

请先 登录 后评论
不写代码的码农
小编

篇文章

作家榜 »

  1. 小编 文章
返回顶部
部分文章转自于网络,若有侵权请联系我们删除