简体   繁体   English

在新标签页中有条件地打开链接

[英]Conditionally open links in a new tab

My goal is to make these links open in a new tab only if the check box is ticked. 我的目标是在选中复选框的情况下,使这些链接在新选项卡中打开。

Why is my anchor.getAttribute not a function if I change getElementByID to getElementsByClassName? 如果将getElementByID更改为getElementsByClassName,为什么我的anchor.getAttribute不是函数?

<!DOCTYPE html>
<html> 
    <head> </head>
    <title> </title>
    <body>
        <input id="checkr" type="checkbox">Open in New Window</input>
        <br />
        <a href="http://www.google.com" class="linker">Google</a> <br>
        <a href="http://www.w3schools.com" class="linker">W3 Schools</a> <br>
        <a href="http://www.twitch.tv" class="linker">Twitch</a> <br>

        <script>
            var checkr = document.getElementById('checkr');
            var anchor = document.getElementsByClassName('linker');
            var link = anchor.getAttribute('href');

            function OpenWindow(href) {
                if (checkr.checked) {
                    window.open(href, '_blank');
                } else {
                    window.open(href, '_self');
                }
            }
            anchor.onclick = function() {
                OpenWindow(link);
                return false;
            };
        </script>
    </body>
</html>

First, getElementsByClassName returns an array-like object...element s plural should be a clue...it's not returning a single thing, it's returning a collection of thing. 首先, getElementsByClassName返回一个类似数组的对象...元素 复数应该是一个提示...它不返回单个事物,而是返回事物的集合

So to attach your handlers, you need to loop over them like so: 因此,要附加处理程序,您需要像这样循环遍历它们:

const linkers = document.getElementsByClassName('linker');
for(const linker of linkers) {
  linker.addEventListener('click', function(evt) {
    // this is your click event listener
  });
}

Second, the way you're trying to get the anchor isn't going to work, because which anchor are you talking about ? 其次,您尝试获取锚点的方法将无法正常工作,因为您在谈论哪个锚点 The best way to do it is let the event itself tell you what anchor was clicked, which it does through it's target property: 最好的方法是让事件本身告诉您单击了哪个锚点,并通过target属性来执行以下操作:

const linkers = document.getElementsByClassName('linker');
for(const linker of linkers) {
  linker.addEventListener('click', function(evt) {
    const href = evt.target.attributes['href'].value;
  });
}

Since you don't want the default behavior to happen, call evt.preventDefault() : 由于您不希望发生默认行为,因此请调用evt.preventDefault()

const linkers = document.getElementsByClassName('linker');
for(const linker of linkers) {
  linker.addEventListener('click', function(evt) {
    evt.preventDefault();
    const href = evt.target.attributes['href'].value;
  });
}

Then finally you can get the value of the checkbox and take the appropriate action: 最后,您可以获取复选框的值并采取适当的措施:

const linkers = document.getElementsByClassName('linker');
for(const linker of linkers) {
  linker.addEventListener('click', function(evt) {
    evt.preventDefault();
    const href = evt.target.attributes['href'].value;
    const newWindow = document.getElementById('checkr').checked;
    window.open(href, newWindow ? '_blank' : '_self');
  });
}

Note that I'm using for...of loops, which may not be available in manky old browsers. 请注意,我正在使用for...of循环,在旧式浏览器中可能无法使用。 If that's a problem, you can replace them with regular for loops with indices (you can't use Array#forEach because the DOM, in its infinite wisdom [cough] doesn't return arrays, but array-like objects). 如果这是一个问题,则可以将它们替换for带有索引的常规for循环(您不能使用Array#forEach因为DOM具有无限智慧[咳嗽]不会返回数组,而是返回类似数组的对象)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM