Tampermonkey 脚本根据页面的打开和呈现方式给出不同的结果? (内容相同)
Tampermonkey script gives different results depending on how the page is opened and rendered? (Content is the same)
我有一个用户脚本(Chrome 中的 Tampermonkey),它 运行 可以在用户打开页面时使用,也可以在单独的 window 中打开页面(相关脚本然后 运行s)。当用户打开页面时,一切都按预期进行。
但是,当页面在另一个 window 中打开时,此功能有时不会按预期处理文本。
代码:
function processTableRows() {
var regex = new RegExp(/(.*?)(\d{7})/);
var texts = document.querySelectorAll(".table__row");
var out = [];
texts.forEach(text=> {
var fixMonth = text.innerText.replace(/(\d*)月/, function(p1) {
const monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
return monthNames[(parseInt(p1) - 1)];
}).replace(regex,
"example.com/page.html?id=\n");
out.push(fixMonth);
});
return out;
}
示例页面文本(脚本前):
05 6月 2019 8989898
Some text
Some more text
当用户打开页面时,控制台中的用户脚本和代码都给出了预期的输出:
example.com/page.html?id=8989898
05 Jun 2019
Some text
Some more text
但是,当它在单独的 Window 中启动时,它 returns(TM 脚本和控制台 运行):
05 Jun 2019
example.com/page.html?id=8989898
Some text
Some more text
我无法想象为什么第二个 replace()
在单独的 window 中似乎有不同的功能。我认为这可能与 JavaScript 的一些正则表达式时髦有关,例如移动索引,影响链式调用,但 MDN 表明它只是 returns 一个字符串。
编辑:
在以下评论后获得的更多信息:
当页面以新的(弹出窗口)启动时 window,它很小,原始文本呈现如下:
05 6月 2019
8989898
Some text
Some more text
然而,当 window 较大时(如用户访问它时),它看起来像:
05 6月 2019 8989898
Some text
Some more text
一般来说,如果相同的用户脚本在同一页面上给出不同的结果,具体取决于该页面的打开方式,原因可能是:
时机。页面加载速度变慢或变快取决于各种因素,经常缓存。所以脚本可能会在它寻找的内容是 present/finished.
之前触发
使用 waitForKeyElements
或 MutationObserver
进行补偿。搜索以前的问题,其中已涵盖此内容。
AJAX。该页面实际上并没有进行正常的 HTML 加载,而是使用 javascript 来(重新)编写一个 "new" 页面。
同样,waitForKeyElements
或 MutationObserver
对此类页面很有帮助。并且,同样,在前面的问题中已经涵盖。
"Responsive"layout/behaviors。同一页面可能会显示不同的内容,and/or 以不同的方式显示,具体取决于 window 大小(通常)或某些状态跟踪或某些 passed-in 参数。
在这种情况下,您的脚本可能需要逻辑代码来适应页面的不同变体。
对渲染敏感的代码。如果您的脚本依赖于定位、CSS 样式、元素大小等;它可能仅在 window 大小不同或页面呈现时间不同时中断。
在这种情况下,问题代码似乎有原因 4 的变体。它使用 innerText
和 innerText varies its results depending on whitespace and visibility。 (innerText 也比 textContent
慢。)
解决方案是 使用 textContent
而不是 innerText
。
这是一个演示,展示了这两个属性有何不同:
srcNode = $(".variableDiv")[0];
$("#TC").text (srcNode.textContent);
$("#IT").text (srcNode.innerText);
.variableDiv {border: 1px solid gray; margin-bottom: 1em;}
td, th {border: 1px solid gray; padding: 0.2ex 1ex;}
table {border-collapse: collapse;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Source Div:
<div class="variableDiv">
Chuck Norris has two speeds: <br> Walk, and Kill.<br>
<span style="display:none">Hidden Text</span>
</div>
<table>
<tr> <th>textContent</th> </tr>
<tr> <td><pre id="TC"> </pre></td> </tr>
<tr> <th>innerText</th> </tr>
<tr> <td><pre id="IT"> </pre></td> </tr>
</table>
IIRC,不同的浏览器也可能会改变 innerText 在隐藏溢出 and/or 遮挡元素上的结果,但我尚未验证。
我有一个用户脚本(Chrome 中的 Tampermonkey),它 运行 可以在用户打开页面时使用,也可以在单独的 window 中打开页面(相关脚本然后 运行s)。当用户打开页面时,一切都按预期进行。
但是,当页面在另一个 window 中打开时,此功能有时不会按预期处理文本。
代码:
function processTableRows() {
var regex = new RegExp(/(.*?)(\d{7})/);
var texts = document.querySelectorAll(".table__row");
var out = [];
texts.forEach(text=> {
var fixMonth = text.innerText.replace(/(\d*)月/, function(p1) {
const monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
return monthNames[(parseInt(p1) - 1)];
}).replace(regex,
"example.com/page.html?id=\n");
out.push(fixMonth);
});
return out;
}
示例页面文本(脚本前):
05 6月 2019 8989898
Some text
Some more text
当用户打开页面时,控制台中的用户脚本和代码都给出了预期的输出:
example.com/page.html?id=8989898
05 Jun 2019
Some text
Some more text
但是,当它在单独的 Window 中启动时,它 returns(TM 脚本和控制台 运行):
05 Jun 2019
example.com/page.html?id=8989898
Some text
Some more text
我无法想象为什么第二个 replace()
在单独的 window 中似乎有不同的功能。我认为这可能与 JavaScript 的一些正则表达式时髦有关,例如移动索引,影响链式调用,但 MDN 表明它只是 returns 一个字符串。
编辑: 在以下评论后获得的更多信息:
当页面以新的(弹出窗口)启动时 window,它很小,原始文本呈现如下:
05 6月 2019
8989898
Some text
Some more text
然而,当 window 较大时(如用户访问它时),它看起来像:
05 6月 2019 8989898
Some text
Some more text
一般来说,如果相同的用户脚本在同一页面上给出不同的结果,具体取决于该页面的打开方式,原因可能是:
时机。页面加载速度变慢或变快取决于各种因素,经常缓存。所以脚本可能会在它寻找的内容是 present/finished.
之前触发 使用waitForKeyElements
或MutationObserver
进行补偿。搜索以前的问题,其中已涵盖此内容。AJAX。该页面实际上并没有进行正常的 HTML 加载,而是使用 javascript 来(重新)编写一个 "new" 页面。
同样,waitForKeyElements
或MutationObserver
对此类页面很有帮助。并且,同样,在前面的问题中已经涵盖。"Responsive"layout/behaviors。同一页面可能会显示不同的内容,and/or 以不同的方式显示,具体取决于 window 大小(通常)或某些状态跟踪或某些 passed-in 参数。
在这种情况下,您的脚本可能需要逻辑代码来适应页面的不同变体。对渲染敏感的代码。如果您的脚本依赖于定位、CSS 样式、元素大小等;它可能仅在 window 大小不同或页面呈现时间不同时中断。
在这种情况下,问题代码似乎有原因 4 的变体。它使用 innerText
和 innerText varies its results depending on whitespace and visibility。 (innerText 也比 textContent
慢。)
解决方案是 使用 textContent
而不是 innerText
。
这是一个演示,展示了这两个属性有何不同:
srcNode = $(".variableDiv")[0];
$("#TC").text (srcNode.textContent);
$("#IT").text (srcNode.innerText);
.variableDiv {border: 1px solid gray; margin-bottom: 1em;}
td, th {border: 1px solid gray; padding: 0.2ex 1ex;}
table {border-collapse: collapse;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Source Div:
<div class="variableDiv">
Chuck Norris has two speeds: <br> Walk, and Kill.<br>
<span style="display:none">Hidden Text</span>
</div>
<table>
<tr> <th>textContent</th> </tr>
<tr> <td><pre id="TC"> </pre></td> </tr>
<tr> <th>innerText</th> </tr>
<tr> <td><pre id="IT"> </pre></td> </tr>
</table>
IIRC,不同的浏览器也可能会改变 innerText 在隐藏溢出 and/or 遮挡元素上的结果,但我尚未验证。