繁体   English   中英

在Internet Explorer中使用sprited按钮和selection.createRange()时获取所选文本时出现问题

[英]Problem getting selected text when using a sprited button and selection.createRange() in Internet Explorer

我正在努力在Stackoverflow心爱的WMD降价编辑器中实现sprited按钮,我遇到了一个奇怪的错误。 在IE的所有版本中,所选文本在按钮单击时丢失,因此,例如,突出显示一个文本块并单击代码按钮就像将光标放在选择的末尾并单击按钮一样。

例如突出显示:

This
Is
Code

并单击代码按钮为您提供:

This
Is
Code`enter code here`

真正奇怪的是我离开了原来的非sprited按钮栏, 并且工作得很好。 实际上所有按钮和键盘快捷键代码都使用相同的doClick(button)功能!

  • 旧式非sprited按钮:好的
  • 键盘快捷键:好的
  • 非IE浏览器中的Sprited按钮:好的
  • IE中的Sprited按钮: WTF

我把问题分解为对selection.createRange()的调用, 它只在单击sprited按钮时找不到任何内容。 我已经尝试过使用focus()并确保在doClick()之前尽可能少地发生但没有快乐。 键盘快捷键似乎有效,因为输入textarea永远不会丢失焦点。 任何人都可以想到一个黑客会让我以某种方式收集IE中的选定文本?

onclick处理程序如下所示:

button.onmouseout = function(){
  this.style.backgroundPosition = this.XShift + " " + normalYShift;
};

button.onclick = function() {
  if (this.onmouseout) {
    this.onmouseout();
  }
  doClick(this);
}

我已经尝试将onmouseout调用移动到doClick之后, doClick导致焦点丢失,但这不是问题。

编辑:

唯一似乎不同的是,在原始按钮代码中,您单击图像。 在sprited代码中,您单击列表项<li>并设置了背景图像。 也许它试图在我的列表项中选择不存在的文本?

/编辑

实际代码位于button-cleanup分支中的git上的wmd存储库中。

如果您恢复为0d6d1b32bb42a6bd1d4ac4e409a19fdfe8f1ffcc提交,则可以看到两个按钮栏。 最上面的一个是sprited并表现出奇怪的行为。 底部包含原始按钮栏的残余,工作正常。 可疑代码位于TextareaState对象的setInputAreaSelectionStartEnd()函数中。

我要提到的最后一件事是,暂时,我试图将控件保持在纯Javascript中,所以我想避免使用像jQuery这样的外部库来解决这个问题。

谢谢你的帮助!

我知道我自己的问题的答案是什么。

sprited按钮使用HTML列表和CSS实现,其中所有列表项都具有背景图像。 使用CSS移动背景图像以显示不同的按钮和状态(如鼠标悬停突出显示)。 标准的CSS按钮spriting东西。

这在IE中工作正常,但有一个例外:当您单击背景图像“按钮”时,IE会尝试选择空列表文本。 输入textarea中的选择消失,当前选择(将由document.selection.createRange()返回)移动到列表项中的空文本。

解决这个问题很简单 - 我创建了一个变量来缓存选择和一个标志。 在IE中,我缓存选择并在mousedown事件处理程序中设置标志。 在文本处理中,我检查是否存在标志 - 如果设置了,我使用缓存范围而不是查询document.selection.createRange()。

以下是一些代码段:

wmd.ieCachedRange = null;
wmd.ieRetardedClick = false;

if(global.isIE) {
  button.onmousedown =  function() { 
    wmd.ieRetardedClick = true;
    wmd.ieCachedRange = document.selection.createRange(); 
  };
}


var range;
if(wmd.ieRetardedClick && wmd.ieCachedRange) {
  range = wmd.ieCachedRange;
  wmd.ieRetardedClick = false;
}
else {
  range = doc.selection.createRange();
}

该解决方案只有几行代码,避免了乱用DOM并可能产生布局引擎问题。

谢谢你的帮助,Cristoph。 我在思考和谷歌搜索你的答案时想出了答案。

在IE可以选择页面上的任何其他内容之前,您必须blur()按钮。

你能提供一个重现错误的最小例子(只包含相关代码)吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM