jQuery / JS:从数组和DOM中删除对象

问题描述 投票:0回答:1

我正在学习JS和jQuery。作为练习,我正在尝试创建一个基本的联系人列表。我需要能够从列表中添加和删除联系人。

但是我的结果有一些错误。我找不到它的原因。如果有人可以提供建议吗?我会非常感激的。

BUG 1:运行下面的代码片段时,您会看到列表中生成的一些示例联系人。您可以删除联系人。您还可以添加联系人。但添加联系人后,删除按钮停止工作。

首先,我认为问题可能是我的.html()方法中的联系人对象中缺少的字符。但我发现那里没有错误。任何人?

BUG 2:在$renderContacts功能内。你可以看到const html。这应该取代下面的let htmlfor loop。它适用于很长的联系人列表。但第一次接触呈现为[对象对象]。我没有看到原因。这两个错误可能有关系吗?

请指教。非常感谢! :)

$(document).ready(function() {

  // Array to store all contacts
  let contactsArr = [];

  // counter to create incrementing ID
  let contactID = 0;

  // Constructor for contact objects
  function Contact(firstName, lastName, email, phone, address) {
    this._id = contactID += 1;
    this.firstName = firstName;
    this.lastName = lastName;
    this.email = email;
    this.phone = phone;
    this.address = address;
    contactsArr.push(this);
  };

  // Some getters, setters and a methods for contact objects
  Contact.prototype = {
    constructor: Contact,
    set(id) {
      console.log(`ID is generated on input and may not be changed`)
    },
    get id() {
      return this._id;
    },
    set firstName(firstName) {
      this._firstName = firstName;
    },
    get firstName() {
      return this._firstName;
    },
    set lastName(lastName) {
      this._lastName = lastName;
    },
    get lastName() {
      return this._lastName;
    },
    set email(emailaddress) {
      this._email = emailaddress;
    },
    get email() {
      return this._email;
    },
    set phone(phone) {
      this._phone = phone;
    },
    get phone() {
      return this._phone
    },
    set address(address) {
      this._address = address;
    },
    get address() {
      return this._address
    },
    toHTML() {
      const renderCell = (content, cssClass = "") => `<div class="table-cell ${cssClass}">${content}</div>`;
      const deleteContact = `<span title="Delete contact" class="delete-contact far fa-trash-alt fa-sm"></span>`;
      const rowActions = renderCell(deleteContact, "text-right contact-actions");
      return '<div class="table-row">' +
        renderCell(this.id, "contact-id text-right") +
        renderCell(this.firstName, "first-name") +
        renderCell(this.lastName, "last-name") +
        renderCell(this.email, "email") +
        renderCell(this.phone, "phone") +
        renderCell(this.address, "address") +
        rowActions + '</div>';
    },
  };


  // SAMPLE CONTACTS
  new Contact("John", "Cubico", "[email protected]", "111-555-6666", "Belgium");
  new Contact("Lisa", "The Sailor", "[email protected]", "111-666-7777", "Spain");
  new Contact("Christophe", "From next door", "[email protected]", "111-777-8888", "Germany");
  new Contact("Aïsha", "From elsewere", "[email protected]", "111-888-9999", "Brussels, Holland");

  // Render Samples
  function $renderContacts(arr = contactsArr) {
    //const html = arr.reduce((all, one) => all += one.toHTML()); // ==>> 1st not rendering
    let html = ``;
    for (let i = 0; i < arr.length; i++) {
      html += arr[i].toHTML();
    };
    $("#contacts-list").append(html);
  };
  $renderContacts();



  // BUTTONS & ACTIONS

  // Add contact
  $("#add-contact").on("click", () => {
    const $firstName = $("#first-name").val();
    const $lastName = $("#last-name").val();
    const $email = $("#email").val();
    const $phone = $("#phone").val();
    const $address = $("#address").val();
    const contact = new Contact($firstName, $lastName, $email, $phone, $address); // create contact
    $("#contacts-list").append(contactsArr[contactsArr.length - 1].toHTML()); // add contact to DOM
  });

  // Delete contact
  $(".delete-contact").on("click", (event) => {
    const arr = contactsArr.slice();
    const $id = Number($(event.currentTarget).closest(".table-row").find(".contact-id").text());
    const i = arr.findIndex(contact => contact.id == $id);
    contactsArr = arr.slice(0, i).concat(arr.slice(i + 1)); // delete from array of contacts
    $(event.currentTarget).closest(".table-row").remove(); // delete only this contact from DOM
  });


});
html {}

.active {}

.inactive {
  color: #b8b8b8;
}

.table td,
.table th {
  padding: 0.5rem;
}

.text-large {
  font-size: 1.5rem;
}

.relative {
  position: relative;
}


/*** Search ***/

#search-input {
  font-size: 2rem;
  font-weight: 300;
}

span#search-btn {
  position: absolute;
  right: 0;
  top: 0;
  width: 50px;
  height: 47px;
  padding: 10px;
  box-sizing: border-box;
  font-size: 1.6rem;
  line-height: 34px;
}


/*** Contacts table ***/

.table-header {
  padding: 15px 0 5px;
}

.table-row {
  display: grid;
  grid-template-columns: 30px repeat(5, 1fr) 100px;
  grid-column-gap: 20px;
  margin: 3px 0;
  padding: 2px 0;
  background: #f0f0f0;
}

.table-cell {
  padding: 3px;
}

.editable-cell {
  background: rgba(255, 255, 255, 0.6);
}

.contact-actions span {
  line-height: 18px;
  padding: 3px;
  display: inline-block;
  width: 26px;
  text-align: center;
}


/*** Form ***/

#form-new-contact {
  align-items: end;
  margin: 0 -15px;
  padding: 15px;
}

#add-contact {
  width: 100%;
}
<html>

<head>
  <title>jQuery contacts app</title>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
  <link rel="stylesheet" type="text/css" href="styles.css">
</head>

<body>
  <header>
    <div class="container text-center mt-4 mb-4">
      <h1>jQuery contacts app</h1>
    </div>
  </header>
  <main>
    <div class="container">
      <form id="form-new-contact" action="" method="POST" class="table-row mt-4 mb-4">
        <div class="text-center"><span class="fas fa-user-plus fa-sm mb-2"></span></div>
        <div class="">
          <label for="first-name">First name:</label>
          <input name="first-name" id="first-name" class="form-control form-control-sm" type="text" value="Voornaam" placeholder="John" required>
        </div>
        <div class="">
          <label for="last-name">Last name:</label>
          <input name="last-name" id="last-name" class="form-control form-control-sm" type="text" value="Achternaam" placeholder="Doe" required>
        </div>
        <div class="">
          <label for="email">Email:</label>
          <input name="email" id="email" class="form-control form-control-sm" type="email" value="E-mailadres" placeholder="[email protected]" required>
        </div>
        <div class="">
          <label for="phone">Phone:</label>
          <input name="phone" id="phone" class="form-control form-control-sm" type="tel" value="Telefoon/GSM" placeholder="555-666-8989" required>
        </div>
        <div class="">
          <label for="address">Address:</label>
          <input name="address" id="address" class="form-control form-control-sm" type="text" value="Adres" placeholder="Somewhere" required>
        </div>
        <div class="">
          <button id="add-contact" type="button" class="btn btn-sm btn-success"><i class="fas fa-plus-circle mr-2"></i>Add</button>
        </div>
      </form>
      <div class="table">
        <div class="table-row table-header">
          <div id="id-header" class="text-right">
            <h3 class="h6">ID</h3>
          </div>
          <div id="first-name-header" class="">
            <h3 class="h6">Firstname</h3>
          </div>
          <div id="last-name-header" class="">
            <h3 class="h6">Lastname</h3>
          </div>
          <div id="email-header" class="">
            <h3 class="h6">Email</h3>
          </div>
          <div id="phone-header" class="">
            <h3 class="h6">Phone</h3>
          </div>
          <div id="address-header" class="">
            <h3 class="h6">Address</h3>
          </div>
          <div class="text-right">
            <h3 class="h6">Actions</h3>
          </div>
        </div>
        <div id="contacts-list" class="">

        </div>

      </div>
    </div>
  </main>


  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <script type="text/javascript" src="script.js"></script>
</body>

</html>
javascript jquery
1个回答
4
投票

BUG1

你无法在动态生成的DOM元素上触发on click函数。向您的元素添加事件侦听器(使用纯JS):

elem.addEventListener("click", func, false);

或者将click函数的语法更改为this(使用jQuery):

$(document).on("click",'.delete-contact', (event) => {
 // your code here
});

BUG2:

我不知道为什么这个函数会那样,但你总是要传递默认的字符串参数。看看我制作的下一行:

let html = arr.reduce((all, one) => all += one.toHTML(), '');

工作fiddle

© www.soinside.com 2019 - 2024. All rights reserved.