Chrome扩展插件替换当前文本区域中的单词

Chrome Extension Replace word in current textarea

本文关键字:区域 单词 文本 扩展 插件 替换 Chrome      更新时间:2023-09-26

当用户触发某个keydown事件时,我正在尝试制作一个chrome扩展,以替换在当前<textarea>中键入的最后一个单词。所以我试过了,但并没有真正奏效。

以下是我的扩展名文件:

我的分机的manifest.json:

{
  "name": "Test",
  "description": "test",
  "version": "0.0.1",
  "permissions": [
    "activeTab"
  ],
  "background": {
    "scripts": ["background.js"],
    "persistent": false
  },
 "browser_action": {
    "default_title": "replace test"
  },
  "manifest_version": 2
}

background.js:

chrome.tabs.executeScript(null, {file: "content_script.js"});

及其content_script.js:

    document.onkeydown = replacePrevWord;  
// Azerty: Ctrl + ² 
// Qwerty: Ctrl + '
function KeyPress(e) {
    var evtobj = window.event? event : e
    if (evtobj.keyCode == 222 && evtobj.ctrlKey)
        return true;
}

function getCaretPosition(ctrl) {
    var CaretPos = 0;   // IE Support
    if (document.selection) {
        ctrl.focus();
        var Sel = document.selection.createRange();
        Sel.moveStart('character', -ctrl.value.length);
        CaretPos = Sel.text.length;
    }
    // Firefox support
    else if (ctrl.selectionStart || ctrl.selectionStart == '0')
        CaretPos = ctrl.selectionStart;
        return (CaretPos);
}

function returnWord(text, caretPos) {
    var index = text.indexOf(caretPos);
    var preText = text.substring(0, caretPos);
    if (preText.indexOf(" ") > 0) {
        var words = preText.split(" ");
        return words[words.length - 1]; //return last word
    }
    else {
        return preText;
    }
}

function replacePrevWord() {
    if(KeyPress()){
        var text = document.activeElement;
        var caretPos = getCaretPosition(text)
        var word = returnWord(text.value, caretPos);
        if (word != null) {
            text.value =  text.value.replace(word,"replaced");
        }
    }
}

这在JSFiddle上运行良好(http://jsfiddle.net/cyo646cr/3/),但我不知道如何在Chrome扩展中做到这一点。

有什么想法吗?

谢谢。

注意:自2021年1月起,使用具有chrome.scripting.executeScript()scripting权限的Manifest V3,并将<all_urls>移动到host_permissions,而不是使用具有tabs权限的不推荐使用的chrome.tabs.executeScript()

问题

您没有正确地注入脚本。这很容易说,因为调用这个简单的线路

chrome.tabs.executeScript(null, {file: "content_script.js"});

background.js中,将导致在当前选项卡中仅注入一次脚本(因为未指定tabId)。因此,在您打开的第一个选项卡中,您的脚本将只在Google Chrome的每个会话中运行一次。

查看chrome.tabs.executeScript的文档。

解决方案

要解决这个问题,你有两个选择:

  1. manifest.json中声明"content_scripts"字段,这样它将被注入到任何与模式匹配的页面中
  2. 使用chrome.tabs.onUpdated.addListener方法添加一个监听器,并在选项卡上注入脚本

选项1

像这样声明manifest.json中的"content_scripts"字段:

...
"content_scripts": [
    {
        "matches": ["<all_urls>"],
        "js": ["content_script.js"],
        "run_at": "document_idle",
        "all_frames": true
    }
],
...

现在,您的内容脚本将被注入到每个页面(因为"<all_urls>"将匹配所有页面)和页面的所有框架中。您可以在此处找到有关"content_scripts"的有用信息

选项2

请求chrome.tabs API的权限以及manifest.json:中所需的URL

...
"permissions": [
    "activeTab",
    "tabs",
    "<all_urls>"
]
...

background.js中,向chrome.tabs.onUpdated添加一个监听器,它将在每次选项卡更新(即url更新)时启动,并使用chrome.tabs.executeScript注入脚本,如下所示:

chrome.tabs.onUpdated.addListener(function(tabID, info, tab) {
    chrome.tabs.executeScript(tabID, {file: "content_script.js"});
});

请参见chrome.tabs.onUpdated的文档。