【问题标题】:Optimising Jquery: If href contains url from shortened links优化 Jquery:如果 href 包含来自缩短链接的 url
【发布时间】:2017-08-07 22:20:30
【问题描述】:

当我想突出显示页面中所有缩短的链接时,我试图避免潜在的问题。目前我有这个代码:

        $('a').each(function() {

            var urlHref = $(this).attr('href');
            var shortenedLinks = ["bit.ly", "amzn.to","goo.gl","t.co","lnkd.in"];

            for (var item in shortenedLinks) {
                if (urlHref.includes(shortenedLinks[item])) {
                    console.log('yes');
                } else {
                    console.log('no');
                }
            }
        });

这很好用,因为控制台中的结果是:

是的

(4) 没有

潜在问题

目前,对于每个链接,它都会遍历数组并比较 URL 的一部分。这对于少量 URL 来说很好,但是我有大约 80 个 URLshortener 服务,如果页面包含 80 个链接,这将是 6,400 次检查。

我在页面上的几个链接和所有缩短的 url 提供程序上尝试了这个,但花了一些时间来浏览它们。

问题

有没有办法加快这个过程,这样我就可以在不循环的情况下检查数组和部分 url?

【问题讨论】:

  • 这应该移到代码审查 :)

标签: jquery optimization


【解决方案1】:

首先进行一些小调整,休息是节省资源

// define the array more global, otherwise you set the array every call.
var shortenedLinks = ["bit.ly", "amzn.to","goo.gl","t.co","lnkd.in"];
$('a').each(function() {
    // use native JS where you can
    var urlHref = this.href // was: $(this).attr('href');


    for (var item in shortenedLinks) {
        // use starts with: https://stackoverflow.com/questions/646628/how-to-check-if-a-string-startswith-another-string
        if (urlHref.startsWith('http://'+shortenedLinks[item]) || urlHref.startsWith('https://'+shortenedLinks[item])) {
            console.log('yes');
            break; // we've found a match, stop looping <-- this is the biggest win
        } else {
            console.log('no');
        }
    }
});

您可以通过在数组中添加 http:// 部分来进一步改进这一点,这样您就不必重复它们了。


之后,也可以先检查是否为内链。所有内部链接都不是短网址,因此您可以一次性跳过这些链接,无需循环:

var shortenedLinks = ["bit.ly", "amzn.to","goo.gl","t.co","lnkd.in"];
function isHrefShorturl(elem){
    // <a href="/example"> is an internal link, continue
    if( elem.href.substr(0,1)!="/" ){
        for (var item in shortenedLinks) {
            // use starts with: https://stackoverflow.com/questions/646628/how-to-check-if-a-string-startswith-another-string
            if (elem.href.startsWith('http://'+shortenedLinks[item]) || elem.href.startsWith('https://'+shortenedLinks[item])) {
                return true; // when we find something, return true
            }
        }
    }
    return false; // fallback, return false if no matches
};

$('a').each(function() {
    if( isHrefShorturl(this) ){
        console.log('yes');
    } else {
        console.log('no');
    }
});

【讨论】:

  • 为什么这被否决了 - 这对我来说似乎是一个很好的解决方案。关于为什么我不应该使用它的任何 cmets?
  • 我的第一轮并不完美(尽管不值得一票否决(IMO)),也许这就是原因。无论如何,我已经改进了它,使用了更好的名称并添加了内部链接检查:)
  • 哈哈谢谢。我有一些空闲。虽然我很感激,但只要你认为值得点赞就点赞吧:)
  • @JamesG 我不知道你真正的最终目标,但如果你只需要突出显示缩短的链接,我会选择纯 CSS 解决方案
【解决方案2】:

你可以直接获取以你的字符串开头的 href 锚点

$( "a[href^='http://bit.ly']" ).each //do something
$( "a[href^='http://amzn.to']" ).each //do something

但要检查 80 个域,您必须查询 dom 80 次,因此您可以将选择器合并为一个

$( "a[href^='http://bit.ly'],a[href^='http://amzn.to']" ).each //do something

如果,正如您发布的那样,您只是想突出显示这些链接,也许您可​​以使用相同的选择器,但在 css 中

a[href^="http://bit.ly"],a[href^='http://amzn.to'] {
    background: #ffff00;
}

编辑: 经过一些讨论和测试,如果浏览器支持 querySelectorAll,就性能而言,vanilla javascript 方法看起来是最快的。

document.querySelectorAll('a[href^="http://bit.ly"],a[href^="http://amzn.to"],a[href^="http://goo.gl"]').forEach(function(e){
  e.style.background='#ffff00';//highlights the link
});

jquery 的属性选择器在老浏览器上可能比较慢

不过,css 选项(同样,取决于浏览器)对于性能和动态添加的链接来说是最好的

【讨论】:

  • 我非常怀疑这是否更好,属性选择器很昂贵。至少到$('a').filter("[href^='http://bit.ly']")
  • @Martijn,在这种情况下,属性选择器的性能要高得多,这有点令人惊讶。 jsfiddle.net/daveSalomon/0u7ccesj
  • 是的,但“属性选择器”版本有 2 个选项,我的有 5 个。您还有一个外部链接 (bit.ly)
  • 虽然,当我们添加更多时,它仍然很快。 jsfiddle.net/9f8hqg2p/1我感觉我错过了什么。
  • eheh,奇怪 :) 如果一个页面有 1000 个链接(500 个内部链接,250 个缩短的和 250 个外部未缩短的链接),您的解决方案仍将检查 1000 个链接,并循环阵列 250 次匹配对于缩短的链接并将整个数组再循环 250 次,而没有为外部非缩短链接找到任何东西
猜你喜欢
  • 2018-11-23
  • 1970-01-01
  • 2011-08-04
  • 1970-01-01
  • 1970-01-01
  • 2021-05-23
  • 2013-03-30
  • 2021-04-14
  • 1970-01-01
相关资源
最近更新 更多