【问题标题】:Why can't I retrieve "this" dom element without onclick?为什么我不能在没有 onclick 的情况下检索“this”dom 元素?
【发布时间】:2015-08-31 18:05:39
【问题描述】:

我有一个关于使用“this”关键字检索 DOM 元素的非常基本的问题。

考虑以下 HTML/Javascript:

<div class="container">
    <div class="regular-div">
        <script type="text/javascript">
            console.log(this);
        </script>
        Here is a div withOUT onclick
    </div>
    <div class="onclick-div" onclick="console.log(this)">
        Here is a div with onclick
    </div>
</div>

单击“onclick-div”时,它会返回该 div 的 DOM 对象。但是,console.log 事件在 "regular-div" 中间接调用 'this' 并返回 window。

间接调用 'this' 时是否可以获得“this” DOM 对象?我的目的是我想在 HTML 中触发一个函数,但需要发送函数“this”。这是我正在尝试做的一个例子:

<div class="container">
    <div class="regular-div">
        <script type="text/javascript">
            loadSomeHTML(this, varA, varB, varC);
        </script>
    </div>
</div>

感谢大家对上述上下文中“this”如何工作的任何澄清。

【问题讨论】:

标签: javascript html this


【解决方案1】:

在您的第一个示例中,脚本与div 没有任何关联。它只是在 div 中输出,但没有连接到它。脚本在页面被解析时运行。

是否可以在没有用户交互的情况下获取“this”DOM 对象?

如果你的意思是与 HTML 的解析内联,你可以这样做:

<div class="container">
    <div class="regular-div">
        Here is a div withOUT onclick
    </div>
    <script type="text/javascript">
    (function() {
        var list = document.querySelectorAll('div');
        console.log(list[list.length - 1]);
    })();
    </script>
</div>

请注意,script 标记紧跟在您尝试定位的 div 的结尾 &lt;/div&gt; 标记之后。该脚本获取脚本运行时文档中当前最后一个div 的内容。或者,您当然可以通过某种方式(例如,一个类)识别 div 并使用它(然后可能将其删除,以便稍后在文档中再次执行)。

它看起来很狡猾,但它是完全有效的跨浏览器,甚至是recommended at one stage by the Google Closure Library engineers

实例:

<div class="container">
  <div class="regular-div">
    Here is a div withOUT onclick (look in console for result)
  </div>
  <script type="text/javascript">
    (function() {
      var list = document.querySelectorAll('div');
      console.log(list[list.length - 1]);
    })();
  </script>
</div>

使用我们移动的类的示例:

<div class="container">
  <div class="target-me">
    The first div
  </div>
  <script type="text/javascript">
    (function() {
      var div = document.querySelector(".target-me");
      div.classList.remove("target-me");
      console.log(div);
    })();
  </script>
  <div class="target-me">
    The second div
  </div>
  <script type="text/javascript">
    (function() {
      var div = document.querySelector(".target-me");
      div.classList.remove("target-me");
      console.log(div);
    })();
  </script>
</div>

注意我没有使用id,因为如果我们使用id并且没有启用JavaScript,我们最终会得到一个无效的文档(因为它会有多个元素具有相同的id )。如果启用 JavaScript 就好了(因为我们会在创建后续代码之前从早期代码中删除 id),但是...

【讨论】:

  • 谢谢 T.J.,我已经看到了 [list.length - 1] 方法,并且确实认为“这看起来很时髦”,所以你上面的解释为我提供了很多背景信息。再次感谢您的宝贵时间,这非常有帮助。
【解决方案2】:

Javascript 与 HTML DOM 没有隐式连接。 onclick 之所以按您想要的方式工作是因为 HTML DOM 实现将元素传递给 js 回调。在其他情况下,您需要做类似的事情。一种方法是:

<div class="container">
    <div class="regular-div" id="mydiv">
        <script type="text/javascript">
            loadSomeHTML("#mydiv", varA, varB, varC);
        </script>
    </div>
</div>

然后你的 js 实现会查找元素:

function loadSomeHTML(selector, varA, varB, varC) {
    var el = document.querySelector(selector);
    // now el is where you want to insert your HTML
    // ...
}

【讨论】:

  • 感谢dbcb,作为一个业余爱好者,这样的解释真的很有帮助。
【解决方案3】:

script 标签内的代码与标签本身没有任何联系。 this 基本上应该返回调用当前函数的对象或全局环境window。在第一个 div 中,代码只是在没有对象上执行,所以返回 window。另一方面,onclick 的值被视为一个函数(甚至带有一些参数,例如 e),它在具有属性的元素上被调用。因此,script 元素中的代码在全局范围内执行,而属性中的代码在函数范围内(这就是所有 vars 都在 script 标签之间共享的原因)。

【讨论】:

    【解决方案4】:

    How may I reference the script tag that loaded the currently-executing script? 中所述,获取对正在执行其代码的script 元素的引用的正确方法是

    document.currentScript;
    

    然后,要获取该元素的父节点,请使用

    document.currentScript.parentNode;
    

    <div class="container">
      <div id="regular-div">
        <script type="text/javascript">
          alert('#' + document.currentScript.parentNode.id);
        </script>
        Here is a div withOUT onclick
      </div>
    </div>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-03
      • 2021-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-17
      • 2014-06-01
      相关资源
      最近更新 更多