IE TextRange选择方法无法正常工作 [英] IE TextRange select method not working properly

查看:106
本文介绍了IE TextRange选择方法无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于将contentEditable设置为true的IE文档,我遇到了一个不寻常的问题。在位于紧邻块元素之前的文本节点末尾的范围上调用select()会使选择转移到右边的一个字符,并显示在不应该出现的位置。我已向Microsoft提交了针对IE8的错误。如果可以,请为此问题投票,以便修复。

I'm having an unusual problem with an IE document with contentEditable set to true. Calling select() on a range that is positioned at the end of a text node that immediately precedes a block element causes the selection to be shifted to the right one character and appear where it shouldn't. I've submitted a bug to Microsoft against IE8. If you can, please vote for this issue so that it can be fixed.

https://connect.microsoft.com/IE/feedback/ViewFeedback.aspx?FeedbackID=390995

我写了一个测试用例来证明效果:

I've written a test case to demonstrate the effect:

<html>
  <body>
    <iframe id="editable">
      <html>
        <body>
          <div id="test">
            Click to the right of this line -&gt;
            <p id="par">Block Element</p>
          </div>
        </body>
      </html>
    </iframe>
    <input id="mytrigger" type="button" value="Then Click here to Save and Restore" />
    <script type="text/javascript">
        window.onload = function() {
            var iframe = document.getElementById('editable');
            var doc = iframe.contentDocument || iframe.contentWindow.document;

            // An IFRAME without a source points to a blank document.  Here we'll
            // copy the content we stored in between the IFRAME tags into that
            // document.  It's a hack to allow us to use only one HTML file for this
            // test.
            doc.body.innerHTML = iframe.textContent || iframe.innerHTML;

            // Marke the IFRAME as an editable document
            if (doc.body.contentEditable) {
                doc.body.contentEditable = true;
            } else {
                var mydoc = doc;
                doc.designMode = 'On';
            }

            // A function to demonstrate the bug.
            var myhandler = function() {
                // Step 1 Get the current selection
                var selection = doc.selection || iframe.contentWindow.getSelection();
                var range = selection.createRange ? selection.createRange() : selection.getRangeAt(0);

                // Step 2 Restore the selection
                if (range.select) {
                    range.select();
                } else {
                    selection.removeAllRanges();
                    selection.addRange(range);
                    doc.body.focus();
                }
            }

            // Set up the button to perform the test code.
            var button = document.getElementById('mytrigger');
            if (button.addEventListener) {
                button.addEventListener('click', myhandler, false);
            } else {
                button.attachEvent('onclick', myhandler);
            }
          }
    </script>
  </body>
</html>

问题暴露在myhandler函数中。这就是我正在做的事情,在保存和恢复选择之间没有第3步,但光标移动了。除非选择为空(即我有一个闪烁的光标,但没有文本),似乎不会发生这种情况,并且只有当光标位于紧邻块节点之前的文本节点的末尾时,它才会发生。

The problem is exposed in the myhandler function. This is all that I'm doing, there is no Step 3 in between the saving and restoring the selection, and yet the cursor moves. It doesn't seem to happen unless the selection is empty (ie. I have a blinking cursor, but no text), and it only seems to happen whenever the cursor is at the end of a text node that immediately precedes a block node.

似乎范围仍然在正确的位置(如果我在返回div的范围内调用parentElement),但是如果我从当前获得一个新的范围选择,新范围在段落标记内,即它的parentElement。

It seems that the range is still in the correct position (if I call parentElement on the range it returns the div), but if I get a new range from the current selection, the new range is inside the paragraph tag, and that is its parentElement.

如何解决此问题并始终如一地保存和恢复互联网中的选择资源管理器?

推荐答案

我已经找到了一些处理IE范围的方法。

I've figured out a few methods for dealing with IE ranges like this.

如果您只想保存光标所在的位置,然后将其恢复,则可以使用pasteHTML方法在光标的当前位置插入空跨度,并且然后使用moveToElementText方法再次将其放回该位置:

If all you want to do is save where the cursor is, and then restore it, you can use the pasteHTML method to insert an empty span at the current position of the cursor, and then use the moveToElementText method to put it back at that position again:

// Save position of cursor
range.pasteHTML('<span id="caret"></span>')

...

// Create new cursor and put it in the old position
var caretSpan = iframe.contentWindow.document.getElementById("caret");
var selection = iframe.contentWindow.document.selection;
newRange = selection.createRange();
newRange.moveToElementText(caretSpan);

或者,您可以计算当前光标位置前面的字符数并保存该数字:

Alternatively, you can count how many characters precede the current cursor position and save that number:

var selection = iframe.contentWindow.document.selection;
var range = selection.createRange().duplicate();
range.moveStart('sentence', -1000000);
var cursorPosition = range.text.length;

要恢复光标,请将其设置为开头,然后将其移动该字符数:

To restore the cursor, you set it to the beginning and then move it that number of characters:

var newRange = selection.createRange();
newRange.move('sentence', -1000000);
newRange.move('character', cursorPosition);

希望这会有所帮助。

这篇关于IE TextRange选择方法无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆