为什么我不能在没有 onclick 的情况下检索 "this" dom 元素?

Why can't I retrieve "this" dom element without onclick?

我有一个关于使用 "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" 时,它会 return DOM 对象 div。但是,console.log 事件在 "regular-div" 和 return 中间接调用 '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" 在上述情况下的工作原理所做的任何澄清。

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

Is it possible to get "this" DOM object without a user interaction?

如果你的意思是内联 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 的结束 </div> 标记之后。该脚本在脚本运行时获取文档中当前最后一个 div 的内容。或者,您当然可以以某种方式识别 div(例如 class)并使用它(然后可能会删除它,以便稍后在文档中再次执行)。

它看起来很狡猾,但它是完全有效的跨浏览器,甚至 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>

示例使用 class 我们移动:

<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 中删除),但是...

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

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
    // ...
}

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>