Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

148
Views
Preserve text selection on click in Safari

Selecting some text on a page and then clicking a button preserves text selection in pretty much any browser other than Safari (at least its mobile version).

Is there any way to make Safari behave just like everything else?

Simple jsFiddle demonstrating the problem, where selecting some text and clicking the button doesn't report selected text in Safari (selection is removed and window.getSelection() returns nothing): https://jsfiddle.net/u5b3awhd/

    <span>here's some text to select</span>
    <button onclick="showSelection()">click me</button>
    <div id="message"></div>
    function showSelection() {
      document.getElementById("message").innerText = "selected " + window.getSelection();
    }

I've tried adding user-select: none and similar styles to the button, but it didn't help.

I also found some recommendations to get selected text on some other input events (mouse events etc.), but there are 2 major reasons I'm looking for a better solution:

  1. It looks a little hacky, especially since this needs to run on mobile, where there is no mouse, so those events are emulated and might be tricky to get right without other undesirable side effects. Although the selectionchange event might partially solve this problem, there is still another problem #2...
  2. Text selection in browser UI actually gets lost and the user needs to select it again later, which is not the best experience, especially considering that it works great in other browsers.

So how does everyone solve this in 2022?

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

I've got a solution for you, maybe, it feels gross because we're certainly compensating for the weirdness of iOS Safari. It really depends on what you're doing with the selection. Specific to your test code above:

var documentFragment;
var ancestorNode;

// listen to touchy on the element you want to select from
document.querySelector("span").addEventListener("touchend", (e) => {
   let selection = document.getSelection();
   if (!selection || selection.rangeCount === 0 || selection.getRangeAt(0).length === 0)
      return;
   let range = selection.getRangeAt(0);
   ancestorNode = range.commonAncestorContainer; // if you need it
   documentFragment = range.CloneContents(); // because you'll never get the selection
});

document.querySelector("button").addEventListener("click", (e) => {
   if (!documentFragment) {
      // nothing there from a 'touchend' event, check now from other means.
      // do all the things above, but you know, refactor it so it's DRY.
   }
   if (documentFragment) {
      // do all the things with the fragment, like...
      let div = document.createElement("div");
      div.appendChild(documentFragment);
   }
});

Even though the selection is cleared, what it was is now contained in that object. It may be more elegant, and work, if you listen to touchend and mouseup but I haven't had a chance to validate that. Then you wouldn't have to have your alternate flow as I did above. The other thing I put in there optionally is to get the commonAncestorContainer from the range, in case you need to look at that or its parents to see if it's contained in a certain element id or something. I needed it to validate that the selection was from the markup the user was allowed to markup.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!