javascript - 为什么更改我的框的innerHTML 会使我的按钮在Greasemonkey 中停止工作?

标签 javascript greasemonkey innerhtml

所以,我编写了一个脚本,在新选项卡中一次加载一个图像...感谢 Brock HERE ,让停止按钮可以工作。 ...

然后我打破了它,添加了我在等待该问题的答案时写入的计数器。

我看不出任何应该破坏它的原因...请帮忙?

我的脚本:

var box = document.createElement ('div');
box.id = 'mySelectBox';
GM_addStyle (
    ' #mySelectBox {             ' +
    '    background: white;     ' +
    '    border: 2px solid red; ' +
    '    padding: 4px;          ' +
    //'    position: absolute;    ' +
    '    position: fixed;       ' +
    '    top: 8px; left: 8px;   ' +
    '    max-width: 400px;      ' +
    ' } '
);
document.body.appendChild (box);
box.innerHTML = '';

var searchButton = document.createElement ('div');
searchButton.className = 'mySearchButton';
searchButton.textContent = 'Open';

GM_addStyle (
    ' .mySearchButton {           ' +
    '    background: #aaa;       ' +
    '    border: 1px solid #777; ' +
    '    padding: 1px;           ' +
    '    margin-left: 8px;       ' +
    '    float: right;           ' +
    '    cursor: pointer;        ' +
    ' } '
);
box.insertBefore (searchButton, box.nextSibling);

var stopButton = document.createElement ('div');
stopButton.className = 'myStopButton';
stopButton.textContent = 'Stop';

GM_addStyle (
    ' .myStopButton {           ' +
    '    background: #aaa;       ' +
    '    border: 1px solid #777; ' +
    '    padding: 1px;           ' +
    '    margin-left: 8px;       ' +
    '    float: right;           ' +
    '    cursor: pointer;        ' +
    ' } '
);
box.insertBefore (stopButton, box.nextSibling);

var closeButton = document.createElement ('div');
closeButton.className = 'myCloseButton';
closeButton.textContent = 'X';

GM_addStyle (
    ' .myCloseButton {           ' +
    '    background: #aaa;       ' +
    '    border: 1px solid #777; ' +
    '    padding: 1px;           ' +
    '    margin-left: 8px;       ' +
    '    float: right;           ' +
    '    cursor: pointer;        ' +
    ' } '
);

box.insertBefore (closeButton, box.firstChild);
closeButton.addEventListener ('click', function () {
    box.parentNode.removeChild (box);
}, true);

var mytable = document.getElementById

    ('lair-sort-pets').getElementsByTagName ('img');

var linksToOpen = [];
var mywin2 = null;

var okayToOpenLinks = true;

searchButton.addEventListener ('click', openpics);
stopButton.addEventListener ('click', stopLinkSequence);

function openpics () {
    okayToOpenLinks = true;

    if (linksToOpen.length === 0) {
        for (var J = 0, L = mytable.length; J < L; J++) {

            linksToOpen.push (mytable[J].src); //-- Add URL to list
        }
    }

    openLinksInSequence ();
};

original = box.innerHTML

function stopLinkSequence () {
    okayToOpenLinks = false;
}

function openLinksInSequence () {
    k = linksToOpen.length - 1

    if (mywin2) {
        mywin2.close ();
        mywin2 = null;
    }

    if (okayToOpenLinks && linksToOpen.length) {
        var link = linksToOpen.shift ();
        mywin2 = window.open (link, "my_win2");

        box.innerHTML = '<center>Links left</center><br>' + '<center>' + k + '</center><br>' + original;

        mywin2.addEventListener ('load', openLinksInSequence, false);
    }
}


如果我注释掉这一行,它会再次工作(除了没有状态计数器):

box.innerHTML = '<center>Links left</center><br>'+'<center>'+k+'</center><br>'+original;


为什么?

HERE 是 Greasemonkey 脚本的可能目标页面。

最佳答案

当您使用innerHTML(或outerHTML)更改元素的内容时,it trashes any event handlers of anything that element contained 。它还可能导致性能问题和内存泄漏。不要在用户脚本中使用 innerHTML,除非是为了初始创建全新节点。

对于倒计时/状态显示,只需创建一次 HTML,然后只需更改数据内容和/或使用 CSS 来更改显示。这样做,并稍微清理一下,代码就变成了:

var box         = document.createElement ('div');
document.body.appendChild (box);    // Must append before set outerHTML
box.outerHTML   = multilineStr ( function () {/*!
    <div id="mySelectBox">
        <div id="myStatus">Links left<br>
            <span>86</span>
        </div>
        <div id="myCloseButton">X</div>
        <div id="mySearchButton">Open</div>
    </div>
*/} );

document.getElementById ("myCloseButton").addEventListener ('click', function () {
    var box = this.parentNode;
    box.parentNode.removeChild (box);
} );
var startStopBtn    = document.getElementById ("mySearchButton");
startStopBtn.addEventListener ('click', startStopPicsLoad);

var mytable         = document.querySelectorAll ('#lair-sort-pets img');
var linksToOpen     = [];
var mywin2          = null;
var okayToOpenLinks = true;

function startStopPicsLoad () {
    if (typeof startStopPicsLoad.isStartBtn === "undefined") {
        startStopPicsLoad.isStartBtn    = true;
    }
    if (startStopPicsLoad.isStartBtn) {
        //-- Change start button to stop button
        startStopBtn.textContent        = "Stop";
        startStopPicsLoad.isStartBtn    = false;

        if (linksToOpen.length === 0) {
            for (var J = 0, L = mytable.length; J < L; J++) {
                linksToOpen.push (mytable[J].src); //-- Add URL to list
            }

            //-- Display the status area.
            document.querySelector ('#myStatus').style.display = "block";
        }

        openLinksInSequence ();
    }
    else {
        //-- Change stop button to start button
        startStopBtn.textContent        = "Open";
        startStopPicsLoad.isStartBtn    = true;

        //-- Actually stop the sequence.
        okayToOpenLinks = false;
    }
};

function openLinksInSequence () {
    if (mywin2) {
        mywin2.close ();
        mywin2 = null;
    }

    if (okayToOpenLinks) {
        if (linksToOpen.length) {
            var k           = linksToOpen.length - 1;
            var statDisp    = document.querySelector ('#myStatus span');
            statDisp.textContent = k;

            var link        = linksToOpen.shift ();
            mywin2          = window.open (link, "my_win2");
            mywin2.addEventListener ('load', openLinksInSequence, false);
        }
    }
    else {
        //-- Sequence is now stopped, reset the state variable.
        okayToOpenLinks = true;
    }
}

GM_addStyle ( multilineStr ( function () {/*!
    #mySelectBox {
        background: white;
        border: 2px solid red;
        padding: 4px;
        //position: absolute;
        position: fixed;
        top: 8px; left: 8px;
        max-width: 400px;
    }
    #myStatus {
        text-align: center;
        display: none;
    }
    #myCloseButton {
        background: #aaa;
        border: 1px solid #777;
        padding: 1px;
        margin-left: 8px;
        float: right;
        cursor: pointer;
    }
    #mySearchButton {
        background: #aaa;
        border: 1px solid #777;
        padding: 1px;
        margin-left: 8px;
        float: right;
        cursor: pointer;
    }
*/} ) );

function multilineStr (dummyFunc) {
    var str = dummyFunc.toString ();
    str     = str.replace (/^[^\/]+\/\*!?/, '') // Strip function() { /*!
            .replace (/\s*\*\/\s*\}\s*$/, '')   // Strip */ }
            .replace (/\/\/.+$/gm, '') // Double-slash comments wreck CSS. Strip them.
            ;
    return str;
}

关于javascript - 为什么更改我的框的innerHTML 会使我的按钮在Greasemonkey 中停止工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26420444/

相关文章:

javascript - 使用 jquery 查找 href 属性的父级并访问特定属性

javascript - AJAX 响应包装器

coding-style - 在 IE8 中修改 &lt;style&gt; 元素的 innerHTML

php - 获取 SimpleXMLElement 的 XML 内容

Javascript insidehtml 不适用于 Twig 标签

javascript - 无法读取 null 的属性 *0*

javascript - 单击 <li> 列表仅适用于第一个

javascript - 由于重定向,Greasemonkey 脚本在提交表单后停止执行

javascript - Greasemonkey/Tampermonkey @match 带参数的页面

javascript - 模拟用户脚本中的 Enter 键 tampermonkey