Найти конкретный div в forEach - PullRequest
1 голос
/ 15 мая 2019

Мне интересно, как выбрать дочерний элемент, если обратный вызов forEach не напрямую ссылается на нужный элемент.

const $searchField = document.querySelectorAll('.js-search');

if ($searchField.length > 0) {
  $searchField.forEach(function($el) {
    // $el = .js-search
    $el.addEventListener('click', function(event) {
      $el.classList.add('is-active');
    });

    // Here, i need to target the input, not .js-search
    $el.addEventListener('keyup', function(event) {
      if ($el.value.length > 0) {
         $el.classList.add('is-active');
       } else {
         $el.classList.remove('is-active')
       }
    //});
  });
}

Здесь $el относится к родительскому .js-search, поэтому очевидно, что keyup не может работать. Я хотел бы убедиться, что выбрал вход, но я не уверен, как это сделать правильно.

Демо доступно на Codepen !

Цель состоит в том, чтобы сохранить состояние активным, когда поиск завершен (имеет как минимум 1 символ).

Спасибо

Ответы [ 2 ]

3 голосов
/ 15 мая 2019

Просто выберите ребенка input .value вместо $el .value:

const $searchField = document.querySelectorAll('.js-search');
$searchField.forEach(function($el) {
  // $el = .js-search
  $el.addEventListener('click', function() {
    $el.classList.add('is-active');
  });

  const input = $el.querySelector('input');
  input.addEventListener('keyup', function() {
    if (input.value.length > 0) {
       $el.classList.add('is-active');
     } else {
       $el.classList.remove('is-active')
     }
  });
});

Обратите внимание, что нет необходимости в проверке if, если вы не хотите - вызов forEach для пустой коллекции не выдаст ошибку, он просто не будет перебирать что-либо.

Вы также можете рассмотреть возможность включения полифилла для NodeList.prototype.forEach (если вы этого еще не сделали), так как старые браузеры не поддерживают его. (Либо, преобразуйте коллекцию в массив или используйте Array.prototype.forEach.call)

Немного основанный на мнении, но нет необходимости добавлять префикс имен к $ - это не PHP. Часто префикс $ делается, когда указывается, что что-то является коллекцией jQuery ($). Если вы выполняете манипуляции с DOM, вероятно, лучше не использовать имя переменной, начинающееся с $, чтобы избежать путаницы для будущих читателей вашего кода.

1 голос
/ 15 мая 2019

Вы можете использовать this.querySelector('input');, где this будет родительским элементом, а querySelector получит первый input дочерний элемент

const $searchField = document.querySelectorAll('.js-search');

if ($searchField.length > 0) {
  $searchField.forEach(function($el) {
    $el.addEventListener('click', function(event) {
      $el.classList.add('is-active');
      let $input = this.querySelector('input');
      $input.addEventListener('keyup', function(et) {
        console.log(et.target.value)
      });

    });

  });


  document.addEventListener('click', function(event) {
    if (!$(event.target).closest('.js-search').length) {
      closeSearchs();
    }

    $('.js-search.is-active').not($(event.target).closest('.js-search')).removeClass('is-active');
  });
}

function closeSearchs() {
  $searchField.forEach(function($el) {
    $el.classList.toggle('is-active');
  });
}
.field-search {
  position: relative;
  &.is-active {
    .search-input {
      background-color: rgba(0, 0, 0, .35);
      color: white;
    }
  }
  .search-input {
    background: none;
    box-shadow: none;
    border-radius: 4px;
    color: black;
    font-size: 1.2rem;
    font-weight: 400;
    height: 100%;
    outline: none;
    padding-left: 4.5rem;
    transition: background-color .2s;
    width: 365px;
    &::placeholder {
      color: black;
      font-size: 1.2rem;
      font-weight: 400;
    }
    &.is-active {
      background-color: rgba(255, 255, 255, .1);
    }
  }
}
<div class="field-search js-search">
  <input type="search" class="search-input" placeholder="Search...">
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...