如何禁用选择div中的一些文本?

时间:2017-12-15 16:20:57

标签: javascript html css selection

假设我有一个带标记的文字,例如:

enter image description here

我想禁用选择选项的开头或结尾不在标记中。因此,所有这些选择都应该是可能的:

enter image description here
enter image description here
enter image description here

另一方面,应禁用这些选择:

enter image description here
enter image description here

到目前为止,我只尝试使用一些简单的CSS,

mark {
   -khtml-user-select: all;
   -webkit-user-select: all;
   -o-user-select: all;
   user-select: all;
}
This is <mark>marked text</mark>. I want to disable selecting only part of <mark>marked text</mark>.

jsfiddle link

有没有办法做到这一点?任何答案都将不胜感激!

我实现了我想做的事情,所以我在这里分享。

function checkSelection () {
  var sel = window.getSelection();
  var marks = document.getElementsByTagName('mark');
  for(var i = 1; i < sel.rangeCount; i++) {
    sel.removeRange(sel.getRangeAt(i));
  }
  var range = sel.getRangeAt(0);
  var startnode = range.startContainer;
  var endnode = range.endContainer;
  for (var i = 0; i < marks.length; i++) {
  	if (marks[i].contains(startnode)) {
      range.setStartBefore(startnode);
    }
  	if (marks[i].contains(endnode)) {
      range.setEndAfter(endnode);
    }
  }
}

document.addEventListener('mouseup', checkSelection)
document.addEventListener('touchend', checkSelection)
This is <mark>marked text</mark>. I want to disable selecting only part of <mark>marked text</mark>.

jsfiddle link

2 个答案:

答案 0 :(得分:1)

我认为单独使用CSS是不可能的,你很可能需要JavaScript来检测用户开始选择哪些元素。

我做的是使用了Selection API中的containsNode方法(工作草案,可能不适用于所有浏览器,可能已弃用)以检测是否已选中范围要么包含整个标记元素,要么根本不包含。如果选择仅包含标记元素的一部分,则它将使用removeAllRanges方法清除选择。

function checkSelection () {
  var sel = window.getSelection()
  var marks = document.getElementsByTagName('mark')
  for (var i = 0; i < marks.length; i++) {
    if (sel.containsNode(marks[i], false) !== sel.containsNode(marks[i], true))
      sel.removeAllRanges()  // clear selection
  }
}

document.addEventListener('mouseup', checkSelection)
document.addEventListener('touchend', checkSelection)
mark {
  background: yellow;
}
This is <mark>marked text</mark>. I want to disable selecting only part of <mark>marked text</mark>.

请注意,您需要捕获所需的所有选择方法,无论是通过鼠标事件和触摸事件(我包括的所有),键盘插入符号选择还是程序选择。

这可以根据您的喜好进行扩展和调整,但这是我从您的规范中复制您想要的行为的最好方法。如果其中一个选择的边界在标记区域的边缘开始或结束,则上面的代码段不能正常工作,但是代码片段应该展示应该工作的基本概念,只需对边缘稍微微调一下例。

答案 1 :(得分:0)

用户选择的CSS属性尚未正式发布,只有最新的浏览器支持。

无论如何,您可以使用user-select: none;并附上span标记内无法选择的所有文字

https://developer.mozilla.org/en-US/docs/Web/CSS/user-select

但你可以尝试这样的事情

.unselectable {
  -moz-user-select: none;
  -webkit-user-select: none;
  -ms-user-select: none;
  user-select: none;
}
<p>This text can be selected, But <span class="unselectable">this</span> can only be <span class="unselectable">partially se</span>lected</p>

https://developer.mozilla.org/en-US/docs/Web/CSS/user-select