【问题标题】:How can you detect which element in a class was clicked on with Javascript?如何检测类中的哪个元素被 Javascript 点击了?
【发布时间】:2014-03-27 17:44:04
【问题描述】:

假设我们有一个带有类的无序列表:

    <ul class="list-class">
        <li><a href="#">All</a></li>
        <li><a href="#">Breakfast</a></li>
        <li><a href="#">Lunch</a></li>
        <li><a href="#">Dinner</a></li>
        <li><a href="#">Snack</a></li>
   </ul>

假设现在我想创建一些函数,根据点击的项目执行不同的操作:

function whichElement() {
    alert("The -- Link has been clicked");
}

如果不为每个项目创建单独的函数并编写内联 onclick="" 事件,如何做到这一点?我也愿意使用 jQuery。

【问题讨论】:

  • 为什么不使用 jquery
  • 最简单的方法是给列表项或链接自己的类。有什么特别的东西会让人觉得这是个坏主意吗?
  • 没有,但有没有办法简单地确定这一点?可能使用“这个”?我只是第一次学习JS。
  • @Arun 你检查我的答案了吗?有用吗?

标签: javascript jquery


【解决方案1】:

如果我理解正确的话会怎样:

var items = document.querySelectorAll('.list-class li');

[].forEach.call(items, function(item){

  var text = item.textContent.trim().toLowerCase();

  item.addEventListener('click', function(){
    if (text == 'all') {
      //...
    }
    //...
  });
});

【讨论】:

  • 值得一提的是,其中一些方法需要现代浏览器,或者这些方法需要匀场。即querySelectorAllforEachtextContenttrimaddEventListener,当前代码需要 IE9+,但对于 POJS 解决方案需要 +1。
  • [].forEach.call 会在内存中创建一个空的ArrayArray.prototype.foreach.call 不会。
【解决方案2】:

你可以试试这个

function addEvent(elem, event, fn)
{
    if (elem.addEventListener)
    {
        elem.addEventListener(event, fn, false);
    }
    else
    {
        elem.attachEvent("on" + event, function() {
            return(fn.call(elem, window.event));   
        });
    }
}

addEvent(window, 'load', function(e){
    var list = document.querySelector('.list-class');
    addEvent(list, 'click',  function(e){
         e = e || window.event;
         var el = e.target || e.srcElement;
         alert(el.innerHTML);
    });
});

DEMO.

【讨论】:

  • 我不知道为什么您的跨浏览器 POJS 解决方案只完成了一半?您创建了一个跨浏览器addEvent,但随后您使用了需要 IE8+ 的“querySelector”。不过,为 POJS 解决方案 +1。
  • 是的,我提到它是IE8+
【解决方案3】:

ul 添加一个点击处理程序,类似于:

$('.list-class').on(
  'click',
   function(e){
     e = e || event;
     var from = e.target || e.srcElement;
     if (/^a$/i.test(from.tagName)){
        alert('you clicked '+from.innerHTML);
     }
   });

看到这个jsFiddle

【讨论】:

  • 使用 jquery 的事件委托而不是测试标签不是更好吗?为什么不用简单的from.tagName === "a" 而不是正则表达式test
  • 也许吧,但你知道吗 - 这 is 事件委托。 JQuery 将在内部使用相同的机制。 test:一些浏览器报告'A',其他浏览器报告'a'作为标记名,所以测试比from.tagName === "a" || from.tagName === "A"短一点。
  • 也许我没有很好地解释自己,是的,您有一种“直接委托”的形式,请参阅jquery on event delegation。 jquery 还应该通过"normalisation" 为您处理e || eventtarget || srcElement,因此是不必要的。然后关于约翰·雷西格本人的tagName。根据jsfiddle 为您提供 jquery 中的最终代码。这就是我想要传达的。
【解决方案4】:

做一个 Jquery Trick as

$("#list-class li").click(function() {
    alert($(this).prevAll().length+1);
});

这里是FIDDLE

【讨论】:

    【解决方案5】:

    编辑: event.target 返回启动事件的 DOM 元素。

    $('.list-class').click(function(e){  
       alert(e.target.nodeName);
    });
    

    JSFiddle查看这个

    【讨论】:

    • 有了这个,我当然可以点击li元素,而不是具体包含的a元素,它会触发警报。
    【解决方案6】:

    不要跟风,因为这与其他人相似(但不完全)......

    $('.list-class>li').on('click',
       function(){
          alert('clicked ' + $('a',this)[0].innerHTML); //eg "clicked Lunch" etc
       }
    );
    

    http://jsfiddle.net/znySy/

    这只是提醒点击链接的文本,但同样在函数内你可以在文本上switch,例如...

    function(){
        switch ($('a',this)[0].innerHTML) {
            case 'Lunch'     : // do something for Lunch
            case 'Breakfast' : // do something for Breakfast
            default          : // do something for not Lunch or Breakfast
        }
    }
    

    【讨论】:

      【解决方案7】:

      您可以像这样在 POJS 中执行此操作,这应该是跨浏览器兼容的,并且不使用任何 3rd 方库。另一个优点是命名类的每个元素只有一个事件侦听器,使用事件传播。

      Javacsript

      /*jslint maxerr: 50, indent: 4, browser: true */
      /*global alert */
      
      (function () {
          "use strict";
      
          function addEvent(elem, event, fn) {
              if (typeof elem === "string") {
                  elem = document.getElementById(elem);
              }
      
              function listenHandler(e) {
                  var ret = fn.apply(null, arguments);
      
                  if (ret === false) {
                      e.stopPropagation();
                      e.preventDefault();
                  }
      
                  return ret;
              }
      
              function attachHandler() {
                  window.event.target = window.event.srcElement;
      
                  var ret = fn.call(elem, window.event);
      
                  if (ret === false) {
                      window.event.returnValue = false;
                      window.event.cancelBubble = true;
                  }
      
                  return ret;
              }
      
              if (elem.addEventListener) {
                  elem.addEventListener(event, listenHandler, false);
              } else {
                  elem.attachEvent("on" + event, attachHandler);
              }
          }
      
          function whichElement(e) {
              var target = e.target;
      
              if (target.tagName === "A" && target.parentElement.tagName === "LI" && target.parentElement.parentElement.className === "list-class") {
                  alert("The " + target.firstChild.nodeValue + " Link has been clicked");
              }
          }
      
          addEvent(document.body, "click", whichElement);
      }());
      

      开启jsfiddle

      如果您使用一些较新/自定义的 HTML 标记或 XML,那么您可能需要考虑 tagName case sensitivity,并写下以下内容以确定。

      if (target.tagName.toUpperCase() === "A" && target.parentElement.tagName.toUpperCase() === "LI" && target.parentElement.parentElement.className === "list-class") {
      

      在 jquery 术语中,上面可以写成

      Javascript

      $(document).on('click', '.list-class>li>a', function (e) {
          alert("The " + e.target.firstChild.nodeValue + " Link has been clicked");
      });
      

      开启jsfiddle

      在 jquery 中,他们称之为event delegation

      【讨论】:

      • 明白,当然,如果您保留自己的函数库,那么 jquery 就变得非常多余,并且您揭开了隐藏的魔力。 :)
      • 哦,是的,我不是不明白 jQuery 只是一个 JS 库的人之一。它只是让一些东西真的很容易写!顺便说一句,答案很好!很高兴看到一些 POJS
      • 可能不会。我的宠物讨厌(之一)
      【解决方案8】:
      <ul class="list-class">
              <li><a href="#" id="hrefID1">All</a></li>
              <li><a href="#" id="hrefID2">Breakfast</a></li>
              <li><a href="#" id="hrefID3">Lunch</a></li>        
         </ul>
       <script>
      $(".list-class li").find('a').each(function(){
          $(this).click(function(){
              switch($(this).attr('id'))
              {
                  case "hrefID1";
                          //do what ever 
                          break;
                  case "hrefID2";
                          //do what ever 
                          break;
                  case "hrefID3";
                          //do what ever 
                          break;
              }
          });
      });
      </script>
      

      【讨论】:

        猜你喜欢
        • 2016-08-18
        • 1970-01-01
        • 2022-01-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多