javascript - 在不丢失事件的情况下替换 HTML 中数据绑定(bind)中的值

标签 javascript html greasemonkey tampermonkey

为了提高网站的可用性,我想使用 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 驱动的,因此您需要类似 MutationObserverwaitForKeyElements 的东西。

这是一个脚本,展示了如何替换这些类型的属性:

// ==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/

相关文章:

javascript - 如何制作响应式弹出div?

javascript - 使用 javascript(内部 html)传递到 html 时多重选择不起作用

c# - 从 javascript 调用方法背后的代码

javascript - 是否可以将 ng-repeat 值分配给文本框

javascript - 使用 Javascript 在 HTML 上的事件

javascript - 如何使用 Greasemonkey 代码替换 Head 脚本

javascript - 从 GreaseMonkey 中的外部 url 获取 html

cross-browser - 如何编写跨浏览器兼容的用户脚本?

Javascript 从服务器下载 zip 文件

javascript - 使用 javascript 设置 stroke-dasharray 和 dashoffset 的长度