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

Posted

技术标签:

【中文标题】Chrome 扩展替换当前文本区域中的单词【英文标题】:Chrome Extension Replace word in current textarea 【发布时间】:2014-12-07 18:06:51 【问题描述】:

当用户触发某个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 扩展程序中执行此操作。

有什么想法吗?

谢谢。

【问题讨论】:

如何获得222 KeyCode?当我查看此列表时:cambiaresearch.com/articles/15/javascript-char-codes-key-codes 222 是单引号。你想在哪个键上做一个动作? ²? 哦,我想我明白了...Ctrl + ' ??该键确实适用于小提琴 我是 azerty 键盘上的法国人,我忘了 ² 在 qwerty 中不存在 ^^ 所以是的,它是 Ctrl + ' 给你的 ^^ 不确定,但也许你可以使用 chrome.commands developer.chrome.com/extensions/commands 我已经尝试在清单上添加命令,但我从未触发过它们.. :/ 【参考方案1】:

注意:自 2021 年 1 月起,将Manifest V3 与chrome.scripting.executeScript()scripting 权限一起使用,并将<all_urls> 移动到host_permissions,而不是将已弃用的chrome.tabs.executeScript() 与@ 一起使用987654331@权限。

问题

您没有正确注入脚本。说起来容易,因为调用这个简单的行

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

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

看看the documentation for chrome.tabs.executeScript

解决方法

要解决此问题,您有两种选择:

    在您的 manifest.json 中声明 "content_scripts" 字段,以便将其注入任何匹配模式的页面中。 使用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
    
],
...

现在您的内容脚本将被注入每个页面(因为"&lt;all_urls&gt;" 将匹配所有页面)和页面的所有框架。您可以找到有关 "content_scripts" here 的有用信息。

选项 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");
);

the documentation for chrome.tabs.onUpdated

【讨论】:

在选项 1 中,您无需为清单中声明的​​脚本显式声明权限。另外,为了充分发挥作用,请解释为什么当前的注入方式不正确。 @Marco Bonelli 非常感谢

以上是关于Chrome 扩展替换当前文本区域中的单词的主要内容,如果未能解决你的问题,请参考以下文章

用空格替换文本区域中的逗号、破折号和输入键

将文本区域中的 <br /> 替换为行分隔符(Javascript)

如何防止文本区域中的重复空格

文本区域中的CSS悬停滚动条光标

如何识别富可编辑文本区域中的文本溢出

如何阻止 Chrome 在我的文本区域中添加额外的换行符?