繁体   English   中英

javascript 范围环绕内容()捕获 InvalidStateError

[英]javascript range surroundContents() catch InvalidStateError

我有一个带有溢出的 div:hidden 包含混合内容 html/文本。 我对这个 div 容器应用了 mousedown 和 mouseup 事件。 如果用户在 mousedown 上突出显示内容,则在 mouse up 事件上捕获选择。

一切正常,(直到/或如果)用户执行以下操作:

用户在 div 容器内按下 mousedown,突出显示特定内容,然后在按下鼠标按钮的同时将指针移到容器外,然后释放鼠标按钮,在 div 容器外调用 mouseup 事件。

我收到此错误:InvalidStateError:尝试使用不可用或不再可用的 object。

我想要实现的是:如果在 div 容器外释放鼠标按钮,我只想保留容器内仍然突出显示的内容。 如果这是不可能的,请删除所有范围/选择/亮点。

我已经阅读了关于.getSelection() 和无效 state 错误的所有文档,并在谷歌上搜索一切试图找到我的结果的方法。

我读过的所有内容都无法捕获 InvalidStateError 或如何处理选择以将内容保留在 div 容器中。

这是我的代码示例:

<style>container{width:120px;height:120px;overflow:hidden;}</style>



<div class="container">testNode text testNode text testNode text testNode text testNode text testNode text testNode text testNode texttestNode text testNode texttestNode texttestNode texttestNode texttestNode texttestNode texttestNode texttestNode texttestNode texttestNode texttestNode texttestNode texttestNode texttestNode texttestNode texttestNode texttestNode text</div>



<script>$('.container').on('mouseup', function(){    
            var sel = getSelection();
            var range = sel.getRangeAt(0).cloneRange();
            var end = sel.toString().length;
            var newNode = document.createElement('tmp');
            /*on this following line i get invalidstate error
            if mouse released outside the container div*/
            range.surroundContents(newNode);
            sel.removeAllRanges();
            sel.addRange(range);
})
</script>
container = $('.container');
containerString = $('.container').html().toString();
selection = range.cloneContents();
selectionString = selection converted to String();
containerSelectionString = selection append to div get      
$('.container').html().toString();

如果滚动超出范围,我制定了一个解决方案并摆脱了 range.surroundContents(newNode) 。 此解决方案获取用户 selectionString,然后将 selectionString 与 containerString 进行比较。 如果 containerString 具有 selectionString 的索引,则像上面的第一个代码一样正常进行,否则如果 selectionString 的索引为 -1(不存在),那么我们知道鼠标超出范围,因此我们将选择 append 带到新创建的 div元素,然后我们得到我们的 containerSelectionString。 现在我们知道用户从容器中选择了什么。

现在!!

我们获取我们的 containerSelectionString 并检查它是否唯一并且存在于容器中,如果是,我们可以包装范围。 我们测试容器字符串是否只出现一次,如下所示:

if containerString.indexOf(containerSelectionString) == containerString.lastIndexOf(containerSelectionString && containerString.indexOf(containerSelectionString) != -1)

现在我们知道字符串是否唯一且存在。

现在很简单,我们使用我们的 containerString 并像这样进行修改:

containerString  = containerString.substring(0, containerString.indexOf(containerSelectionString)) + '<tmp>' + containerSelectionString + '</tmp>' + (containerString.indexOf(containerSelectionString) + containerSelectionString.length))

现在我们只需使用新的 containerString 填充容器,然后在我的情况下,临时设置为具有独特的背景颜色。就是这样。

如果字符串不是唯一的,我们就让选择消失。 可能有一种方法可以从选择或范围中获取 startindex,然后在开始索引处拆分 divtext,如果结束索引较高,则使用字符串的第二部分并匹配,或者如果结束索引较低,则使用第一个字符串的一部分,但是对于我的需要,这个解决方案很好,如果它不是唯一的,用户只有 10% 的机会需要重新 select 文本。

希望这可以帮到你。

顺便提一句。 这里的 get:getSelection() 实际上是一个小 function ,如果你在不同的浏览器上使用它,这里是 getSelection() 函数:

$.fn.getSelection = function() {
    if (window.getSelection) {
        return window.getSelection();
    } else if (document.getSelection) {
        return document.getSelection();
    } else if (document.selection) {
        return document.selection.createRange().htmlText;
    }
};

代码如下:

$('.container').on('mouseup', function(){  
   var divObject = $(this);   
        var sel = getSelection();
        var range = sel.getRangeAt(0).cloneRange();
        var end = sel.toString().length;

                divText = divObject.html().toString();
                var selHTML = range.cloneContents();
                var div = document.createElement("div");
                div.appendChild(selHTML);
                var testS = div.innerHTML.toString();
                var findx = divText.indexOf(testS);
                if (findx > -1) {
                    var newNode = document.createElement('tmp');
                    range.surroundContents(newNode);
                    sel.removeAllRanges();
                    sel.addRange(range);
                } else {
             var testS = div.querySelector('.container').innerHTML.toString();
             var findx = divText.indexOf(testS);
             if (findx == divText.lastIndexOf(testS) && findx != -1) {
             var sindx = findx + testS.length;
             divText = divText.substring(0, findx) + '<tmp>' + testS + '</tmp>' + divText.substring(sindx);
                        divObject.html(divText);
                    } 
}
                   div.remove();
})

暂无
暂无

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

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