在模板文字中设置 HTML Button`onclick`

Ell*_*ary 7 html javascript html5-template template-literals

我有一个 html 模板,我正在使用模板文字。该函数如下所示

// postCreator.js
export const blogPostMaker = ({ title, content, address, id }, deletePost) => {
  const innerHtml = `
  <blog-post>
    <h1 class='title'>${title}</h1>
    <p class='content'>${content}</p>
    <p class='address'>${address}</p>
    <button onclick='${() => deletePost(id)}'>Delete</button>
  </blog-post>
  `
  return innerHtml
}


//Blog.js
  postHelper.getSeriesOfPosts(10)
  .then(resp => {
    resp.forEach(post => (blogDiv.innerHTML += blogPostMaker(post, postHelper.deletePost)))
  })
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚的是如何让 onclick 工作。我试过将 anon 函数传递Blog.js给 thepostCreator也没有运气。

有任何想法吗?

max*_*uty 6

Miroslav Savovski 的解决方案有效,但他们没有解释原因,所以我想我应该添加这个答案及其背后的推理,并逐步说明它实际上是如何工作的,以及为什么 OP 的解决方案最初不起作用。

太长了?滚动到最后两个代码片段。

使用模板文字,当您将函数放入其中时,它会执行该函数,所以假设我们有一个像这样的简单函数,它只返回一个字符串'blue'

const getBlueColor = () => 'blue'
Run Code Online (Sandbox Code Playgroud)

然后我们在模板文字中调用这个函数,如下所示:

`The color is ${getBlueColor()}`
Run Code Online (Sandbox Code Playgroud)

发生的情况是getBlueColor()在执行该代码时立即调用 。

现在假设我们想onclick这样做:

<button onclick="${getBlueColor()}"></button>
Run Code Online (Sandbox Code Playgroud)

正在发生的事情是getBlueColor没有被执行onclick,它实际上是在执行模板文字时执行的。

我们解决这个问题的方法是通过简单地删除模板文字来防止模板文字执行此函数:

<button onclick="getBlueColor()"></button>
Run Code Online (Sandbox Code Playgroud)

但现在假设您想将一些参数传递给如下所示的函数getOppositeColor(color)

<button onclick="getOppositeColor(color)"></button>
Run Code Online (Sandbox Code Playgroud)

这不会起作用,因为color不会被定义。因此,您需要使用模板文字将包装在如下字符串中:

<button onclick="getOppositeColor('${color}')"><button>
Run Code Online (Sandbox Code Playgroud)

现在,onclick当用户单击按钮时,您将调用 ,并且您将向其传递一个如下所示的字符串color

getOppositeColor('blue')
Run Code Online (Sandbox Code Playgroud)


Sup*_*arp 5

如果您不想全局公开事件回调,则应将其附加到代码的 JS 部分addEventListener()

// postCreator.js
export const blogPostMaker = ({ title, content, address, id }) => 
  `
  <blog-post id='${id}'>
    <h1 class='title'>${title}</h1>
    <p class='content'>${content}</p>
    <p class='address'>${address}</p>
    <button>Delete</button>
  </blog-post>
  `

//Blog.js
  postHelper.getSeriesOfPosts(10).then(resp => {
    resp.forEach(post => {
      blogDiv.innerHTML += blogPostMaker(post)
      blogDiv.querySelector(`blog-post[id="${post.id}"] > button`)
        .addEventListener('click', () => postHelper.deletePost(post.id))
  })
Run Code Online (Sandbox Code Playgroud)

注意:这不是最有效的方法,但它可以保留文件结构。

<button>相反,我会直接创建createElement(),然后将其添加到 DOM appendChild(),或者我会使用 DocumentFragment 或 a<template>以避免querySelector()所有blogDiv.


如果您绝对想使用内联 JS 而不暴露助手,您需要将您的组件定义为组件(例如自定义元素)。


Mir*_*ski 5

const markUp = `
    <button onclick="myFunction()">Click me</button>
`;

document.body.innerHTML = markUp;

window.myFunction = () => {
    console.log('Button clicked');
};
Run Code Online (Sandbox Code Playgroud)

  • 如果您能解释一下您的代码,那就更好了。 (2认同)