How to Create Actions for Selected Text With the Selection API
Click, drag, release: you’ve just selected some text on a webpage — probably to copy and paste it somewhere or to share it. Wouldn’t it be cool if selecting that text revealed some options that make those tasks easier? That’s what a selection menu does.
You may already be familiar with selection menus if you’ve ever used an online editor. When you select text, options to format the selection might float above it. In fact, I’m writing this draft in an editor that does exactly this.
Let’s see how we can create a selection menu like this using JavaScript’s Selection API. The API gives us access to the space and content of the selected area on a webpage. This way we can place the selection menu exactly above the selected text and get access to the selected text itself.
Here’s an HTML snippet with some sample text:
<article> <h1 id="Select-over-the-text-below">Select over the text below</h1> <p>Cascading Style Sheets (CSS) is a style sheet language used for describing the presentation of a document written in a markup language such as HTML. CSS is a cornerstone technology of the World Wide Web, alongside HTML and JavaScript. CSS is designed to enable the separation of presentation and content, including layout, colors, and fonts. This separation can improve content accessibility, provide more flexibility and control in the specification of presentation characteristics. </p> </article> <template><span></span></template>
There’s a tag at the end there. The inside it is our selection menu control. Anything inside a tag is not rendered on the page until it’s later added to the page with JavaScript. We’ll add the selection menu control to the page when user selects text. And when the user selects that text, our selection menu will prompt the user to tweet it.
Here’s the CSS to style it:
#control { background-image: url("data:image/svg xml,<svg xmlns="http://www.w3.org/2000/svg" width="40px" height="40px"><foreignobject width="40px" height="40px"><div xmlns="http://www.w3.org/1999/xhtml" style="width:40px;height:40px;line-height:40px;text-align:center;color:transparent;text-shadow: 0 0 yellow, 2px 4px black, -1px -1px black;font-size:35px;">?</div></foreignobject></svg>"); cursor: pointer; position: absolute; width: 40px; height: 40px; } #control::before{ background-color: black; color: white; content: " tweet this! "; display: block; font-weight: bold; margin-left: 37px; margin-top: 6px; padding: 2px; width: max-content; height: 20px; }
Check out this article to learn how I used an emoji (?) for the background image.
So far, the sample text is ready, and the selection menu control has been styled. Let’s move on to the JavaScript. When a selection is made, we’ll get the size and position of the selected area on the page. We then use those measurements to assign the position of the selection menu control at the top-middle of the selected area.
var control = document.importNode(document.querySelector('template').content, true).childNodes[0]; document.querySelector('p').onpointerup = () => { let selection = document.getSelection(), text = selection.toString(); if (text !== "") { let rect = selection.getRangeAt(0).getBoundingClientRect(); control.style.top = `calc(${rect.top}px - 48px)`; control.style.left = `calc(${rect.left}px calc(${rect.width}px / 2) - 40px)`; control['text']= text; document.body.appendChild(control); } }
In this code, we first get a copy of the selection menu control inside , then assign it to the control variable.
Next, we write the handler function for the onpointerup event of the element carrying the sample text. Inside the function, we get the selection and the selected string using document.getSelection(). If the selected string is not empty, then we get the selected area’s size and position, via getBoundingClientRect(), and place it in the rect variable.
Using rect, we calculate and assign the top and left positions of the control. This way, the selection menu control is placed a little above the selected area and centered horizontally. We’re also assigning the selected string to a user-defined property of control. This will later be used to share the text.
And, finally, we add control to the webpage using appendChild(). At this point, if we select some of the sample text on the page, the selection menu control will appear on the screen.
Now we get to code what happens when the selection menu control is clicked. In other words, we’re going to make it so that the text is tweeted when the prompt is clicked.
control.addEventListener('pointerdown', oncontroldown, true); function oncontroldown(event) { window.open(`https://twitter.com/intent/tweet?text=${this.text}`) this.remove(); document.getSelection().removeAllRanges(); event.stopPropagation(); }
When the control is clicked, a tab opens with Twitter’s “New Tweet” page, complete with the selected text ready to go.
After the tweet prompt, the selection menu control is no longer needed and is removed, along with any selection made on the page. The way that the pointerdown event cascades further down the DOM tree is also stopped at this point.
We also need an event handler for the onpointerdown event of the page:
document.onpointerdown = ()=> { let control = document.querySelector('#control'); if (control !== null) {control.remove();document.getSelection().removeAllRanges();} }
Now the control and any selection made on the page are removed when clicking anywhere on the page but the selection menu control.
Demo
Here’s a more prettified version that Chris put together:
And here’s an example showing more than one control in the selection menu:
About that
It’s not totally necessary that we use it. Instead, you can also try simply hiding and showing the control some other way, like the hidden HTML attribute or the CSS display. You can also build a selection menu control in the JavaScript itself. The coding choices will depend on how efficiently you execute them, and their fallbacks, if needed, as well as how they fit in with your application.
Some UI/UX advice
While this is a nice effect, there are a couple of things to consider when using it to ensure a good user experience. For example, avoid injecting your own text into the text selection — you know, like appending a link back to your site in the auto-generated tweet. It’s intrusive and annoying. If there’s any reason to do that, like adding the source citation, let the user see a preview of the final text before posting it. Otherwise, the user might be confused or surprised by the addition.
One more thing: It’s best if the menu control is out of the way. We don’t want it covering up too much of the surrounding content. That sort of thing adds up to CSS “data loss” and we want to avoid that.
Bottom line: Understand why your users need to select text on your website and add the controls in a way that gets out of the way of what they’re trying to do.
The above is the detailed content of How to Create Actions for Selected Text With the Selection API. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

It's out! Congrats to the Vue team for getting it done, I know it was a massive effort and a long time coming. All new docs, as well.

With the recent climb of Bitcoin’s price over 20k $USD, and to it recently breaking 30k, I thought it’s worth taking a deep dive back into creating Ethereum

I had someone write in with this very legit question. Lea just blogged about how you can get valid CSS properties themselves from the browser. That's like this.

The other day, I spotted this particularly lovely bit from Corey Ginnivan’s website where a collection of cards stack on top of one another as you scroll.

I'd say "website" fits better than "mobile app" but I like this framing from Max Lynch:

There are a number of these desktop apps where the goal is showing your site at different dimensions all at the same time. So you can, for example, be writing

If we need to show documentation to the user directly in the WordPress editor, what is the best way to do it?

Questions about purple slash areas in Flex layouts When using Flex layouts, you may encounter some confusing phenomena, such as in the developer tools (d...
