【问题标题】:Replace text on gmail using js使用js替换gmail上的文本
【发布时间】:2020-11-30 23:07:52
【问题描述】:

我正在开发一个 chrome 扩展,它替换了部分文本。但它在 Gmail 上无法正常工作。

扫描仪:

Gmail 编辑器有以下文字 -

我现在就是这个。

我能做到。

我想把它换成-

我是新手。

我能做到。

但是,每当我执行代码时,它都不会替换正确位置上的文本。 它会看到我的光标所在的位置并将文本附加到那里而不是替换预期的文本。 此 sn-p 适用于其他具有可内容编辑器的网站。

我当前的实现如下所示:

const range = document.createRange();
const ele = <div tag element for 'i am now to this.' sentence>
// rangeStart and rangeEnd are the index which wraps word 'now'

range.setStart(ele.childNodes[0], rangeStart);
range.setEnd(ele.childNodes[0], rangeEnd);
const selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
setTimeout(()=>{
        document.execCommand(
          "insertText",
          false,
          "new"
        );
      },0)

【问题讨论】:

  • 标准方法是 1) 聚焦 contentenditable 元素,2) 调用 SelectAll 命令,3) 调用 insertText 命令。见Enter data into a custom-handled input field
  • @wOxxOm 我尝试了这个解决方案,但它重置了撤消堆栈。出于同样的原因,我没有使用插入 textNodes 并使用 innerHTML 替换,并且我使用 document.execCommand 来维护并拥有无缝的撤消体验。有什么办法可以在不弄乱撤消堆栈的情况下替换文本?
  • execCommand 始终保留撤消堆栈,所以我猜您在浏览器中遇到了错误。
  • @wOxxOm 也许这就是它在几年内被标记为折旧的原因。

标签: javascript dom google-chrome-extension gmail range


【解决方案1】:

有几件事可能会出错。

一个是我注意到div 最初包含一个文本节点,其中一些文本切换到一个包含多个文本节点的节点,所有文本都完全相同,考虑到您仅使用 @ 操作,这可能会产生许多问题987654322@.

另一件事对我不起作用是执行 isertText 的文档

对我有用的东西如何:

        var range = document.createRange();
        var rangeStart = el.innerText.indexOf(s);
        var rangeEnd = rangeStart + s.length;
        var selection = window.getSelection();

        range.setStart(el.childNodes[0], rangeStart);
        range.setEnd(el.childNodes[0], rangeEnd);

        selection.removeAllRanges();
        selection.addRange(range);
        range.deleteContents();
        range.insertNode(document.createTextNode(ss))

我的整个测试场景:

(()=>{
    var all = document.getElementsByTagName('div');
    var n = all.length;
    var find = (s)=>{
        var result = [];
        for (var i = 0; i < n; i++) {
            var el = all[i];
            var text  = el && el.childNodes && el.childNodes[0] && el.childNodes[0].wholeText;
            if (text && text.match(s)) {
                result.push(el);
            }
        }
        return result.length ? result : false;
    }
    ;

    var replacer = (s,ss)=>(el)=>{
        try {
        var range = document.createRange();
        var rangeStart = el.innerText.indexOf(s);
        var rangeEnd = rangeStart + s.length;
        range.setStart(el.childNodes[0], rangeStart);
        range.setEnd(el.childNodes[0], rangeEnd);
        var selection = window.getSelection();
        selection.removeAllRanges();
        selection.addRange(range);
        range.deleteContents();
        range.insertNode(document.createTextNode(ss))
        }catch(ex){
            
        }

    }
    ;

    var elements = find('now');

    if (elements) {
        elements.map(replacer('now', 'new'))
    }

}
)(window);

祝你好运:)

【讨论】:

  • 感谢您的回答。我尝试了这个解决方案,但它重置了撤消堆栈。出于同样的原因,我没有使用插入 textNodes 并使用 innerHTML 替换。这就是我使用 document.execCommand 来维护并拥有无缝撤消体验的原因。有什么方法可以在不弄乱撤消堆栈的情况下替换文本?
猜你喜欢
  • 1970-01-01
  • 2014-09-19
  • 2016-02-10
  • 2016-02-17
  • 2020-09-26
  • 1970-01-01
  • 1970-01-01
  • 2015-12-10
  • 2011-09-25
相关资源
最近更新 更多