如何在单击按钮时获取最接近的隐藏输入字段的值

时间:2019-01-15 13:17:04

标签: javascript

我在循环中有这段代码,即:每个删除按钮和csrf令牌显示的次数与数据库记录一样多:

<% for (const products of approved) { %>
<li>
    <div class="list-box-listing">
        <div class="list-box-listing-img"><a href="#"><img src="../<%= products.image %>" alt=""></a></div>
        <div class="list-box-listing-content">
            <div class="inner">
                <h3><a href="#"><%= products.title %></a></h3>
                <span><%= products.address.city %>, <%= products.address.suburb %></span>
                <div class="star-rating">
                    <h5>Added <%= moment(products.createdAt).fromNow() %></h5>
                </div>
            </div>
        </div>
    </div>
    <div class="buttons-to-right">
        <a href="edit-listing/<%= products._id %>" class="button gray edit"><i class="sl sl-icon-note"></i> Edit</a>
        <input type="hidden" name="_csrf" value="<%= csrfToken %>">
        <a href="#" class="button gray delete" data-id="<%= products._id %>"><i class="sl sl-icon-close"></i> Delete</a>
    </div>
</li>
<% } %>

我想获取与单击的按钮位于同一区域的csrf令牌的值。

document.body.addEventListener("click", e => {
  if (!e.target.matches(".delete")) return;
  e.preventDefault();


  const deleteBtn = e.target;
  const csrf = document.querySelector("[name=_csrf").value;
  const productId = deleteBtn.dataset.id;

  console.log(csrf);

});

我尝试使用“最接近”,但这是史诗般的失败。

  const deleteBtn = e.target;
  const csrf = deleteBtn.closest("[name=_csrf]").value;

我也尝试过:

const csrf = deleteBtn.parentNode.querySelector("[name=_csrf]").value;

但这给了我错误:

  

未捕获的TypeError:无法读取null的属性“值”       在HTMLBodyElement.document.body.addEventListener.e

3 个答案:

答案 0 :(得分:1)

在演示中,e.currentTarget从以下位置更改:

document.body.addEventListener(...

收件人:

document.querySelector('.buttons-to-right').addEventListener(...

使用previousElementSibling,请参见演示1 。如果这不起作用,请尝试使用e.currentTarget,然后从那里获取参考,请参见演示2 。顺便说一句,您可以将以下内容应用于用于按钮的<a>锚点:

<a href="#/" ...

斜杠/禁用默认的跳转行为,因此您不必使用e.preventDefault()


演示1

const getCSRF = e => {

  const tgt = e.target;
  if (tgt.matches(".delete")) {

    const input = tgt.previousElementSibling;
    const csrf = input.value;
    const productId = tgt.dataset.id;

    console.log(csrf);
  }
};

document.querySelector('.buttons-to-right').addEventListener("click", getCSRF);
<li>
  <div class="list-box-listing">
    <div class="list-box-listing-img"><a href="#"><img src="../<%= products.image %>" alt=""></a></div>
    <div class="list-box-listing-content">
      <div class="inner">
        <h3>
          <a href="#"></a>
        </h3>
        <span></span>
        <div class="star-rating">
          <h5>Added </h5>
        </div>
      </div>
    </div>
  </div>
  <div class="buttons-to-right">
    <a href="edit-listing/<%= products._id %>" class="button gray edit"><i class="sl sl-icon-note"></i> Edit</a>

    <input type="hidden" name="_csrf" value="<%= csrfToken %>">
    <a href="#/" class="button gray delete" data-id="<%= products._id %>"><i class="sl sl-icon-close"></i> Delete</a>
  </div>
</li>


演示2

const getCSRF = e => {

  const tgt = e.target;
  const cur = e.currentTarget;

  if (tgt.matches(".delete")) {

    const input = cur.querySelector('[name=_csrf]');
    const csrf = input.value;
    const productId = tgt.dataset.id;

    console.log(csrf);
  }

};

document.querySelector('.buttons-to-right').addEventListener("click", getCSRF);
<li>
  <div class="list-box-listing">
    <div class="list-box-listing-img"><a href="#"><img src="../<%= products.image %>" alt=""></a></div>
    <div class="list-box-listing-content">
      <div class="inner">
        <h3>
          <a href="#"></a>
        </h3>
        <span></span>
        <div class="star-rating">
          <h5>Added </h5>
        </div>
      </div>
    </div>
  </div>
  <div class="buttons-to-right">
    <a href="edit-listing/<%= products._id %>" class="button gray edit"><i class="sl sl-icon-note"></i> Edit</a>

    <input type="hidden" name="_csrf" value="<%= csrfToken %>">

    <a href="#/" class="button gray delete" data-id="<%= products._id %>"><i class="sl sl-icon-close"></i> Delete</a>
  </div>
</li>

答案 1 :(得分:1)

尝试获取包含元素并查询目标字段,如下所示:

document.querySelectorAll('a.delete').forEach(button => {
  button.addEventListener('click', function(e) {
    e.preventDefault();

    var csrf = this.parentElement.querySelector('[name="_csrf"]').value;

    console.log(csrf);
  });
});
<li>
  <div class="list-box-listing">
    <div class="list-box-listing-img">
      <a href="#">
        <img src="https://via.placeholder.com/200" alt="product-image">
      </a>
    </div>
    <div class="list-box-listing-content">
      <div class="inner">
        <h3><a href="#">Product title 1</a></h3>
        <span>Address 2</span>
        <div class="star-rating">
          <h5>Added 01/15/2019</h5>
        </div>
      </div>
    </div>
  </div>
  <div class="buttons-to-right">
    <a href="edit-listing/1" class="button gray edit"><i class="sl sl-icon-note"></i> Edit</a>
    <input type="hidden" name="_csrf" value="TOKEN_VALUE_1">
    <a href="#" class="button gray delete" data-id="123"><i class="sl sl-icon-close"></i> Delete</a>
  </div>
</li>

<li>
  <div class="list-box-listing">
    <div class="list-box-listing-img">
      <a href="#">
        <img src="https://via.placeholder.com/200" alt="product-image">
      </a>
    </div>
    <div class="list-box-listing-content">
      <div class="inner">
        <h3><a href="#">Product title 2</a></h3>
        <span>Address 2</span>
        <div class="star-rating">
          <h5>Added 01/15/2019</h5>
        </div>
      </div>
    </div>
  </div>
  <div class="buttons-to-right">
    <a href="edit-listing/1" class="button gray edit"><i class="sl sl-icon-note"></i> Edit</a>
    <input type="hidden" name="_csrf" value="TOKEN_VALUE_2">
    <a href="#" class="button gray delete" data-id="456"><i class="sl sl-icon-close"></i> Delete</a>
  </div>
</li>

答案 2 :(得分:0)

使用此脚本。

    <script>
    document.body.addEventListener("click", e => {
        if (!e.target.matches(".delete")) return;
        e.preventDefault();
        const deleteBtn = e.target;
        const closestDiv = deleteBtn.closest("[class=buttons-to-right]");
        const csrf = closestDiv.querySelector("[name=_csrf]").value;
        console.log(csrf);
    });
</script>