16

经过2天的研究,我在问这个问题。我已经阅读了 stackoverflow 和 google 中的所有相关问题和答案(包括这个问题,它非常相似但没有答案),但仍然找不到解决方案。希望这里有人能够提供帮助。

我有一个 UIWebView ,其中加载了一些文本。我想以编程方式选择部分文本,就好像用户长按它一样。

我尝试执行此 javascript 代码作为对点击的响应:

function selectEl(x,y)
{
    document.designMode = "on";
    var el = document.elementFromPoint(x, y);
    var range = document.createRange();
    range.selectNodeContents(el);
    var sel = document.getSelection();
    sel.removeAllRanges();
    sel.addRange(range);
    document.designMode = "off";
}

我已经尝试过在函数结束时将 designMode 更改为“off”,也可以不更改。我知道这段代码“选择”了正确的元素,因为如果我执行这个命令

document.execCommand("BackColor", false, "#ffffcc");

它实际上突出显示了我单击的元素,但不会导致选择文本。关于如何实现这一目标的任何想法?

4

3 回答 3

2

这似乎是 Mobile Safari 中的一个错误。当我切换contentEditable到 truetouchstart并将其设置为 false 时,touchend它​​可以工作。如果我删除这些行并刷新它仍然有效。如果我关闭 Mobile Safari,清除缓存,然后重新打开删除行的文档,它会再次停止工作。

我已经用工作版本更新了下面的代码(尽管为了简单起见,我删除了长按)。

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">

(function() {
    var node,
        range,
        offset,
        clientX,
        clientY;

    document.addEventListener("DOMContentLoaded", function() {
        document.body.addEventListener("touchstart", function(event) {
            var selection = window.getSelection();
            selection.removeAllRanges();

            clientX = event.touches[0].clientX;
            clientY = event.touches[0].clientY;

            range = document.caretRangeFromPoint(clientX, clientY);
            node = range.startContainer;
            offset = range.startOffset;

            document.body.contentEditable = "true";
            event.preventDefault();
        });
        document.body.addEventListener("touchmove", function(event) {
            var selection = window.getSelection(),
                range = document.caretRangeFromPoint(event.touches[0].clientX, event.touches[0].clientY),
                newRange = document.createRange();

            if(clientY < event.touches[0].clientY) {
                newRange.setStart(node, offset);
                newRange.setEnd(range.startContainer, range.startOffset);
            }
            else {
                newRange.setStart(range.startContainer, range.startOffset);
                newRange.setEnd(node, offset);
            }

            selection.removeAllRanges();
            selection.addRange(newRange);

            event.preventDefault();
        });
        document.body.addEventListener("touchend", function(event) {
            document.body.contentEditable = "false";
            event.preventDefault();
        });
    });
})();
</script>
<body>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam tempus volutpat mauris sed porta. Phasellus euismod malesuada eleifend. Donec mattis, orci quis scelerisque mattis, turpis sem pulvinar nisi, et sagittis nunc nisi sed nulla. Pellentesque pharetra consequat neque, ultrices mattis mauris auctor id. Aenean tincidunt turpis non odio gravida semper. Praesent feugiat, lorem at lacinia tristique, orci eros tincidunt leo, at adipiscing sapien felis at tellus. Phasellus ac est nec nibh posuere euismod vel vitae neque. Vestibulum mollis adipiscing urna ut tristique. Vivamus purus tortor, venenatis id aliquam nec, elementum et lacus. Praesent elementum purus eget sapien ornare laoreet. Vestibulum ac odio enim.
</body>
</head>
</html>
于 2012-11-28T21:58:21.260 回答
0

只是一个想法:确保你没有在你的 css 中使用这样的东西:

* {
  -webkit-touch-callout: none;
   -webkit-user-select: none;
   user-select: none;
}

这可以防止任何文本选择。

于 2012-11-30T10:00:21.303 回答
-3

我遇到了这个:

hitElem.style.backgroundColor = "highlight";
hitElem.style.color = "highlighttext";

或者, 这个网站已经写了一些可怕的脚本,但它可以帮助你:) 它适用于范围。

于 2012-11-30T14:22:53.853 回答