试图找出如何使用“ this”寻址单个菜单项

时间:2019-11-08 22:06:58

标签: javascript arrays this undefined

我想做的是使用“ 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 个答案:

答案 0 :(得分:2)

this的值取决于函数的调用方式。

事件处理程序函数的this等于事件处理程序绑定到的元素。

所以onclick="this /* is the element */"

在没有上下文的情况下调用的函数(例如,如果您调用openMenuItemAll();)具有等于{{1}的this(除非您未能触发严格模式,在这种情况下它将为{{1 }}。


旁边:undefined用于链接。如果您未链接到任何地方,请不要使用它。禁止在链接中添加window


首先,修复您的标记:

<a>

请注意,链接已删除,我没有转移<button>,因为您可以从列表本身的类中推断出它。

然后选择所有按钮:

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

然后遍历按钮并将class函数绑定为事件处理程序。

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

答案 1 :(得分:0)

您需要在函数中传递thisonclick="openMenuItemAll(this); 然后,您可以从数组中获取目标的索引。

话虽如此,只要您在<li>元素中的任意位置单击,onclick事件就会发生。如果仅希望在单击按钮时触发事件,则需要将事件放在按钮内。由于按钮是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>

答案 2 :(得分:0)

Quentin有您的答案,但也可以考虑使用event delegation使代码更可扩展:

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”链接到任何内容(如果确实需要,您仍然可以获取索引)。