0

我是 JavaScript 新手,有点掌握它。我注意到我的displayEmail函数没有正确id接受list-group. 我想让我的displayEmail函数弹出一个模式,但我需要每个列表项在list-group-itemonclick 事件发生时正确返回一个 ID。

这是控制台中的问题

问题

这是我的 Javascript 代码:

document.addEventListener('DOMContentLoaded', function() {

  // Use buttons to toggle between views
  document.querySelector('#inbox').addEventListener('click', () => load_mailbox('inbox'));
  document.querySelector('#sent').addEventListener('click', () => load_mailbox('sent'));
  document.querySelector('#archived').addEventListener('click', () => load_mailbox('archive'));
  document.querySelector('#compose').addEventListener('click', compose_email);

  // By default, load the inbox
  load_mailbox('inbox');
});

function compose_email() {

  function clear_compose_form() {
    document.querySelector('#compose-recipients').value = '';
    document.querySelector('#compose-subject').value = '';
    document.querySelector('#compose-body').value = '';
  }

  // Show compose view and hide other views
  document.querySelector('#emails-view').style.display = 'none';
  document.querySelector('#compose-view').style.display = 'block';

  // Clear out composition fields
  clear_compose_form()

  document.querySelector("#compose-form").addEventListener('submit', (event) => {

    const recipients = document.querySelector('#compose-recipients').value;
    const subject = document.querySelector('#compose-subject').value;
    const body = document.querySelector('#compose-body').value;

    const message = document.createElement("div")
    message.className = "alert alert-";

    fetch("/emails", {
      method: "POST",
      body: JSON.stringify({
        recipients: recipients,
        subject: subject,
        body: body
      })
    })
    .then(response => response.json())
    .then(jsonResponse => {

      let messageText = null

      if (jsonResponse.hasOwnProperty("message")) {
        message.className += "success";
        messageText = jsonResponse["message"]
      } else {
        message.className += "danger";
        messageText = jsonResponse["error"]
      }

      message.innerHTML = messageText

      let alert = document.querySelector(".alert")
      if (alert !== null) {
        alert.replaceWith(message)
      } else {
        document.querySelector("#compose-view").insertBefore(message, document.querySelector("#compose-form"))
      }

      clear_compose_form()
    })

    event.preventDefault();
    return false;
  });

}


function load_mailbox(mailbox) {
  
  // Show the mailbox and hide other views
  document.querySelector('#emails-view').style.display = 'block';
  document.querySelector('#compose-view').style.display = 'none';

  // Show the mailbox name
  document.querySelector('#emails-view').innerHTML = `<h3> ${mailbox.charAt(0).toUpperCase() + mailbox.slice(1)}</h3>`;

  fetch(`/emails/${mailbox}`, {
    method: "GET"
  })
  .then(response => response.json())
  .then(emailsData => mailboxEmails(emailsData, mailbox))

}


function mailboxEmails(data, mailbox) {

  const emailsContainer = document.createElement("ul");
  emailsContainer.className = "list-group";
  emailsContainer.addEventListener("click", event => displayEmail(event));

  data.forEach(emaildata => {

    email = emailPreview(emaildata, mailbox);
    emailsContainer.appendChild(email)

  });

  document.querySelector('#emails-view').append(emailsContainer)

}


function emailPreview(emaildata , mailbox) {

  const email = document.createElement("li")
  const emailPreviewContent = document.createElement("h5")
  const userDidSend = mailbox === "sent"

  
  let otherUsers = null;

  if (userDidSend){
    otherUsers = emaildata["recipients"];
  } 
  else {
    otherUsers = emaildata["sender"];

    const unreadNotification = document.createElement("span")
    unreadNotification.className = "badge badge-warning"
    unreadNotification.innerHTML = "Unread"
    email.appendChild(unreadNotification)
  }

  email.id = emaildata["id"]
  email.className = "list-group-item list-group-item-action list-group-item-light";

  emailPreviewContent.innerHTML = `${otherUsers} - ${emaildata["subject"]} - ${emaildata["body"] } - ${emaildata["timestamp"] }` 
  emailPreviewContent.style.textOverflow = "ellipsis"
  email.appendChild(emailPreviewContent)

  return email;
}


function displayEmail(event) {
  if (event.target) {
    console.log(event.target.id + " was clicked")
  }
  

  // document.addEventListener(bd-email-modal-lg)
}

这是我的 HTML:


    <button class="btn btn-sm btn-outline-primary" id="inbox">Inbox</button>
    <button class="btn btn-sm btn-outline-primary" id="compose">Compose</button>
    <button class="btn btn-sm btn-outline-primary" id="sent">Sent</button>
    <button class="btn btn-sm btn-outline-primary" id="archived">Archived</button>
    <a class="btn btn-sm btn-outline-primary" href="{% url 'logout' %}">Log Out</a>
    <hr>

    <div id="emails-view">
    </div>

    <div id="compose-view">
        <h3>New Email</h3>
        <form id="compose-form">
            <div class="form-group">
                From: <input disabled class="form-control" value="{{ request.user.email }}">
            </div>
            <div class="form-group">
                To: <input id="compose-recipients" class="form-control">
            </div>
            <div class="form-group">
                <input class="form-control" id="compose-subject" placeholder="Subject">
            </div>
            <textarea class="form-control" id="compose-body" placeholder="Body"></textarea>
            <input type="submit" class="btn btn-primary"/>
        </form>
    </div>

    <div class="modal fade bd-email-modal-lg" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true">
        <div class="modal-dialog modal-lg">
          <div class="modal-content">
            ...
          </div>
        </div>
      </div>

有什么帮助,谢谢!

4

1 回答 1

1

您的问题是您已将事件侦听器添加到外部容器:

 emailsContainer.addEventListener("click", event => displayEmail(event));

因此,根据单击发生时指针的位置,单击目标可能是一个<li>(因此它会冒泡到您期望的<ul>单击处理程序id)或者它可能是包含的<ul>,在这种情况下id将是未定义的)。如果您确实需要id来自项目本身,则必须将点击处理程序单独添加到每个项目,而不是容器上。

function emailPreview(emaildata , mailbox) {
    const email = document.createElement("li")
    email.addEventListener("click", event => displayEmail(event));
    ...

您还需要更新单击处理程序以引用currentTarget而不是target. currentTarget为您提供处理事件的项目(您的<li>),后者是被单击的项目(可能是<li>,也可能是它的任何子项)。

function displayEmail(event) {
  if (event.target) {
    console.log(event.currentTarget.id + " was clicked")
  }
}
于 2020-11-27T09:27:47.523 回答