Apple’s Safari web-browser on OS X exhibits a behaviour that seems to me to be irrational and counter-intuitive. You’ll notice it on web-pages that have scrollable regions on them, such as a HTML <textarea>
, where there is enough content overflow to enable the scroll functions.
Scroll behaviour on such pages depends on the position of the mouse cursor relative to the scrollable region, whether that be the browser window itself, or the scrollable element within it. If the mouse pointer doesn’t pass over a scrollable region when scrolling the window, then the behaviour is as it should be, the window scrolls.
However, if the cursor passes over a scrollable region within the parent window, then the scrolling control passes to the region, rather than the window. The region is then scrolled to the edge of it’s content, in the direction of the scroll, before scrolling control passes back to the parent window. This is all performed in one seamless, uninterrupted flow.
So far, this is all pretty much as it should be, scrolling the child region as it passes under the cursor makes sense, it reveals content that the reader might not have realised was there otherwise. This is especially true since Apple have chosen to hide scroll-bars by default (from OS X “Lion” onwards).
These behaviours irritate me though when I am working within the content editor of my CMS, or other <textarea>
elements, on long bodies of text. What happens is that I’ll scroll through the content I am editing and, as I reach the end of it, the encapsulating window scrolls —
I could mitigate this behaviour with an auto-size on the relevant areas. Then the editable region is always as large as (or larger than) the content it contains, therefore preventing the scrollable state. But that’s not my preferred solution, particularly within my CMS’ editor where, if I were editing a particularly large document, I’d have to scroll up whenever I needed to access the formatting controls.
What I really need is the flexibility to be able to control the scroll behaviour of each scrollable region independently. So… drum roll please… I have a written a handler to do just that.
Introducing scroll Targeting.js
scrollTargeting.js is a ridiculously small (468 bytes minimised, 264 bytes minimised and gzipped) jQuery plug-in for controlling scrolling behaviours in the web-browser (only tested in Safari 6 on OS X 10.8, may work on other platforms).
The plug-in “watches” the mouse cursor position and the DOM’s focused properties and adjusts the scroll behaviour accordingly. It has a small footprint and should not have a negative impact on performance.
Demo
I have put together a demo page, illustrating the options of the scrollTargeting.js plug-in.
Usage
Load jQuery:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js" type="text/javascript"></script>
Load the plug-in:
<script src="/path/to/scrollTargeting.min.js" type="text/javascript"></script>
Bind the behaviours:
<script type="text/javascript">
/* <![CDATA[ */
scrollTargeting('#exampleID', 1);
/* ]]> */
</script>
Details, Details
When binding the behaviours, the two parameters you must provide are the element/object selector(s) and the behaviour index respectively. Hence:
scrollTargeting('#myTextarea', 1);
will add behaviour #1 to the element#myTextarea
;scrollTargeting('pre', 3);
will add behaviour #3 to all<pre>
elements;scrollTargeting('#myContainer textarea', 2);
will add behaviour #2 to all<textarea>
elements that are descendants of the element#myContainer
;scrollTargeting('textarea, blockquote, code, pre', 1);
will add behaviour #1 to all<textarea>
,<blockquote>
,<code>
and<pre>
elements.
The element/object can be any jQuery-style selector. The behaviours are as follows:
- Scrolls the element under the mouse cursor;
- Scrolls the element that has focus;
- A combination of #1 and #2. Scrolls the element under the mouse cursor or that which has focus.
Where Can I Use It?
Anywhere. Aside from working with editable content areas, scrollTargeting.js comes in handy for <pre>
and <code>
regions, HTML <iframe>
containers or for preventing scrolling under modal windows. The plug-in can be useful when used in conjunction with light-box scripts, especially when they are displaying scrollable content of their own.
Downloads
- Minified (468 bytes) - for the plug-n-play user
- Source (723 bytes) - for those who want to tweak things
Code
This project is on GitHub.