Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript document.activeElement在firefox插件上不可用';s仅适用于Gmail的内容脚本_Javascript_Firefox_Firefox Addon_Firefox Addon Sdk - Fatal编程技术网

Javascript document.activeElement在firefox插件上不可用';s仅适用于Gmail的内容脚本

Javascript document.activeElement在firefox插件上不可用';s仅适用于Gmail的内容脚本,javascript,firefox,firefox-addon,firefox-addon-sdk,Javascript,Firefox,Firefox Addon,Firefox Addon Sdk,我正在使用插件sdk开发Firefox插件。此插件将菜单项添加到上下文菜单中,用户可以右键单击任何编辑控件来激活此菜单项。一旦激活,当用户键入内容时,它会显示一个带有建议的小弹出窗口 除了在Gmail上,一切都很好 在Gmail中,以下代码失败 self.port.on('showPopup', function(data) { var active = document.activeElement; console.log(active.type); if (activ

我正在使用插件sdk开发Firefox插件。此插件将菜单项添加到上下文菜单中,用户可以右键单击任何编辑控件来激活此菜单项。一旦激活,当用户键入内容时,它会显示一个带有建议的小弹出窗口

除了在Gmail上,一切都很好

在Gmail中,以下代码失败

self.port.on('showPopup', function(data) {
    var active = document.activeElement;
    console.log(active.type);
    if (active && getWordUnderCaret(active).word == data.input) {
        populateSuggestions(data);
        positionPopup(active);
        stylePopup();
    }
});
失败的原因是
document.activeElement
指向
document.body
,而
getWordUnderCaret
由于需要输入/文本区域控件而失败。这在所有其他地方都很有效。我不知道为什么它指向
document.body
,因为我可以看到焦点在输入控件上。在Firebug控制台中键入
document.activeElement
可以为我提供正确的对象

或者,我尝试自己跟踪活动元素,而不是使用
document.activeElement
。但我在某个地方遇到了类似坚持这样的问题。我无法使用
window
来持久化此操作,因为
window
是一个代理。我尝试使用
unsafeWindow
,但无法使其工作

我想知道为什么这在Gmail中失败了?如果能帮上忙,那就太好了

我的代码可在

编辑


看起来这是插件sdk的问题。我创造了一个要点,可以用来重现这个问题。它是可用的

您是否尝试过使用最新git版本的插件sdk?那里的上下文菜单已经从头重写,我听说它修复了不少bug。

我想,你指的是Gmail上的大框,在那里你在撰写电子邮件时输入邮件正文

»如果是这样的话

原因是: Gmail上的编辑控件不是文本控件(输入或文本区域)。这是一个编辑器,通过设置
document.designMode=“on”
(或
document.body.contentEditable=true
,根据浏览器的支持,可编辑

所以,当点击时;在这种情况下,查询document.activeElement的方式并不总是能得到正确的元素。您将获得包装(主)文档的
正文
,(甚至不是
iframe
正文

比如,;我相信,你的代码;将
单击
事件侦听器添加到主文档中。但您也应该将其添加到页面中的可编辑iFrame;因为页面和iframe具有不同的
文档
对象(并且iframe不会将自身设置为活动)。因此,您将得到错误的
文档.activeElement

解决方法: 在iFrame中添加必要的事件侦听器;因为你想得到他们的通知

// Add mouseup event listener to the main document
document.addEventListener('mouseup', logActiveElement, false);
// Get all the iframes on the main document.
var iframeElems = document.getElementsByTagName('iframe');
// Add mouseup event listener to the document of the iframe elements
for (var i = 0; i < iframeElems.length; ++i) {
    addIframeEvent(iframeElems[i], true, 'mouseup', logActiveElement);
}
现在,事件处理程序将把正确的
activeElement
记录到控制台

难题: 因此,;现有代码中的文本选择和检查等操作与常规编辑控件(输入、文本区域等)的工作方式不同

比如,;您的
getWordUnderCaret(编辑器)
函数通过
编辑器获取
插入点。
,它不存在于
document.body
(目标
iframe
)中。对于此类选择/检查;你应该在;而不是s中的文本选择和范围

注意:您使用的文本选择/范围jQuery库()承诺在浏览器中处理此类可编辑内容(iFrame、div等)。你在iframes上试过吗(比如在Gmail上)

进一步资料:
  • 请参见Mozilla Developer上的 网络。另一方面,它表示:“不要将焦点与焦点混淆 在文档上进行选择。如果没有选择,则
    activeElement
    是页面的
更新: 检查Gmail上的文本控件;我还使用了您的示例代码

  • 添加了
    附件:[“现有”、“顶部”、“框架”]
    到PageMod选项
  • contentScriptWhen
    的值更改为
    'end'
    (而不是 PageMod选项中的
    'ready'
    );确保所有内容,包括DOM、CSS、JS都已加载。一些内容可能会在页面就绪/加载时通过JS进行更改,因此“结束”将在页面就绪/加载后执行
  • 将选择器上下文也应用于菜单项;为了 确保该项仅在选择器上下文中显示
在Gmail(搜索框、聊天框等)和其他网站上测试;这似乎起作用了。
请参阅/测试工作负载


Gmail是指撰写新邮件时的大邮箱还是顶部的搜索框?聊天窗口中的搜索框和文本区谢谢。但我的问题是在聊天窗口的搜索框和文本区域。非常感谢您提供的详细答案。
// Adds the specified event listener to the iframe element. 
function addIframeEvent(iframeElem, editableOnly, eventName, callback) {
    // Get the document of the iframe element.
    var iframeDocument = iframeElem.contentDocument || 
                            iframeElem.contentWindow.document;
    // Watch for editableOnly argument. 
    if ( (editableOnly && isDocEditable(iframeDocument)) || !editableOnly) {
        // Add the event listener to the document of the iframe element.
        iframeDocument.addEventListener(eventName, callback, false);
    }
}

// Checks whether the specified document is content-editable or in design mode.
function isDocEditable(doc) {
    return ( ('contentEditable' in doc.body) && (doc.body.contentEditable === true) ) || 
        ('designMode' in doc) && (doc.designMode == "on") );
}

// Handler function
function logActiveElement() {
    console.log("Active Element:", document.activeElement);
}