从Template Literal用参数调用函数时出现JS错误

问题描述

我正在使用模板文字将内容插入页面:

entries.forEach((entry) => {
  let id = entry.id;
  entryList.innerHTML += `
  <div class="entry">
      <button class="delete-btn" onclick="deleteEntry(${id})">D</button>
  </div>`;
});

当我单击按钮时,我收到“未捕获的SyntaxError:无效或意外的令牌”。

但是,如果我改按按钮:

<button class="delete-btn" onclick="deleteEntry(3)">D</button>

该错误不会发生。

您能告诉我这里怎么了吗?谢谢。

解决方法

您的id值必须用引号引起来。您已经说过:

生成的HTML正是我想要的:<button class="delete-btn" onclick="deleteEntry(e5f7ce9a-1383-5d7c-9a9b-e8ce73d09041)">D</button>

但是在属性中查看该代码:

deleteEntry(e5f7ce9a-1383-5d7c-9a9b-e8ce73d09041)

这是语法错误。该字符串必须用引号引起来。

最小的更改是在'周围添加${id},假设您知道'永远不会出现在id值中:

entries.forEach((entry) => {
  let id = entry.id;
  entryList.innerHTML += `
    <div class="entry">
      <button class="delete-btn" onclick="deleteEntry('${id})'">D</button>
    </div>`;

...但是正如我在评论中所说,将+=innerHTML一起使用,以及使用onxyz-属性样式的事件处理程序通常都是不好的主意:

  • 执行element.innerHTML += "some string"时,浏览器必须遍历element中的整个DOM结构,并构建HTML字符串以传递给您的JavaScript代码。然后,您的JavaScript代码必须追加到字符串,并将其返回给浏览器。然后,浏览器必须完全删除element的所有内容,解析JavaScript代码给它的字符串,并为曾经存在的元素(然后再为新元素)构建新元素。这是很多不必要的工作,而且是有损失的:事件处理程序丢失,用户的聚焦元素(如果位于element中)丢失,并且表单元素中的当前选择丢失。相反,请考虑createElementappendChildinsertBeforeinsertAdjacentHTML,insertAdjacenText`和其他各种DOM方法。
  • onxyz属性类型的事件处理程序要求您发出语法有效的代码对其进行编码,以使其可以正确显示在属性中,并且只能使用全局函数。通常,最好避免使用全局功能。而是考虑使用现代事件处理,addEventListener等。这样也可以避免导致问题的问题(不输出语法有效的代码)。

例如:

entries.forEach(({id}) => {
    entryList.insertAdjacentHTML(
        "beforeend",`<div class="entry">
            <button class="delete-btn">D</button>
        </div>`
    );
    entryList.lastElementChild.querySelector("button").addEventListener(
        "click",() => deleteEntry(id)
    );
    // ...

这是我在那里做的:

  1. 我在参数列表中使用了结构分解,只挑选了对象的id属性,以使代码不会覆盖对象引用。
  2. 我使用insertAdjacentHTML将DOM结构添加到entryList 的末尾,而没有销毁并重新创建所有先前的元素。
  3. 我在新元素(querySelector)上使用了entryList.lastElementChild来获取按钮,并使用了addEventListener为其添加了事件处理程序。这样可以避免将id的值用引号引起来的麻烦,并且可以根据需要使deleteEntry为非全局值。
,

这是工作示例:

const entries = [{id: 1,text:'Hello World!'},{id: 2,text:'ABC'},{id: 3,text:'XYZ'}];

const entryList = document.querySelector('#entryList');

deleteEntry = function(id) {
  console.log('clicked id : ',id);
}

entries.forEach((entry) => {
  let id = entry.id;
  entryList.innerHTML += `
    <div class="entry">
      <button class="delete-btn" onclick="deleteEntry(${id})">D${id}</button>
    </div>`;
});
<div id="entryList"></div>

,

对于字符串文字,您必须使用引号

onclick=`deleteEntry(${id})`

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...