当我单击使用 tampermonkey 添加到其中的按钮时,如何阻止 gmail 打开电子邮件?

How to stop gmail from opening the email when I click the button I added to it with tampermonkey?

我做了这个 tampermonkey 脚本来解析我的 gmail 收件箱项目并添加一个按钮 linking 到我们的 Redmine 问题跟踪器,这样我就可以打开线程而无需打开电子邮件。我添加的这个按钮,立即打开一个新选项卡并将焦点切换到它。

它工作正常,除了每次我单击该按钮时,它还会在 Gmail page/browser 选项卡上打开电子邮件。为了解决这个问题,我添加了一个 setTimeout(function() { window.history.go(-1); }, 1000) 以在打开 link.

后跳回

问题是这不允许我一次打开多个问题,即按住 Ctrl+Click 因为它会打开电子邮件并跳回(大闪烁)。

当我点击我添加的按钮时,如何阻止电子邮件打开?

我尝试将超时设置为 0,即 setTimeout(function() { window.history.go(-1); }, 0),但这没有帮助,因为 GMail 在当前浏览器 tab/page 和新页面(以及我的 Redmine 页面),然后当我用 Ctrl+Click.

单击我的按钮时,我打开了 2 个新页面
  1. 有什么我可以添加到 setTimeout(..., 0) 的东西可以在它开始之前取消电子邮件打开吗? (所以我可以通过按住 Ctrl 按钮一次打开多个选项卡)
  2. 或者当我点击我刚添加的按钮时,有没有办法在打开电子邮件时删除点击事件? (所以我可以通过按住 Ctrl 按钮一次打开多个选项卡)
// ==UserScript==
// @name         GMail Redmine Link to Redmine
// @namespace    *
// @version      0.1
// @description  Redmine button to jump directly to redmine thread
// @author       user
//
// @include https://mail.google.com/*
// @require http://code.jquery.com/jquery-3.4.1.min.js
// ==/UserScript==

(function() {
    'use strict';

    let keepclosing = async () => {
        let elementid = `div[role="link"] span[data-thread-id]`;
        let viewedbar = $(elementid).not('span[data-donot-process-this-again]');
        if(viewedbar.length)
        {
            $(viewedbar).each(function(index, item)
            {
                let newitem = $(item).text();
                let redmineregex = /\#(\d+)/g;
                let regeresult = redmineregex.exec(newitem);

                if(regeresult && regeresult.length) {
                    let redminecase = regeresult[1];
                    let previousItem = function() {
                        window.open(`https://redmine.com/issues/${redminecase}`);
                        setTimeout(function() { window.history.go(-1); }, 1000);
                        return false;
                    };
                    let mybutt = document.createElement("input");
                    mybutt.type = "button";
                    mybutt.id = `OpenRedmineCaseButton${redminecase}`;
                    mybutt.value = `#${redminecase}`;
                    mybutt.onclick = previousItem;

                    $($($($(item).parent()).parent()).parent()).prepend(mybutt);
                }
                $(item).attr('data-donot-process-this-again', true);
            })
        }
        setTimeout(keepclosing, 500);
    }
    setTimeout(keepclosing, 500);
})();

观察:我发布的图像有颜色,因为完整的代码也必须删除部分以简化问题:

let LatestIssues = 44000;
...
let casenumber = parseInt(redminecase);
if( casenumber > LatestIssues ) {
    mybutt.style.background = '#ffe0e0';
}
else if( casenumber > LatestIssues - 2000 ) {
    mybutt.style.background = '#faffd4';
}
else {
    mybutt.style.background = '#cfe9ff';
}

// This is something I used to add the button more above, but did not worked
// $($($($($($($(item).parent()).parent()).parent()).parent()).parent()).parent()).prepend(mybutt);

只需阻止事件向上传播到行中 Gmail 的点击侦听器即可达到目的:

let previousItem = function(e) {
    e.stopPropagation();
    window.open(`https://redmine.com/issues/${redminecase}`);
};

IMO,更简单的方法是:

'use strict';

const processed = new Set();
const addButtons = () => {
    const parentSelector = `div[role="link"] > div`;
    for (const parent of document.querySelectorAll(parentSelector)) {
        const row = parent.children[0];
        if (processed.has(row)) continue;
        processed.add(row);
        const caseNumber = row.querySelector('span[data-thread-id]')?.textContent.match(/$(\d+)/)?.[1];
        if (!caseNumber) continue;
        const button = row.insertAdjacentElement('afterbegin', document.createElement('input'));
        button.type = 'button';
        button.onclick = (e) => {
            e.stopPropagation();
            window.open(`https://redmine.com/issues/${caseNumber}`);
        };
        button.value = `#${caseNumber}`;
    }
};
setInterval(addButtons, 500);