JavaScript:如何与事件委托一起使用以获取子元素“ i”类名?

时间:2018-11-17 19:14:00

标签: javascript event-delegation

我正在为我的最终项目重新创建一个经典的纸牌记忆游戏-我需要翻转和匹配的一副纸牌。 HTML中的卡片组摘录如下:

<ul class="deck">
    <li class="card">
        <i class="fa fa-diamond"></i>
    </li>
    <li class="card">
        <i class="fa fa-paper-plane-o"></i>
    </li>
    <li class="card">
        <i class="fa fa-diamond"></i>
    </li>
    <li class="card">
        <i class="fa fa-paper-plane-o"></i>
    </li>
</ul>

我已经通过将事件委托应用于父节点并使用event.target属性来添加了翻转功能。

document.querySelector('.deck').addEventListener('click', function(event) {
    if (event.target.nodeName === 'LI') {
        event.target.classList.add('open');
        //get child element "i" classname, add to array and match cards
    }
});

现在,我需要获取被单击的卡的子代,将其添加到数组中,然后使用该数组将两个打开的卡匹配在一起。问题是,我似乎无法弄清楚如何获得子元素的类(例如i class =“ fa fa-diamond”)。我怎么从这里开始?

我曾考虑只向每个卡添加一个单独的事件侦听器,但是我想那将是一个成本更高的操作。还是会更好呢?期待您的帮助和建议。

1 个答案:

答案 0 :(得分:0)

要从event.target获取实际的子调用querySelector(),并传入一个与您的<i>元素匹配的选择器,例如i.fa。或者,如果它是该<li>的唯一子元素,则只需抓住children

中的第一个元素
var child = event.target.querySelector("i.fa");
//or
var child = event.target.children[0];

此外,您不需要将每个元素的类都添加到rayy中。保存单击的卡,然后单击下一张卡,只需将其与保存的卡进行比较即可。

savedI.className == child.className

演示

var openCard = null;

document.querySelector('.deck').addEventListener('click', function(event) {
  //check that we havent clicked on the <li> or child <i>
  if (event.target.nodeName !== "LI" && event.target.nodeName !== "I") {
    return;
  }
  var child = null;
  
  if (event.target.nodeName == "LI") {
    //if we clicked on the li, child is target.children[0]
    child = event.target.children[0];
  } else {
    //if we clicked on the i directly, child is just the event target
    child = event.target;
  }

  child.parentElement.classList.add('open');

  if (openCard && openCard.className == child.className) {
    openCard.classList.add("match");
    child.classList.add("match");
    openCard = null;
    console.log("match");
  } else if (openCard) {
    openCard.parentElement.classList.remove("open");
    child.parentElement.classList.remove("open");
    openCard = null;
    console.log("No match");
  } else {
    openCard = child;
  }
});
i {
  height: 32px;
  width: 32px;
  display: block;
}

.open {
  outline: 1px solid #F00;
}

li i.match {
  background: #0F0;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" />
<ul class="deck">
  <li class="card">
    <i class="fa fa-diamond"></i>
  </li>
  <li class="card">
    <i class="fa fa-paper-plane-o"></i>
  </li>
  <li class="card">
    <i class="fa fa-diamond"></i>
  </li>
  <li class="card">
    <i class="fa fa-paper-plane-o"></i>
  </li>
</ul>