I’ve stopped using jQuery years ago now. I learned a lot from jQuery, and from not using it anymore as well. Besides the things you can do with or without jQuery in terms of DOM selection, manipulation, and traversal (or AJAX, the sole reason people keep adding it to their projects nowadays – even though modules like xhr
exist) – there’s unsurprisingly a ton of stuff you can easily do in plain native DOM API, without involving any libraries.
Some of them even enjoy wide browser support! This article explores getBoundingClientRect
, elementFromPoint
, and text selection with selectionStart
and selectionEnd
.
element.getBoundingClientRect
You could use getBoundingClientRect
to get the current size of any DOM element, as well as it’s current position, relative to the viewport.
In the screenshot below I chose a random DOM element on the Elements tab of Dev Tools. Then I popped open the Console and used getBoundingClientRect
on $0
– which is always bound to the last DOM element selected in the Elements tab.
In dragula
, for example, I use getBoundingClientRect
to figure out the absolute positioning of the elements that get dragged around by humans. A better example might be bullseye
used in rome
, horsey
, and woofmark
to place elements right below inputs, textareas, or even the text selection caret (although that one uses getSelection
, polyfilled by seleccion
, to get the selection offset).
The getBoundingClientRect
method also has great browser support: all the way down to IE4. On IE8 and older, the often convenient width
and height
properties aren’t provided, but they could be inferred as right - left
and bottom - top
respectively.
document.elementFromPoint
Another cool piece of the web API that enjoys from broad browser support is elementFromPoint
. It can find the topmost DOM element at any (x, y)
point in the document. If the topmost element is inside an <iframe>
, the <iframe>
itself is returned. This method vastly simplifies the code in dragula
, which needs to figure out what’s behind the element being dragged.
The code below hides the element being dragged using a class that sets display: none !important
, ensuring that the subsequent elementFromPoint
call returns the element that’s below. It surely doesn’t come up quite that often, but it’s still a nifty hack to leverage!
function getElementBehindPoint (point, x, y) {
var old = point.className;
point.className += ' gu-hide';
var el = document.elementFromPoint(x, y);
point.className = old;
return el;
}
Besides drag and drop situations, this method is often used in integration tests using Selenium, when testers want to click a button that can be found in a precise point in the document. There’s probably a few more use cases, but there’s generally way cleaner ways to get references to DOM elements you care about.
selectionStart
and selectionEnd
Whenever we modify user input we need to be careful enough to preserve their text selection. This comes up when we replace tokens such as at mentions (see the <textarea>
example here), insert images or links in rich text-editing scenarios, and similar situations where you want to manipulate user input while it’s being entered.
Both of these properties can be found in input elements. You can read them directly, and you could also change their value, immediately updating the DOM as you’re used for other DOM-changing getters and setters like style properties such as el.style.display
.
If you need support below IE9 you’d have to use something like sell
, which leverages the TextRange API in those scenarios, and otherwise uses selectionStart
and selectionEnd
.
Have any questions or thoughts you’d like me to write about? Send an email to thoughts@ponyfoo.com. Remember to subscribe if you got this far!
Comments