簡體   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