为了提高网站的可用性,我想使用 Greasemonkey (JavaScript) 更改以下内容:
data-bind="text: 'Price: ' + db.totalpr().toFixed(2) + ' GBP'"`
到
data-bind="text: 'Price: ' + db.totalpr().toFixed(2)*current_exchange_rate + ' USD'"`
尝试过
document.body.innerHTML = document.body.innerHTML.replace(text_to_find, text_to_replace)
但是页面丢失了事件并且没有数据被加载:“Price”没有加载任何东西并且保持为空。
然后我发现了这个:Replace text in a website
function replaceTextOnPage(from, to){
getAllTextNodes().forEach(function(node){
node.nodeValue = node.nodeValue.replace(new RegExp(quote(from), 'g'), to);
});
function getAllTextNodes(){
var result = [];
(function scanSubTree(node){
if(node.childNodes.length)
for(var i = 0; i < node.childNodes.length; i++)
scanSubTree(node.childNodes[i]);
else if(node.nodeType == Node.TEXT_NODE)
result.push(node);
})(document);
return result;
}
function quote(str){
return (str+'').replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
}
}
但是,不幸的是,它在我的情况下不起作用:它可以将“价格”替换为我想要的任何文本,但不是
db.totalpr().toFixed(2)
到
"db.totalpr().toFixed(2)*current_exchange_rate"
有什么想法可以让它在不丢失事件的情况下工作吗?
更新:
<div class="row">
<div class="col-md-5">
<h5 data-bind="text: 'Price: ' + db.totalpr().toFixed(2) + ' GBP'" style="margin-left:7px"></h5>
</div>
</div>
最佳答案
这看起来符合“X Y 问题”。请参阅折叠下方...
问题意味着替换属性,而不是文本。 (而且,只是属性,这样您就不会破坏该 ajax 驱动的页面。)
由于它是 ajax 驱动的,因此您需要类似 MutationObserver
或 waitForKeyElements
的东西。
这是一个脚本,展示了如何替换这些类型的属性:
// ==UserScript==
// @name _Dynamically replace JS-coded attributes
// @match *://YOUR_SERVER.COM/YOUR_PATH/*
// @require https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js
// @require https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant GM_addStyle
// @grant GM.openInTab
// ==/UserScript==
//- The @grant directives are needed to restore the proper sandbox.
var current_exchange_rate = 1.41; // Hard coded for demo purposes only.
waitForKeyElements ("[data-bind]", ReplacePriceAttributes);
function ReplacePriceAttributes (jNode) {
// Following could alternatively could use `.data("bind")` since attribute is of `data-` type.
var oldBind = jNode.attr ("data-bind");
if (/Price:/.test (oldBind) ) {
let newBind = oldBind.replace ("db.totalpr().toFixed(2)", `( db.totalpr() * ${current_exchange_rate} ).toFixed(2)`);
jNode.attr ("data-bind", newBind)
}
}
current_exchange_rate
在脚本中是硬编码的。获取实时值超出了这个问题的范围,covered elsewhere , 无论如何。
真正的问题:
替换这些属性值不太可能实现您真正想要的(以美元显示价格)。如果页面由 Knockout.js 驱动(看起来似乎是),则尤其如此。
要更改您看到的显示价格,请使用与 linked answer 非常相似的技术。 ...
waitForKeyElements ("[data-bind]", ReplacePriceText);
function ReplacePriceText (jNode) {
var oldPriceTxt = jNode.text ();
/* Appropriate HTML not provided by question asker, but convert price text
as shown in linked answer, setting newPriceTxt
*/
jNode.text (newPriceTxt);
}
关于javascript - 在不丢失事件的情况下替换 HTML 中数据绑定(bind)中的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49638267/