【问题标题】:How to use this in JavaScript?如何在 JavaScript 中使用它?
【发布时间】:2016-12-26 07:38:25
【问题描述】:

在 jQuery 中我们使用:

$("p").click(function(){$(this).hide();});

在上面的语句中this 非常重要,因为它只隐藏了我们点击的那个p 元素。但是,如果我们在this 的位置使用"p",则当我们单击p 元素中的任何一个时,它将隐藏所有p 元素。

我想知道是否有任何方法可以使用 JavaScript 生成相同的效果。我试过了:

document.getElementsByTagName("p").onclick = function(){this.style.display:none;}

document.getElementsByTagName("p").onclick = function(){document.getElementsByTagName(this).style.display:none;}

但这些都不起作用。

【问题讨论】:

  • 你可以试试 this.style.display = 'none';内部点击事件
  • “我想知道他们是否有任何方法可以使用 javascript 生成相同的效果” - 不,它只适用于使用黑魔法的 jQuery。
  • 相关,但可能不是骗子:stackoverflow.com/q/8801099/1075247
  • 我想避免使用 jquery。但我认为他们不是使用javascript获得相同效果的简单方法。所以我认为我应该使用 jquery 而不是编写复杂的 javascripts。
  • @Bergi 我认为讽刺很明显

标签: javascript html jquery dom dom-events


【解决方案1】:

您需要遍历每个元素,然后使用addEventListener 为其附加一个事件:

var allP = document.getElementsByTagName("p");
for(i=0; i< allP.length; i++) {
    allP[i].addEventListener('click', function () {
      this.style.display = "none";
    });
}

Working Demo

【讨论】:

  • 或使用事件委托:)
  • @Alex: 除非动态加载 dom,否则不推荐 :)
  • @Milind Anantwar:不推荐 - 你为什么这么认为?
  • @degr:当元素可以有自己的事件时,将负载放在父元素上是没有意义的。
  • 对不起,我错过了这条评论
【解决方案2】:

作为Alex wrote in comments:

我想知道是否有任何方法可以使用 JavaScript 生成相同的效果。

不,它只适用于使用黑魔法的 jQuery。

jQuery 滥用了this。实际上它应该只在类中使用,而不是在回调中。

使用原生 DOM 达到同样的效果:

现场演示

Array.from(document.querySelectorAll("p"))
  .forEach(el => el.addEventListener('click', () => el.style.display = 'none'))
<p>Try clicking any of the paragraphs.</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla purus metus, ullamcorper tempus augue interdum, efficitur vulputate lectus.</p>
<p>Vestibulum ullamcorper ultrices egestas.</p>
<p>Pellentesque volutpat, est ut convallis interdum, elit metus dapibus ex, non consectetur sem est et felis.</p>

【讨论】:

  • 事件处理程序很容易被视为 DOM 元素的 方法,尤其是通过 .onclick = 附加时。在里面使用this 会很有意义。
  • @Bergi 是的,但无论如何在使用箭头函数时,this 不会引用当前元素。
  • 当然不是。所以不要抱怨那些:-)顺便说一句,“方法”可以被重用,不像箭头函数闭包需要在每次循环迭代中重新创建。
  • -1 “事实上它应该只在类中使用,而不是在回调中”。这个断言是严重自以为是的,而且非常不协调。在 ES6 之前,JavaScript 甚至没有 类,而在函数上绑定this 的能力总是存在于callapply
【解决方案3】:

第一步:获取所有段落

第二步:为段落中的每一项附加一个clickListener

<html>
<head><title>Test</title></head>

<body>
    <p>This is a paragraph</p>

    <p>This is another paragraph</p>
</body>

<script type="text/javascript">

    function paragraphsClickHandler() {
        this.style.display = "none";
    }

    var paragraphs = document.getElementsByTagName("p");
    var i;

    for(i=0; i<paragraphs.length; i++)
        paragraphs[i].addEventListener("click", paragraphsClickHandler);


</script>
</html>

【讨论】:

    【解决方案4】:

    如果你碰巧更喜欢箭头函数或者由于某种原因不能信任this,你可以改用e.currentTarget

    const elems = document.getElementsByTagName("p");
    const handleClick = e => console.log(e.currentTarget); //logs the clicked element
    
    for (let i = 0; i < elems.length; i++) {
      elems[i].addEventListener('click', handleClick);
    }
    

    【讨论】:

      【解决方案5】:

      方法document.getElementByTagName不存在。

      你应该使用 document.getElement**s**ByTagName 来代替它返回一个集合:

      document.getElementsByTagName("p")[0].onclick = function(){
          this.style.display= "none";
      }
      

      或将其用于相同的$("p") 示例:

      var elems = document.getElementsByTagName("p");
      for(var i = 0; i < elems.length; i++){
          elems[i].onclick = function(){
              this.style.display= "none";
          }
      }
      

      【讨论】:

      • 这只会将事件监听器附加到 DOM 中找到的第一个 &lt;p&gt;
      • 当然。该示例用于演示问题中提出的此关键字
      • 但是问题中的示例将处理程序应用于 all &lt;p&gt; 并且仅隐藏被单击的那个,您的示例 not 创建一样的效果
      【解决方案6】:
       var bubblingToEle = function (target, type, value) {
              while(target){
                  switch (type){
                      case 'nodeName':
                          if(target.nodeName === value){
                              return target;
                          }
                          break;
                      default :
                          break;
                  }
                  target = target.parentNode;
                  if(target.nodeName === 'HTML'){
                      break;
                  }
              }
              return null;
          }
          document.body.addEventListener('click', function (e) {
              var target = e.target,
                  isPTag = bubblingToEle(target, 'nodeName', 'P');
      
              if(isPTag){
                  isPTag.style.display = 'none';
              }
          })
      

      我觉得这样比较好,不用绑定很多监听器。

      【讨论】:

        【解决方案7】:

        document.getElementsByTagName("p") 返回一个集合。您需要在每个元素上迭代和挂钩事件:

        Array.prototype.slice.call(document.getElementsByTagName("p"))
                             .forEach(function(element) {
                                        element.onclick = function() {
                                         element.style.display = 'none';
                                        }
                              });
        

        【讨论】:

          【解决方案8】:

          由于您使用的是getElementsByTagName,它将给出一个数组对象,而不是单个元素,因此您需要在循环中对其进行迭代并将点击事件与每个元素绑定如下:

          var domLength = document.getElementsByName('p').length;
          for (var i=0; i<domLength; i++) {
              document.getElementsByName('p')[i].style.display = none;
          }
          

          【讨论】:

          • 虽然这段代码 sn-p 可以解决问题,但including an explanation 确实有助于提高帖子的质量。请记住,您正在为将来的读者回答问题,而这些人可能不知道您的代码建议的原因。也请尽量不要用解释性 cmets 挤满你的代码,因为这会降低代码和解释的可读性!
          • 什么是 btnSubmit?
          • 无论如何,这是一个糟糕的决定,因为您在每个循环迭代中执行 dom 搜索。
          • @degr ,我只是忘了把 btnSubmit 换成 P,现在改正
          猜你喜欢
          • 1970-01-01
          • 2010-11-11
          • 1970-01-01
          • 2023-04-04
          • 1970-01-01
          • 1970-01-01
          • 2011-09-02
          • 2011-10-11
          • 2018-06-04
          相关资源
          最近更新 更多