[英]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.