为什么我的点击事件处理程序(是"是")有效?

时间:2017-09-13 20:39:53

标签: javascript html

我知道它有点滑稽,因为人们经常要求解决一些不起作用的事情,在这种情况下它恰恰相反。

我正在玩JavaScript,我发现了让我困惑的事情! 我尝试在网上寻求帮助,但我找不到任何有用的主题。

问题是这样的:只调用一次函数bar后,onclick事件就完好无损了。怎么可能!?

但是当我要求变量类型x时,它会返回undefined而不是Number,这是正常的,因为x位于bar内。< / p>

function bar() {
    var p = document.getElementById("foo");
    p.onclick = showAlert;
    var x = 5;
    alert("bar function was called !");
  }
  bar();

任何人都可以告诉我究竟发生了什么,详细解释会非常感激。

完整代码:(JSfiddle link:https://jsfiddle.net/ge4gj5nw

<!DOCTYPE html>
<html>
  <head>
    <style>
      #foo {
        border: solid blue 1px;
        width: 30%;
        padding: 10px;
      }
    </style>
  </head>
  <body>
    <p id="foo">My Event Element</p>
    <p>Click on the above element..</p>
  </body>
</html>

<script>
  function bar() {
    var p = document.getElementById("foo");
    p.onclick = showAlert;
    var x = 5;
    alert("bar function was called !");
  }
  bar();
  function showAlert(event) {
    alert("onclick Event detected!");
  }
</script>

5 个答案:

答案 0 :(得分:2)

即使p的作用域为bar函数getElementById,也会返回对DOM中节点的引用(范围更高)。通过调用p.onclick = showAlert;,您正在改变该函数中的onclick属性(更高范围)。

  

只调用一次“bar”函数后,“onclick”事件就是   工作得很好..这怎么可能?

这是可能的,因为bar的调用会改变更高范围的对象。

var global = {specialKey: 'I am global scoped'}

function testingFunctionScope() {
    global.specialKey = 'Not function scoped!';
    console.log(global.specialKey); // Not function scoped!
}

testingFunctionScope(); 
console.log(global.specialKey); // Not function scoped!

答案 1 :(得分:1)

好的,我想我知道你不懂什么,我已经准备好了一小段代码来说明。当函数绑定到那里时,使用p.onclick的地方并不重要,它将保留在DOM元素的整个生命周期中,或直到你取消绑定该函数。 检查一下: https://jsfiddle.net/52wq4gdv/1/ 我根据按下的按钮设置处理程序并将其删除

// set vars globaly for ease of use.
var p = document.getElementById("foo");
var buttonRemove = document.getElementById("remove-handler");
var buttonAdd = document.getElementById("add-handler");

function bar() {
  p.onclick = showAlert;
  buttonRemove.onclick = removeOnClick;
  buttonAdd.onclick = addOnClick;
  var x = 5;
  alert("bar function was called !");
}
bar();

function showAlert(event) {
  alert("onclick Event detected!");
}

function addOnClick(event) {
  p.onclick = showAlert;
}

function removeOnClick(event) {
  p.onclick = undefined;
}

和html:

<button id="foo">My Event Element</button>
<p>Click on the above element..</p>
<button id="remove-handler">
  Remove on click handler
</button>
<button id="add-handler">
  Add back on click handler
</button>

此网址应该清除一些内容: https://www.w3schools.com/js/js_htmldom.asp

答案 2 :(得分:0)

当调用'bar'函数时,它会更新'p'元素的onclick属性。在刷新页面之前,该属性保持设置状态,然后需要再次调用“bar”函数才能设置属性。链接的“onclick”属性的范围是页面的生命周期。它是页面的全局。

'x'是局部变量,其范围在声明时开始,在函数结束时结束。在函数外部,页面不知道变量'x'。

有关更多信息,请查找全局变量与局部变量。

答案 3 :(得分:0)

这称为“提升”,在您的示例中,它是提升优先级,在变量声明之前可以访问函数。我建议你阅读一下JavaScript中的提升内容。 关于变量x,它是“闭包”。如果我正确理解你的问题,你试图从另一个函数调用变量“x”。

答案 4 :(得分:0)

onclick事件正在运行,因为在bar函数中你设置了元素的onclick参数。

var p = document.getElementById("foo");
p.onclick = showAlert;

您可以将这两行移动到条形函数之外,并获得相同的效果,而无需使用单独的函数。

var p = document.getElementById("foo");
p.onclick = showAlert;

function showAlert(event) {
   alert("onclick Event detected!");
 }

这就是脚本标记中所需的全部内容。

单击元素时,将调用showAlert函数。