I'm working on implementing sprited buttons in Stackoverflow's beloved WMD markdown editor and I've run into an odd bug. On all versions of IE, the selected text is lost upon button clicks, so, say, highlighting a block of text and clicking the code button acts like you placed the cursor at the end of the selection and clicked the button.

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

e.g. highlighting this:

例如突出这个:

This
Is
Code

and clicking the code button give you:

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

This
Is
Code`enter code here`

What's really weird is that I left the original non-sprited button bar in and that works just fine. In fact ALL buttons and keyboard shortcuts code use the same doClick(button) function!

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

  • Old-style non-sprited buttons: OK
  • 旧式非sprited按钮:好的

  • Keyboard shortcuts: OK
  • 键盘快捷键:好的

  • Sprited buttons in non-IE browsers: OK
  • 非IE浏览器中的Sprited按钮:好的

  • Sprited buttons in IE: WTF
  • IE中的Sprited按钮:WTF

I've isolated the problem down to a call to selection.createRange() which finds nothing only when the sprited button is clicked. I've tried screwing around with focus()ing and making sure as little as possible happens before the doClick() but no joy. The keyboard shortcuts seem to work because the focus is never lost from the input textarea. Can anyone think of a hack that will let me somehow collect the selected text in IE?

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

The onclick handler looks like this:

onclick处理程序如下所示:

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

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

I've tried moving the onmouseout call to after the doClick in case that was causing a loss of focus but that's not the problem.

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

EDIT:

The only thing that seems to be different is that, in the original button code, you are clicking on an image. In the sprited code, you are clicking on a list item <li> with a background image set. Perhaps it's trying to select the non-existent text in my list item?

唯一不同的是,在原始按钮代码中,您单击图像。在sprited代码中,您单击列表项

  • 并设置了背景图像。也许它试图在我的列表项中选择不存在的文本?

  • /EDIT

    Actual code is located in my wmd repository on git in the button-cleanup branch.

    实际代码位于按钮清理分支中的git上的wmd存储库中。

    If you revert to the 0d6d1b32bb42a6bd1d4ac4e409a19fdfe8f1ffcc commit you can see both button bars. The top one is sprited and exhibits the weird behavior. The bottom one contains the remnants of the original button bar and works fine. The suspect code is in the setInputAreaSelectionStartEnd() function in the TextareaState object.

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

    One last thing I should mention is that, for the time being, I'm trying to keep the control in pure Javascript so I'd like to avoid fixing this with an external library like jQuery if that's possible.

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

    Thanks for your help!

    谢谢你的帮助!

    2 个解决方案

    #1


    I know what the answer to my own question is.

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

    The sprited buttons are implemented using an HTML list and CSS, where all the list items have a background image. The background image is moved around using CSS to show different buttons and states (like mouseover highlights). Standard CSS button spriting stuff.

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

    This works fine in IE with one exception: IE tries to select the empty list text when you click on the background image "button". The selection in the input textarea goes away and the current selection (which will be returned by document.selection.createRange()) is moved to the empty text in the list item.

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

    The fix for this is simple - I created a variable to cache the selection and a flag. In IE I cache the selection and set the flag in a mousedown event handler. In the text processing, I check for the presence of the flag - if it's set I use the cached range instead of querying document.selection.createRange().

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

    Here are some code snippets:

    以下是一些代码段:

    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();
    }
    

    The solution is only a few lines of code and avoids messing around with the DOM and potentially creating layout engine issues.

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

    Thanks for your help, Cristoph. I came up with the answer while thinking and googling about your answer.

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

    更多相关文章

    1. 使用按钮单击按钮添加表格
    2. 具有相同名称的Mutiple按钮显示不同的div。
    3. 如何检查不包含提交按钮的HTML5表单的有效性?
    4. 当函数在单独的PHP文件中定义时,调用JavaScript函数onclick按钮事
    5. 由ajax [duplicate]生成时,formset的提交按钮不起作用
    6. 从django视图中的按钮获取click事件
    7. Android ListView监听上下滑动(判断是否显示返回顶部按钮)
    8. Android SDK:RelativeLayout - 按钮不会水平居中,即使Layout_Cent
    9. android声音播放之SoundPool的应用,让你的按钮从此有声有色

    随机推荐

    1. How can clear screen in php cli (like
    2. PHP / MySQL - 有时会将空白条目添加到
    3. Laravel手把手系列教程之一环安装和环境
    4. php和django位于同一个lighttpd服务器上
    5. 如何加载json文件?
    6. 将node.js服务器更改为Apache服务器
    7. 纯真ip数据库查询的php实现(补充分组查询)
    8. thinkPHP5下扩展encryptedData解密算法文
    9. 用户GROUP BY ERROR之间的SQL查询private
    10. JSON解析错误:无法识别的标记'<'处于角度