无法从Firefox中的内容可编辑div获取范围

问题描述

在我们的项目中,我们有一个内容可编辑的div,另一个div用作显示某些选项的按钮。用户选择这些选项之一,然后将值插入到内容可编辑div的插入符中。因此,我试图从内容可编辑div中获取选定的范围值,以将值文本插入插入符号。

我使用内容可编辑div上的blur()事件来实现它,以在失去焦点之前获取选择,保存该范围数据并在div click事件上使用它。在Chrome / Edge中可以正常工作,但在Firefox / Safari中则不能。

我不明白的是,当使用输入按钮时,它在所有浏览器中均有效,但是当使用div作为按钮时,则在Firefox / Safari中不起作用。

JSfiddlehttps://jsfiddle.net/v7secq04/4/

代码

HTML

<!-- input button and div used as button -->
<input type="button" id="selection-button" value="Get selection">
<div id="selection-div"  style="border-style: solid; width: 100px;cursor: pointer;">Selection DIV</div>

<!-- editable div -->
<div id="editor" contenteditable="true" style="border-style: solid; height: 150px;">Please select some text.</div>

<!-- inputs to display the range values -->
Range start: <input id="start" type="text"/><br/>
Range end:  <input id="end" type="text"/>

JS

var start = 0,end = 0;

// On clicking on the button or the div,the editor div blur event is triggered.
// We get the range start and end,and store them.
$( "#editor" ).blur(function() {
  var range = window.getSelection().getRangeAt(0);
  var preSelectionRange = range.cloneRange();
  preSelectionRange.selectNodeContents(editor);
  preSelectionRange.setEnd(range.startContainer,range.startOffset);
  start = preSelectionRange.toString().length;
  end = start + range.toString().length;
});

// After the blur event is finished,the click event is triggered.
// Start and end values are displayed in the inputs
$('#selection-button,#selection-div').on('click',function() {
  $('#start').val(start);
  $('#end').val(end);
  start = 0;
  end = 0;
});

要重现它:

  • 内容可编辑div中写一些内容
  • 选择一些文本
  • 单击按钮->所选范围数据正确显示在输入中
  • 再次选择一些文本
  • 单击div按钮->输入中显示0

有人知道为什么吗?有什么办法可以使用div按钮获取正确的范围数据?

谢谢!

解决方法

通过单击和单击鼠标并在按钮和div上拆分事件侦听器,我可以正常工作。

<script type="text/javascript">
var start = 0,end = 0;

$(() => {
    $('#selection-div').on('mousedown',getSelection);
    $('#selection-button').on('click',getSelection);

    function getSelection() {
        var range = window.getSelection().getRangeAt(0);
        var preSelectionRange = range.cloneRange();
        preSelectionRange.selectNodeContents(document.getElementById('editor'));
        preSelectionRange.setEnd(range.startContainer,range.startOffset);
        start = preSelectionRange.toString().length;
        end = start + range.toString().length;

        $('#start').val(start);
        $('#end').val(end);
        // Not needed,as you would override it on every click
        //start = 0;
        //end = 0;
    }
})
</script>