避免event.target引用子而不是父

时间:2016-09-12 13:02:58

标签: javascript dom javascript-events

我试图获取一组链接按钮 data attributes ,创建一个事件监听器遵循:

// For all major browsers, except IE 8 and earlier
if (document.addEventListener) {                 
    document.addEventListener("click", executeOnClick);
} else if (document.attachEvent) {   
    // For IE 8 and earlier versions
   document.attachEvent("onclick", executeOnClick);
}

事件侦听器执行下一个功能:

function executeOnClick(e){
    //////////// Only elements which has "specialClass"
    if (hasClass(e.target, 'specialClass')) {
        if(e.target !== undefined){
            console.info(e.target.getAttribute('data-info'));
            e.preventDefault();
        }
    }
}

link 按钮中包含其他标记时,它们无法正常工作。例如:

<a data-info="Lorem ipsum 3!" href="#" class="specialClass">
  <div>Link with div inside: <br> "event.target" is "div", not "a"</div>
</a>

当元素中没有孩子时,我不知道如何使它工作。有人可以帮帮我吗?

我的问题的Codepen:http://codepen.io/tomloprod/pen/gwaVXE

  

注意:我省略了hasClass方法的定义,因为这不是问题所在。无论如何,你可以在codepen上看到它。

1 个答案:

答案 0 :(得分:1)

您可以使用一个函数来递归检查parentNode是否存在data-info属性。

这是一个例子。

//////////// This function works well.

function findParentWithData(elem) {
  try {
    if(elem.getAttribute('data-info'))
      return elem;
  } catch(e) {
    console.log('This was an anchor without data-info attribute.')
    return e
  }
  while(!elem.getAttribute('data-info')) {
    return findParentWithData(elem.parentNode);
  }
}

function hasClass(event, className) {
  if (event.classList) {
    return event.classList.contains(className);
  }
  return new RegExp('(^| )' + className + '( |$)', 'gi').test(event.className);
}

function executeOnClick(e) {

  // if click came from body don't do anything
  if (e.target === document.body) return;

  var result = document.getElementById("result");
  result.innerHTML = "";

  //////////// Only elements that has "specialClass"

  // find parent with data-info
  var elem = findParentWithData(e.target)

  if (elem instanceof Element && hasClass(elem, 'specialClass')) {
    if(elem !== undefined){
      result.innerHTML = "Information: " + elem.getAttribute('data-info');
      e.preventDefault();
    }
  }
}

// For all major browsers, except IE 8 and earlier
if (document.addEventListener) {
  document.addEventListener("click", executeOnClick);
} else if (document.attachEvent) {   
  // For IE 8 and earlier versions
  document.attachEvent("onclick", executeOnClick);
}
.btn {
  opacity:0.8;
  border:0;
  -webkit-border-radius: 28;
  -moz-border-radius: 28;
  border-radius: 28px;
  font-family: Arial;
  color: #ffffff;
  font-size: 37px;
  padding: 10px 20px 10px 20px;
  text-decoration: none;
  outline:0;
  margin: 0em 0 1em 0;
  display: -webkit-inline-box;

}
.btn:hover {
  cursor:pointer;
  opacity:1;

  text-decoration: none;
}

.btn.red{
  background:#e74c3c;
}
.btn.green{
  background:#2ecc71;
}
<div id="result"></div>

<a data-info="Lorem ipsum!" href="#" class="btn green specialClass">Link: Working well</a>	

<button data-info="Lorem ipsum 2!" class="btn green specialClass">Button: Working well too</button>

<a data-info="Lorem ipsum 3!" href="#" class="btn red specialClass">
  <div>Link with div inside: <br> Doesn't work</div>
</a>

<a data-info="Lorem ipsum 4!" href="#" class="btn red specialClass">
  <ul>
    <li>   
      Link with ul inside: 
    </li>
    <li>
      Doesn't work
    </li>
  </ul>
</a>

<a href="#" class="btn red">Foo</a>