【问题标题】:How to detect if selected text is in an editable area?如何检测所选文本是否在可编辑区域中?
【发布时间】:2020-12-31 07:57:24
【问题描述】:

程序员的幻想

我创建了一个简单的用户脚本,可以非常快速地对我选择的文本进行操作。它是这样的:

  1. 我从p 元素中选择一个字词、一个网站(不一定是链接)或一个短语
  2. 当我按下触发键时,算法会尝试判断它是网站还是文本。它将打开一个标签:如果它是一个网站,那就是它会加载的内容;如果是文本,它会用谷歌搜索。

问题暴露了它丑陋的头

它很好用,除了我在编辑文本时。如果我正在编辑我在textarea/input 中写的内容,它会触发,可能会丢失我写的内容。幸运的是,通常有缓存,甚至网站会警告我有未保存的更改,这样我就不会丢失我写的任何内容。但这是要解决的问题。

挑战

用户脚本只能在无法编辑的文本上运行。如果所选文本在textarea 内,您会认为这与不调用函数一样简单。但是有很多方法可以在不使用经典元素的情况下显示可编辑内容。我发现的“最佳”过滤器是检查document.activeElement.isContentEditable。然而,在这个盒子里,它返回false。这是一个textarea 元素,所以我可以将它添加到过滤器中,并且可以通过我能想到的更多来实现。但除了是一个丑陋的解决方案之外,它也不是万无一失的。

除了添加“你是不是不小心跑了我?”提示,有没有更好的方法来做到这一点?

编辑:my current code

【问题讨论】:

  • 我在类似用户脚本中的 hacky 解决方案是检查键盘输入。我展示了“你是不是不小心跑了我?”仅在页面上有多个按键事件时才提示。多次按键表示用户编写了某些内容。我排除了一些键,例如enter、escape 和 ctrl/alt/shift + 组合键。这在静态网站上效果很好。
  • 所以你会一直在听按键,对吧?它不是超级优雅,但它可能是答案......

标签: javascript google-chrome tampermonkey userscripts


【解决方案1】:

如果我理解正确的话....这里是一个如何去做的例子。

if (['TEXTAREA', 'INPUT'].includes(document.activeElement.nodeName)) {
  // it is in textarea, input
}
else if (document.activeElement.isContentEditable) {
  // it is in contentEditable element
}
else {
  // not above
}

Above 不是唯一的方法,例如以下使用window.getSelection():

const sel = window.getSelection();
const text = sel.toString();

if (!text.trim()) {
  // there is no selection
  // or selection is white-space
  // or selection is in textarea, input
}
else if (document.activeElement.isContentEditable) {
  // it is in contentEditable element
}
else {
  // not above
}

【讨论】:

  • 谢谢。这与我所做的非常相似[但你的更好,所以我在偷那个:)],但它涵盖了所有用例吗?现在我找不到示例,但有时我看到人们使用 div 或 span 元素可在某些 JS 框架的帮助下编辑,isContentEditable 返回 false。也许我应该尝试发送一个角色并以某种方式检查它是否“通过”......?我期待一个万无一失的方法。
  • @CarlesAlcolea 这应该涵盖所有常见情况,但可以在需要时进一步调整。如果您有此类边缘情况的示例,请告诉我,我会更新回复。我也会用更多信息更新回复。
  • 我用我正在使用的代码更新了帖子
  • 我能想到一个异常值。使用内部具有 textareainput 的自定义元素会导致它仍然可编辑,但 nodeName 不是“INPUT”或“TEXTAREA”,而是自定义标签名称。
猜你喜欢
  • 1970-01-01
  • 2013-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多