将对象文字扩展为html5数据属性

时间:2017-10-08 15:27:11

标签: javascript

可以将对象文字扩展为html5数据属性吗?

有以下对象:

const requirements = {
    'data-description': 'some text...',
    'data-pointer': true,
    'data-speaker': true
}

我想在锚标记中扩展它以获得类似的内容:

<a href="#" class="show-modal" data-description="some-text" data-pointer="true" data-speaker="true">Show modal</a>

我尝试以这种方式使用传播语法<a href="#" class="show-modal" `${...requirements}`>Show modal</a>但是没有打印

我现在依赖于这个构建锚点并动态传递数据的函数。

function buildAnchor(requirements) {
    const anchor = document.createElement('a');

    anchor.setAttribute('class', 'show-modal');
    anchor.setAttribute('href', '#');
    anchor.textContent = 'More info';

    Object.keys(requirements).forEach(data => {
        anchor.setAttribute(data, requirements[data]);
    });

    return anchor.outerHTML;
}

此功能可以完成这项工作,但我想知道是否可以使用扩展语法

提前致谢

4 个答案:

答案 0 :(得分:3)

如何直接使用HTMLElement's dataset property然后通过Object.assign为其分配简化的配置对象... ... ...

&#13;
&#13;
var requirements = {
  'description': 'some text...',
  'pointer': true,
  'speaker': true
};
var elmLink = document.createElement('a');

elmLink.href = '';
Object.assign(elmLink.dataset, requirements);

console.log('elmLink : ', elmLink);
&#13;
.as-console-wrapper { max-height: 100%!important; top: 0; }
&#13;
&#13;
&#13;

答案 1 :(得分:1)

您可以将data-*属性定义为单个JSON字符串,然后使用JSON.parse()创建.dataset属性的JavaScript对象表示。

请注意模板文字中围绕HTML字符串有效JSON的属性值的单引号。

&#13;
&#13;
const requirements = {
    'description': 'some text...',
    'pointer': true,
    'speaker': true
}

const a = `<a data-requirements='${JSON.stringify(requirements)}'>click</a>`;

document.body.insertAdjacentHTML("beforeend", a);

let data = JSON.parse(document.querySelector("a").dataset.requirements);
           
console.log(data, data.description, data.pointer, data.speaker);
&#13;
&#13;
&#13;

答案 2 :(得分:0)

传播语法不会做你想要的。这实际上是将键/值对从一个对象包含到另一个对象中,或者用于解构赋值。

您可以在模板文字中使用Object.entries() .map().join()

&#13;
&#13;
const requirements = {
  'data-description': 'some text...',
  'data-pointer': true,
  'data-speaker': true
};
const s = `<a href="#" class="show-modal" ${Object.entries(requirements).map(([k, v]) => k + "='" + v + "'").join(" ")}>Show modal</a>`;

console.log(s);
&#13;
&#13;
&#13;

我认为将属性创建移动到自己的函数中会更清晰。

&#13;
&#13;
const requirements = {
  'data-description': 'some text...',
  'data-pointer': true,
  'data-speaker': true
};
const s = `<a href="#" class="show-modal" ${oToA(requirements)}>Show modal</a>`;

console.log(s);

function oToA(obj) {
  return Object.entries(obj)
               .map(([k, v]) => k + "='" + v + "'")
               .join(" ")
}
&#13;
&#13;
&#13;

您可以通过用HTML实体替换嵌入式引号来增强功能。

答案 3 :(得分:0)

来自 MDN:

  

Spread语法允许迭代,例如数组表达式   在零或多个参数的地方扩展(用于函数调用)   或元素(对于数组文字)是期望的,或对象表达式   在零或更多键值对的地方扩展(for   对象文字是预期的。

由于您正在尝试构建一个将需求作为参数(而不是键/值对)的函数,因此数组结构比对象结构更有意义。

&#13;
&#13;
const requirements = [
    {'data-description': 'some text...'},
    {'data-pointer': true},
    {'data-speaker': true}
];

(function populate(){
  var anchor = document.createElement("a");
  // Convert the arguments object to an array and enumerate it
  // so that each object key can become an attribute and the 
  // corresponding value can become the value:
  Array.prototype.slice.call(arguments).forEach(function(arg){
    for(var prop in arg){
      anchor.setAttribute(prop, arg[prop]);
    }
  });
  console.log(anchor);
})(...requirements);
&#13;
&#13;
&#13;