Попытка выяснить, как обращаться к отдельным пунктам меню, используя «это» - PullRequest
0 голосов
/ 09 ноября 2019

То, что я пытаюсь сделать, - это регистрировать результаты, используя «this» как массив, чтобы число 0 регистрировалось в console.log всякий раз, когда я щелкаю по первому элементу списка, без предопределенных переменных и только с использованием одной функции.

<ul class="menuList">
    <li><a class="menuImage" onclick="openMenuItemAll();"><button>&#8250;</button>Chicken Cordon Bleu</a></li>
    <li><a class="menuImage" onclick="openMenuItemAll();"><button>&#8250;</button>Chicken Stir Fry</a></li>
    <li><a class="menuImage" onclick="openMenuItemAll();"><button>&#8250;</button>Chicken Thighs</a></li>
    <li><a class="menuImage" onclick="openMenuItemAll();"><button>&#8250;</button>Fish Fillet</a></li>
    <li><a class="menuImage" onclick="openMenuItemAll();"><button>&#8250;</button>Lasagna</a></li>
    <li><a class="menuImage" onclick="openMenuItemAll();"><button>&#8250;</button>Pizza</a></li>
    <li><a class="menuImage" onclick="openMenuItemAll();"><button>&#8250;</button>Salmon</a></li>
    <li><a class="menuImage" onclick="openMenuItemAll();"><button>&#8250;</button>Spaghetti</a></li>
</ul>
<script type="text/javascript">
    function openMenuItemAll(){
    var menuImage = document.querySelectorAll(".menuImage");
    console.log(this.menuImage);
}
</script>

Я получаю неопределенное значение в console.log, когда пытаюсь получить номер массива на основе позиции пункта меню

Ответы [ 3 ]

2 голосов
/ 09 ноября 2019

Значение this зависит от того, как вызывается функция.

Функции обработчика событий будут иметь this, равный элементу, с которым связан обработчик события.

Итакonclick="this /* is the element */"

Функции, вызываемые без контекста (например, если вы вызываете openMenuItemAll();), имеют this, равный undefined (если вы не активируете строгий режим, в этом случае это будет window).


В сторону: <a> для ссылок . Не используйте его, если вы нигде не ссылаетесь. запрещено помещать <button> внутри ссылки!


Сначала исправьте вашу разметку:

<ul class="menuList">
    <li><button>&#8250;</button>Chicken Cordon Bleu</li>

Обратите внимание, что ссылка удалена,и я не передал class, потому что вы можете вывести его из класса в самом списке.

Затем выберите все кнопки:

const buttons = document.querySelector(".menuList button");

Затем зациклите кнопки исвяжите вашу openMenuItemAll функцию как обработчик событий.

Array.from(buttons).forEach(
    button => button.addEventListener("click", openMenuItemAll)
);
0 голосов
/ 09 ноября 2019

Квентин имеет ваш ответ, но также рассмотрим делегирование события , чтобы сделать код более расширяемым:

window.onload = function() {
  document.querySelector('ul').addEventListener('click', showIndex, false);
}

function showIndex (evt) {
  let tgt = evt.target;
  let btns = this.querySelectorAll('button');
  for (let i=0, iLen=btns.length; i<iLen; i++) {
    if (btns[i] == tgt) {
      console.log('Button ' + i);
      return i;
    }
  }
  return null;
}
<ul>
  <li><button>&#8250;</button>
  <li><button>&#8250;</button>
  <li><button>&#8250;</button>
</ul>

Вы также можете рассмотреть возможность использования OL (упорядоченный список), в этом случае элементы LI будут иметь атрибут value , который является их позициейв списке.

Но я думаю, что еще лучше поставить атрибут на каждую кнопку, чтобы связать их с назначением, чтобы порядок не имел значения, поэтому у вас есть:

<button data-menuItem="123">&#8250;</button>Chicken Cordon Bleu

Тогда вы можете связатьссылка "123" на что угодно (и вы все равно можете получить индекс, если действительно хотите).

0 голосов
/ 09 ноября 2019

Вам нужно передать this в вашей функции: onclick="openMenuItemAll(this); Затем вы можете получить индекс цели из массива.

При этом событие onclick произойдет в любое время, когда вы щелкнете в любом местев элементе <li>. Если вы хотите, чтобы событие срабатывало только при нажатии на кнопку, вам нужно поместить событие внутри кнопки. Поскольку кнопка является дочерней по отношению к li, вам нужно передать this.parentElement, чтобы передать <li> в функцию.

Кроме того, поскольку тег привязки на самом деле не используется для этой цели, выможет удалить это полностью.

В приведенном ниже фрагменте я также удаляю маркеры в списке, поскольку кнопки действительно заменяют необходимость их наличия.

function openMenuItemAll(target) {
  const menuImage = document.querySelectorAll(".menuImage");
  const index = Array.prototype.indexOf.call(menuImage, target)
  console.log(index);
}
.menuImage{
  list-style:none;
}
<ul class="menuList">
    <li class="menuImage">
        <button onclick="openMenuItemAll(this.parentElement);">&#8250;</button> Chicken Cordon Bleu
    </li>
    <li class="menuImage">
        <button onclick="openMenuItemAll(this.parentElement);">&#8250;</button> Chicken Stir Fry
    </li>
    <li class="menuImage">
        <button onclick="openMenuItemAll(this.parentElement);">&#8250;</button> Chicken Thighs
    </li>
    <li class="menuImage">
        <button onclick="openMenuItemAll(this.parentElement);">&#8250;</button> Fish Fillet
    </li>
    <li class="menuImage">
        <button onclick="openMenuItemAll(this.parentElement);">&#8250;</button> Lasagna
    </li>
    <li class="menuImage">
        <button onclick="openMenuItemAll(this.parentElement);">&#8250;</button> Pizza
    </li>
    <li class="menuImage">
        <button onclick="openMenuItemAll(this.parentElement);">&#8250;</button> Salmon
    </li>
    <li class="menuImage">
        <button onclick="openMenuItemAll(this.parentElement);">&#8250;</button> Spaghetti
    </li>
</ul>
...