我有一个扩展名,可以将文本插入到textarea和类似文件中。
用户可以从弹出窗口或上下文菜单中选择文本。
我有“all_frames”:true,以便我的内容脚本可以看到所有iframe - 以防textarea位于iframe中。
在保存到数据库之后(稍微多了一点),如果用户使用contextmenu将文本(通过来自background.js的消息处理到content.js处理)添加到文本区域,则文本将被添加两次。
如果用户使用popup.html机制,该机制将文本传递给相同的content.js,则只输入一次文本(所需的结果!)。
该消息仅由background.js传递一次。
例如,如果页面上有五个iframe,因此有5个content.js实例,则contextmenu监听器脚本运行10次(不是5次,应该如此)。
如果我从清单中删除“all_frames”:true,则文本只会添加一次。
但我需要保留此设置,以便在iFrame中达到textareas。弹出插件在任何地方都能很好地工作。
保存到数据库是触发行为的原因 - 该过程是一个简单的json写入php文件。我擦除了上下文菜单作为该过程的一部分 - 但同样,这不是background.js发送2条消息的问题。发送一条消息,由于某种原因,代码将通过消息传递例程2x运行。
一旦成功插入一次,我就尝试创建标记来标记,但是所有内容都是异步的,即使我能在某些情况下使其工作,我也不认为这会有所帮助。
我觉得我需要杀死一些旧的content.js进程或其他东西......
踢球者:如果我重新加载扩展程序(在开发者模式下),则contextmenu正常工作并仅插入所选文本一次。只有在我保存到数据库之后才会出现问题。
我非常接近抛出contextmenus作为一个功能,只是使用优雅的popup.html。但这似乎是一些值得理解的奇怪边缘情况。
非常感谢您一起来看看。我已经包含了一些代码以及控制台的屏幕截图,其中显示了在插入Google Doc时10x重复的content.js代码。
background.js
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
chrome.tabs.sendMessage(tabs[0].id, {method: "insertComment", comment: tempText}, function(response) {
// console.log(response.status);
});
});
content.js
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if (request.method == 'insertComment'){
var sValue = request.comment;
var currentEltag = document.activeElement.tagName.toLowerCase(); //Checking for currently selected area
console.log("currentEltag before logic: " + currentEltag + " / id: " + document.activeElement.id);
console.log("activeTag: " + activeTag);
// console.log("activeEl: " + activeEl.id + ' / name: ' + activeEl.name + ' /value: ' + activeEl.value);
if (activeTag === undefined || activeTag === null){
console.log('currentEltag in logic: ' + currentEltag);
if (currentEltag === 'iframe'){
activeTag = 'iframe';
console.log('Making activeTag equal iframe');
}
}
var sField = activeEl;
if (activeTag === 'input' || activeTag === 'textarea'){
console.log('Dealing with plain input/textarea - yes! sField is: ' + sField);
var nStart = sField.selectionStart;
var nEnd = sField.selectionEnd;
if (nStart || nEnd == '0'){
console.log("Inside insert sub with starting point: " + nStart + ' and end ' + nEnd + ' with value ' + sValue);
console.log('Print and increment...');
sField.value = sField.value.substring(0, nStart) + sValue + sField.value.substring(nEnd, sField.value.length);
sField.selectionStart = nStart + sValue.length;
sField.selectionEnd = nStart + sValue.length;
console.log('Printed value1...and flag is now: ');
chrome.storage.sync.get("flag", function(data) {
console.log("Flag", data.flag);
});
}
else {
sField.value = sValue;
console.log('Printed value2...');
}
} //End if input or textarea