Vanillla Javascript показывает скрытое содержимое, используя тип данных

#javascript

#javascript

Вопрос:

Я не уверен, что мой подход правильный, но, надеюсь, это так. У меня есть разные разделы, которые можно редактировать в процессе оформления заказа. Поэтому, если клиент нажимает кнопку редактирования для соответствующего раздела, он должен скрыть раздел информации, а затем отобразить раздел редактирования. я думал использовать тип данных из-за попытки сохранить javascript как можно более сухим? итак, это то, что у меня есть, но я не уверен, как к этому подойти.

идея заключается в том, чтобы по щелчку получить тип данных нажатой кнопки редактирования и сопоставить его с идентификатором отображаемого раздела, а затем добавить к нему класс show. Я заработал, но изначально мне нужно сделать двойной щелчок, чтобы отключить его, и если я регистрирую консоль, количество «нажатых» увеличивается экспоненциально.

кроме того, кажется, что наличие двух функций является повторяющимся ..?

 function editDetails() {

  let trigger = document.querySelectorAll('.edit-link');

  trigger.forEach(function(click) {
    click.addEventListener('click', function(e) {

      const target = this.getAttribute('data-checkout');
      const checkoutSection = document.getElementById('checkout-'   target);
      const checkoutEditSection = document.getElementById('edit-checkout-'   target);

      if (checkoutEditSection.classList) {
        checkoutEditSection.classList.add('show');
      }
      if (checkoutSection.classList) {
        checkoutSection.classList.add('hide');
      }

      e.preventDefault();
    })


  });
}

function cancelDetails() {

  let trigger = document.querySelectorAll('.btn-cancel');

  trigger.forEach(function(click) {
    click.addEventListener('click', function(e) {

      const target = this.getAttribute('data-checkout');
      const checkoutSection = document.getElementById('checkout-'   target);
      const checkoutEditSection = document.getElementById('edit-checkout-'   target);

      if (checkoutEditSection.classList) {
        checkoutEditSection.classList.remove('show');
      }
      if (checkoutSection.classList) {
        checkoutSection.classList.remove('hide');
      }

      console.log(target);
      e.preventDefault();
    })
  });
}  
 .edit-link {
  display: inline-flex;
  padding: 1rem 2rem;
  color: white;
  background: blue;
  margin-bottom: 2rem;
  margin-right: 1rem;
}

.info {
  padding: 4em;
  background: lightcoral;
  margin-bottom: 1rem;
  display: block;
}

.details {
  padding: 4em;
  background: #e7e7e7;
  margin-bottom: 1rem;
  display: none;
}

.show {
  display: block;
}

.hide {
  display: none;
}

.btn {
  display: inline-flex;
  padding: 1em 2em;
  color: white;
  background: black;
  text-decoration: none;
}  
 <div class="container container--lg">

  <a onclick="editDetails()" data-checkout="personal" class="edit-link">Edit Personal Details</a>
  <a onclick="editDetails()" data-checkout="payment" class="edit-link">Edit Payment Details</a>

  <div id="checkout-personal" class="contact-info info">this is the Personal Details content</div>
  <div id="edit-checkout-personal" class="contact-info details">
    this is the Personal Details content in <b>Edit mode</b>
    <a class="btn btn-cancel" data-checkout="personal" onclick="cancelDetails()">cancel</a>
    <a class="btn" onclick="saveDetails()">Save</a>

  </div>
  <div id="checkout-payment" class="payment-info info">this is the Payment Details content</div>
  <div id="edit-checkout-payment" class="payment-info details">this is the Payment Details content in <b>Edit mode</b>
    <a class="btn btn-cancel" data-checkout="payment" onclick="cancelDetails()">cancel</a>
    <a class="btn" onclick="saveDetails()">Save</a></div>

</div>  

Комментарии:

1. Я нажал редактировать и [<>] для вас

2. Не ДОБАВЛЯЙТЕ eventlisteners в кнопку, на которую можно нажать более одного раза!!! — Просмотр delegate

3. не думаю, что я подписываюсь на @mplungjan

4. Каждый раз, когда я нажимаю editDetails, вы добавляете функцию к щелчку всех '.edit-link' — вам нужно только добавить это один раз и добавить в статический контейнер, тогда любой щелчок по контейнеру покажет цель в e.target

5. Был создан фрагмент вашего кода, что подразумевается под комментарием к редактированию

Ответ №1:

Каждый раз, когда мы нажимаем editDetails, вы добавляете функцию к щелчку all ‘.edit-link’ — вам нужно добавить это только один раз и добавить в статический контейнер, тогда любой щелчок по контейнеру покажет цель в e.target

Делегируйте вот так

 document.querySelector(".container").addEventListener("click", function(e) {
  const tgt = e.target;
  if (tgt.classList.contains("edit-link") || tgt.classList.contains("btn-cancel")) {
    e.preventDefault();
    const cancel = tgt.classList.contains("btn-cancel");
    const target = tgt.getAttribute('data-checkout');
    const checkoutSection = document.getElementById('checkout-'   target);
    const checkoutEditSection = document.getElementById('edit-checkout-'   target);

    checkoutEditSection.classList.toggle('show', !cancel);
    checkoutSection.classList.toggle('hide', cancel);
  }
})  
 .edit-link {
  display: inline-flex;
  padding: 1rem 2rem;
  color: white;
  background: blue;
  margin-bottom: 2rem;
  margin-right: 1rem;
}

.info {
  padding: 4em;
  background: lightcoral;
  margin-bottom: 1rem;
  display: block;
}

.details {
  padding: 4em;
  background: #e7e7e7;
  margin-bottom: 1rem;
  display: none;
}

.show {
  display: block;
}

.hide {
  display: none;
}

.btn {
  display: inline-flex;
  padding: 1em 2em;
  color: white;
  background: black;
  text-decoration: none;
}  
 <div class="container container--lg">

  <a data-checkout="personal" class="edit-link">Edit Personal Details</a>
  <a data-checkout="payment" class="edit-link">Edit Payment Details</a>

  <div id="checkout-personal" class="contact-info info">
    this is the Personal Details content
  </div>
  <div id="edit-checkout-personal" class="contact-info details">
    this is the Personal Details content in <b>Edit mode</b>
    <a class="btn btn-cancel" data-checkout="personal">cancel</a>
    <a class="btn" onclick="saveDetails()">Save</a>
  </div>
  <div id="checkout-payment" class="payment-info info">
    this is the Payment Details content
  </div>
  <div id="edit-checkout-payment" class="payment-info details">
    this is the Payment Details content in <b>Edit mode</b>
    <a class="btn btn-cancel" data-checkout="payment">cancel</a>
    <a class="btn" onclick="saveDetails()">Save</a>
  </div>
</div>  

Комментарии:

1. что-то не так с кодом, потому что отмена закрывает как детали, так и раздел редактирования

2. Хорошо, вы поняли идею. Я позволю вам разобраться с этим

3. Я предлагаю вам использовать только .hide, а не . показывает и просто переключает этот класс

Ответ №2:

Не уверен, что все ваши требования, но здесь я показываю, как добавить обработчики событий для каждой кнопки и вызвать функцию, чтобы просто переключить hide класс.

Другая ваша работа с кнопками может быть размещена в соответствующих функциях;

 function showAction(text) {
  const showMe = document.getElementById('showme');
  showMe.textContent = text;
}

function clickEventhandler(event) {
  showAction('Clicked:'   this.textContent)
  const target = this.getAttribute('data-checkout');
  const checkoutSection = document.getElementById('checkout-'   target);
  const checkoutEditSection = document.getElementById('edit-checkout-'   target);
  checkoutSection.classList.toggle('hide');
  checkoutEditSection.classList.toggle('hide');
  event.preventDefault();
}

function saveEventHandler(event) {
  showAction('Clicked:'   this.textContent);
  clickEventhandler.call(this, event);
}

function cancelEventHandler(event) {
  showAction('Clicked:'   this.textContent);
  clickEventhandler.call(this, event);
}

function cancelEventHandler(event) {
  showAction('Clicked:'   this.textContent);
  clickEventhandler.call(this, event);
}

document.querySelectorAll('.edit-link')
  .forEach(function(element) {
    element.addEventListener('click', clickEventhandler);
  });
document.querySelectorAll('.btn-cancel')
  .forEach(function(element) {
    element.addEventListener('click', cancelEventHandler);
  });
document.querySelectorAll(".save-details")
  .forEach(function(element) {
    element.addEventListener('click', saveEventHandler);
  });  
 .edit-link {
  display: inline-flex;
  padding: 1rem 2rem;
  color: white;
  background: blue;
  margin-bottom: 2rem;
  margin-right: 1rem;
}

.info {
  padding: 4em;
  background: lightcoral;
  margin-bottom: 1rem;
}

.details {
  padding: 4em;
  background: #e7e7e7;
  margin-bottom: 1rem;
}

.hide {
  display: none;
}

.btn {
  display: inline-flex;
  padding: 1em 2em;
  color: white;
  background: black;
  text-decoration: none;
}

#showMe {
  border solid lime 1px;
}  
 <div class="container container--lg">
  <a data-checkout="personal" class="edit-link">Edit Personal Details</a>
  <a data-checkout="payment" class="edit-link">Edit Payment Details</a>
  <div id="checkout-personal" class="contact-info info ">this is the Personal Details content</div>
  <div id="edit-checkout-personal" class="contact-info details hide">
    this is the Personal Details content in <b>Edit mode</b>
    <a class="btn btn-cancel" data-checkout="personal">cancel</a>
    <a class="btn save-details" data-checkout="personal">Save</a>
  </div>
  <div id="checkout-payment" class="payment-info info">this is the Payment Details content</div>
  <div id="edit-checkout-payment" class="payment-info details hide">this is the Payment Details content in <b>Edit mode</b>
    <a class="btn btn-cancel" data-checkout="payment">cancel</a>
    <a class="btn save-details" data-checkout="payment">Save</a></div>
</div>
<div id="showme"></div>