Я пишу расширение Chrome, которое позволяет пользователям долго нажимать на ссылки на любой веб-странице, и когда это происходит, ссылка открывается в iframe, внедренном расширением Chrome, вместо открытия ссылки внутри веб-страницы или новой вкладки. Когда пользователь щелкает где-то еще по телу (не по ссылке), он должен скрывать вставленный iframe.
Это код, который я придумал, который корректно работает на 99% веб-сайтов, но у меня проблема с веб-сайтами, такими как reddit.com, который запускает навигацию по веб-странице, нажимая на элементы, отличные от ссылок (в основном, где бы вы ни щелкали (заголовок сообщения, div контейнера и т. д.), вы переходите к сообщению, и это скрывает мой iframe из-за кода в функции bodyClickListener
.
// number of milliseconds required for triggering longpress
const LONGPRESS_TIME = 500;
// Create variable for setTimeout for longpress
let openLinkTimeout;
// each 500ms check for new links in DOM and attach listeners to them
setInterval(attachClickListeners, 500);
// attach click listeners
function attachClickListeners() {
// add click listener to body
document.body.addEventListener("click", bodyClickListener);
// add click listeners to links
let links = document.querySelectorAll("a:not(.myExtensionLink)");
for (i = 0; i < links.length; i++) {
let link = links[i];
link.className = (link.className + " " + "myExtensionLink").trim();
link.addEventListener(
"mousedown",
function(e) {
console.log("MOUSE DOWN");
// if left click
if (e.button == 0) {
e.preventDefault();
openLinkTimeout = setTimeout(openLink, LONGPRESS_TIME, link.href);
}
},
true
);
// catch onclick events
link.onclick = clickListener;
}
}
// take care of left click
function clickListener(e) {
// if left click, and link was opened in blade, prevent default click behaviour
if (e.button == 0 && !openLinkTimeout) {
e.preventDefault();
e.stopPropagation();
clearTimeout(openLinkTimeout);
openLinkTimeout = null;
return false;
} else {
clearTimeout(openLinkTimeout);
openLinkTimeout = null;
return true;
}
}
// listen for clicks on body, and hide iframe if it isn't A (link) element
function bodyClickListener(e) {
if (document.querySelector("#myExtensionIframe") && e.target.tagName != "A") {
hideIframe();
}
}
// cancel timeout and open link in iframe
function openLink(href) {
clearTimeout(openLinkTimeout);
openLinkTimeout = null;
openInIframe(href)
}