Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make text "more" selectable

Tags:

I have text in a <p> tag:

<p>Hello world... and goodbye mind A B!</p> 

How do I increase the area in which the text is selectable? I know I can increase the font-size and that would increase the area which is selectable, but is there a better way?

To clarify this question. For example, on mobile screens, I find it difficult to highlight words that are one letter like i, but if the hit detection would be on a wider area, it would be a lot easier to select it.

How to do it? A mind-teasing puzzle.

Bounty info

Looking for a working cross browser solution. Please read the question thoroughly and the comments before posting an answer to avoid confusion. User @mmm posted a question that's quite close, but in his approach, while the <p> tag is has a wider hit detection (perfect!), it auto-selects upon click. I need the user to interact with the <p> tag just like we do with normal text based <p> tags... however with a larger hit detector.

EDIT

Further clarification. As an example, the selection area for a comment to this very question is this large:

enter image description here

You can find this comment below. Hover your cursor over it until the cursor gets changed to cursor:text. That's the default selection area.

But my aim is to extend it to a larger area, like this:

enter image description here

like image 881
Henrik Petterson Avatar asked Feb 20 '16 22:02

Henrik Petterson


People also ask

How do I make a div selectable?

We simply add the onlcick event and add a location to it. Then, additionally and optionally, we add a cursor: pointer to indicate to the user the div is clickable. This will make the whole div clickable.

How do I select text in canvas?

canvas does not have any built-in mechanism for selecting text, so you would have to roll out your own text rendering and selecting code - which can be rather tricky to get right.

What does Unselectable mean in HTML?

Remarks. Note. Setting the UNSELECTABLE attribute to off does not ensure that an element is selectable. One example is an HTML Application (HTA) with the SELECTION attribute set to no. Elements in the body of the HTA cannot be selected, even if the UNSELECTABLE attribute for an element is set to off.


1 Answers

From my test it works on the iphone as well as ff and chrome - if someone can test on android I'll appreciate feedback!

The border obviously can be removed.

This code uses code from this answer (part of the SelectText() function): Selecting text in an element (akin to highlighting with your mouse)

Fiddle

Code:

function extendSelection() {     var extendBy = arguments.length <= 0 || arguments[0] === undefined ? 15 : arguments[0];      var extended = document.getElementsByClassName('extendedSelection');     [].slice.call(extended).forEach(function (v) {         var bounds = v.getBoundingClientRect();         var x = bounds.left;         var r = textWidth(v.innerHTML, ''+ css(v, 'font-weight') +' ' + css(v, 'font-size') + ' ' + css(v, 'font-family') );         var y = bounds.top;         var w = bounds.width;         var h = bounds.height;         var element = document.createElement('div');         element.style.position = 'absolute';         element.style.height = h + extendBy + 'px';         element.style.width = r + extendBy + 'px';         element.style.left = x - extendBy / 2 + 'px';         element.style.top = y - extendBy / 2 + 'px';         element.style.border = '1px dotted black';         document.body.appendChild(element);         element.addEventListener('click', function (e) {             SelectText(v);         });         element.addEventListener('touchend', function (e) {             SelectText(v);         });     }); }  function css(element, property) {     return window.getComputedStyle(element, null).getPropertyValue(property); }  function textWidth(text, font) {     var el = textWidth.canvas || (textWidth.canvas = document.createElement("canvas"));     var draw = el.getContext("2d");     draw.font = font;     var m = draw.measureText(text);     return m.width; };  function SelectText(element) {     var doc = document,         text = element,         range,         selection;     if (doc.body.createTextRange) {         range = document.body.createTextRange();         range.moveToElementText(text);         range.select();     } else if (window.getSelection) {         selection = window.getSelection();         range = document.createRange();         range.selectNodeContents(text);         selection.removeAllRanges();         selection.addRange(range);         selection.setSelectionRange(0, element.value.length)     } }  extendSelection(); 
like image 87
baao Avatar answered Oct 12 '22 17:10

baao