繁体   English   中英

遍历Dom中的所有链接-是否有更优雅的解决方案?

[英]Iterate over all Links in the Dom - Is there a more elegant solution?

我在页面上遍历所有由pushState处理的元素,并防止出现默认行为。 我以为我的函数非常昂贵,所以我尝试了其他与事件监听器不同的解决方案,这些解决方案无法按预期工作。 在该xhr请求的readystate事件发生后,每次单击链接时都会运行此函数。 最后,我要通过xhr更改元素的内容,然后再次运行此函数。

我也尝试这样做: https : //gomakethings.com/why-event-delegation-is-a-better-way-to-listen-for-events-in-vanilla-js/

这会添加一个侦听器,看起来像是您单击的位置,但是最终向我显示了我单击的其他元素,而不是我的a元素,因此这也不起作用。

var dragging = false;

function addPushStateActionToAllLinks() {

    var e = Array.from(document.getElementsByTagName("a"));

    for ( var i = 0; i < e.length; i++ ) {

        e[i].ontouchmove = function () {
            dragging = true;
        };

        e[i].ontouchstart = function () {
            dragging = false;
        };

        e[i].onclick = function ( el ) {
            el.preventDefault ? el.preventDefault() : (el.returnValue = false);
        };

        if(e[i].getAttribute('rel') !== 'noopener noreferrer' && e[i].getAttribute('href') != "" ) {
            e[i].ontouchend = function ( el ) {
                if ( dragging === true ) {
                    return;
                }
                loadInternalLinkByXhr( this, true );
                el.preventDefault ? el.preventDefault() : (el.returnValue = false);
             };
        } else {
            e[i].ontouchend = function ( el ) {
                if ( dragging === true ) {
                  return;
                }
                loadExternalLink( this );
                el.preventDefault ? el.preventDefault() : (el.returnValue = false);
            };
        }
    }
}

编辑:我也尝试过,可以按预期工作,但我认为在移动设备上单击速度较慢:

function someFunction( ) {

    var e = document.getElementsByTagName("a");

    for ( var i = 0; i < e.length; i++ ) {

        if(e[i].getAttribute('rel') !== 'noopener noreferrer' && e[i].getAttribute('href') != "" ) {

            e[i].onclick = function ( el ) {
                if(typeof window.navigator.vibrate !== 'undefined') {
                    window.navigator.vibrate( 1 );
                }
                loadInternalLinkByXhr( this, true );
                el.preventDefault ? el.preventDefault() : (el.returnValue = false);
             };
        } else {
            e[i].onclick = function ( el ) {
                if(typeof window.navigator.vibrate !== 'undefined') {
                    window.navigator.vibrate( 1 );
                }
                loadExternalLink( this );
                el.preventDefault ? el.preventDefault() : (el.returnValue = false);
            };
        }
    }
}

我想要最高效的最佳做法。 当您单击链接,导航,标题等时,只有我的网站的一部分在改变。保持原样。 我尝试向每个元素添加事件侦听器,最终触发多个xhr请求,而这个请求越来越多,而我无法弄清楚为什么会发生这种情况,我还尝试在添加新事件侦听器之前将其删除,但似乎仍会向其中添加多个它。 对于我来说,这仅适用于完整的页面请求,我想避免这种情况。 但是,我的功能按预期工作,在仅使用onclick之前,现在我尝试在ontouchend上进行移动阻止,因为它可能会更快地做出反应。 该项目是新项目,因此我对现代浏览器功能和Vanilla JS持开放态度。

如果在原始设计中使用函数声明,则可以对每个事件使用一个函数,而不必重复它们。

function ontouchmove  () {
   dragging = true;
};

function ontouchstart() {
    dragging = false;
};

function onclick( el ) {
    el.preventDefault ? el.preventDefault() : (el.returnValue = false);
};



for ( var i = 0; i < e.length; i++ ) {

        e[i].ontouchmove = ontouchmove;

        e[i].ontouchstart ontouchstart;

        e[i].onclick = onclick;

        if(e[i].getAttribute('rel') !== 'noopener noreferrer' && e[i].getAttribute('href') != "" ) {
            e[i].ontouchend = function ( el ) {
                if ( dragging === true ) {
                    return;
                }
                loadInternalLinkByXhr( this, true );
                el.preventDefault ? el.preventDefault() : (el.returnValue = false);
             };
        } else {
            e[i].ontouchend = function ( el ) {
                if ( dragging === true ) {
                  return;
                }
                loadExternalLink( this );
                el.preventDefault ? el.preventDefault() : (el.returnValue = false);
            };
        }
    }
}

否则,使用JQuery一次选择所有元素并在整个选择中设置事件会更有意义。

var allLinks = $('a');

allLinks.on('touchmove', function () {
     dragging = true;
};)


allLinks.on('touchstart', function () {
     dragging = false;
};)


allLinks.on('cick', function () {
     this.preventDefault ? this.preventDefault() : (this.returnValue = false);
};)

您可以使用.each方法来迭代选择并基于属性执行操作。

allLinks.each(function() {

   if ($(this).attr('rel') !== 'noopener noreferrer' && $(this).attr('href') != "" ){
       ...
   }

});

暂无
暂无

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

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