使用javascript获取点击链接的正确href?

时间:2015-06-13 23:02:08

标签: javascript html

我有一个简单的html菜单:

<div id="menulinks">
  <ul>
    <li><a href="#link1">Link 1</a></li>
    <li><a href="#link2">Link 2</a></li>
    <li><a href="#link3">Link 3</a></li>
    <li><a href="#link4">Link 4</a></li>
  </ul>
</div>

我需要编写一个javascript - 不能使用jQuery - 这给了我一个点击锚链接的href。这就是我所做的:

var a = document.getElementById("menulinks").getElementsByTagName("a");
for ( var o = 0; o < a.length; o++ ) {
  var clickedLink = a[o];
  clickedLink.addEventListener("click", function() {
    var b = clickedLink.getAttribute("href");
    alert(b);
  });
}

它有效,但无论我点击哪个链接,我总是在警告框中输入'#link4'作为答案。你能告诉我,有什么不对吗?提前谢谢!

5 个答案:

答案 0 :(得分:1)

您可以在处理程序中使用this访问与事件相关的元素。否则,您将引用分配给clickedLink

的最后一个元素

此外,您可以使用querySelectorAll快速选择链接。但是,如果链接更改querySelectorAll返回的列表不会更改,那么您必须再次选择链接。 querySelectorAll返回NodeList,而不是HTMLCollection,因此无法使用forEach之类的数组方法进行访问,但在这种情况下它将完美运行。

&#13;
&#13;
var a = document.querySelectorAll("#menulinks a");
for (var o = 0; o < a.length; o++) {
    a[o].addEventListener('click', function () {
        alert(this.href);
    }, false);
}
&#13;
<div id="menulinks">
    <ul>
        <li><a href="#link1">Link 1</a>
        </li>
        <li><a href="#link2">Link 2</a>
        </li>
        <li><a href="#link3">Link 3</a>
        </li>
        <li><a href="#link4">Link 4</a>
        </li>
    </ul>
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

您的问题是每次clickedLink迭代时for loop都会被后续值覆盖,当点击链接时,clickedLink已被分配了最后一个href 1}}值。

我猜测你的混淆是因为假设Javascript在实际使用lexical scoping时有阻止作用域。 (您也可以阅读variable hoisting ...)

一种解决方案是将分配给clickedLink的每个值绑定到立即调用的函数...

for ( var o = 0; o < a.length; o++ ) {
  var clickedLink = a[o];
  (function(clickedLink) { 
    clickedLink.addEventListener("click", function() {
      var b = clickedLink.getAttribute("href");
      alert(b);
    });
  })(clickedLink);
}

答案 2 :(得分:1)

这是围绕范围问题的另一种方式;将环体包裹在IIFE中。它基本上是@sfletche的答案,但“向上”一个级别,并且不需要参数:

var a = document.getElementById("menulinks").getElementsByTagName("a");
for (var o = 0; o < a.length; o++) {
  (function() {
    var clickedLink = a[o];
    clickedLink.addEventListener("click", function() {
      var b = clickedLink.getAttribute("href");
      alert(b);
    });
  })();
}
<div id="menulinks">
  <ul>
    <li><a href="#link1">Link 1</a></li>
    <li><a href="#link2">Link 2</a></li>
    <li><a href="#link3">Link 3</a></li>
    <li><a href="#link4">Link 4</a></li>
  </ul>
</div>

我不会以这种方式,但如果您刚刚进入闭包和/或IIFE,它可能更容易理解。

答案 3 :(得分:0)

链接clickedLink指的是每次迭代都会被覆盖,当链接被点击时,它指的是最后一个链接。

您只需更改

即可轻松解决问题
var b = clickedLink.getAttribute("href");

var b = this.getAttribute("href");

那么它会起作用:

var a = document.getElementById("menulinks").getElementsByTagName("a");
for ( var o = 0; o < a.length; o++ ) {
  var clickedLink = a[o];
  clickedLink.addEventListener("click", function() {
    var b = this.getAttribute("href");
    alert(b);
  });
}
<div id="menulinks">
  <ul>
    <li><a href="#link1">Link 1</a></li>
    <li><a href="#link2">Link 2</a></li>
    <li><a href="#link3">Link 3</a></li>
    <li><a href="#link4">Link 4</a></li>
  </ul>
</div>

或者如果你想使用新的ES6功能(在某些现代浏览器中工作但不是全部),那么你可以这样做:

<div id="menulinks">
  <ul>
    <li><a href="#link1">Link 1</a></li>
    <li><a href="#link2">Link 2</a></li>
    <li><a href="#link3">Link 3</a></li>
    <li><a href="#link4">Link 4</a></li>
  </ul>
</div>
<script type="application/javascript;version=1.7">
var a = document.getElementById("menulinks").getElementsByTagName("a");
for ( var o = 0; o < a.length; o++ ) {
  let clickedLink = a[o];
  clickedLink.addEventListener("click", function() {
    alert( clickedLink.getAttribute("href") );
  });
}
</script>

答案 4 :(得分:0)

您刚刚发现variable hoisting。这是解释器认为代码的样子。

var a = document.getElementById("menulinks").getElementsByTagName("a");
var clikedLink, o;
for ( o = 0; o < a.length; o++ ) {
  clickedLink = a[o];
  clickedLink.addEventListener("click", function() {
    var b = clickedLink.getAttribute("href");
    alert(b);
  });
} 

由于事件监听器中的clickedLinkclosed over,因此它将在循环的每个交互中继续被覆盖,因此为什么每个链接都给出了最后一个a标记的href,因为 是最后一个a标记。

这是你如何正确地做到这一点

var a = document.getElementById("menulinks").getElementsByTagName("a");
for ( var o = 0; o < a.length; o++ ) {
  a[o].addEventListener("click", function() {
    var b = this.getAttribute("href");
    alert(b);
  }.bind(a[o]));
}

或者如果你不能使用Function.prototype.bind

var a = document.getElementById("menulinks").getElementsByTagName("a");
for ( var o = 0; o < a.length; o++ ) {
  (function(l) {
    l.addEventListener("click", function() {
    var b = l.getAttribute("href");
    alert(b);
  })(a[o]);
}