How to disable text selection in a div?

Say I have text with a label, for example:

enter image description here

And I would like to disable the selection so that the beginning or end of the selection is not in the sign. Therefore, all these choices should be possible:

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

On the other hand, these choices should be disabled:

enter image description here
enter image description here

So far I have tried using only simple 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

Is there any way to do this? Any answer would be appreciated!


I have achieved what I wanted, so I will talk about it here.

 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

+5
source share
2 answers

I don’t think that this could be done using CSS, you will most likely need JavaScript to determine which elements the user has started to select.


What I did, I used the containsNode method from the selection API (The working draft may not work with all browsers and may be deprecated) to determine if the selected range contains the entire selected element or is missing at all. If the selection contains only part of the checked item, it will clear the selection using the removeAllRanges method.

 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>. 

Note that you will need to capture all the selection methods that you want, be it mouse events and touch events (all that I have included), keyboard carriage selection, or programmatic selection.


It can be expanded and customized to your liking, but this is my best chance to reproduce the behavior you want from your specifications. The above snippet does not work correctly all the time if one of the selection boundaries starts or ends on the edge of the marked area, but the snippet should demonstrate the basic concept of what should work, just with a little tweaking for the edge of the cases.

+1
source

The custom CSS property is not yet official and is only supported by the latest browsers.

In any case, you can use user-select: none; and enclose all text that cannot be selected inside the span tag

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

But you can try something like this

 .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

0
source

Source: https://habr.com/ru/post/1274103/


All Articles