JSFiddle - React, Tailwind, and code Playground

by tonyleeper

HTML

<div class="box"></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />

CSS

.box {
    font-family: arial;
    font-size: 16px;
    width: 300px;
    height: 200px;
    background-color: #000077;
    color: #ffffff;
}

JavaScript

var utils = {
    /**
     * triggers a fake DOM event on the specified node
     *
     * @param {HTMLDomNode} node the DOM node on which to trigger the event
     * @param {string} type the type of event to trigger
     */
    triggerEvent: function (node, type) {
        // Legacy approach to support IE11
        var event = document.createEvent('Event');
        event.initEvent(type, true, true);
        node.dispatchEvent(event);
    },

    /**
     * true if the node contains the specified point, otherwise false
     *
     * @param {HTMLDomNode} node the DOM node
     * @param {object} point the point {x, y}
     */
    containsPoint: function (node, point) {
        var rect = node.getBoundingClientRect();
        return point.x >= rect.left && point.x <= rect.right && point.y <= rect.bottom && point.y >= rect.top;
    },

    /**
     * gets the first scrollable ancestor of the node
     * 
     * @param {HTMLDomNode} node the target node 
     */
    getFirstScrollableAncestor: function (node) {
        // find the first scrollable element in the DOM heirarchy
        var scrollableNode = node.parentNode;

        // detatched nodes, return null
        if (scrollableNode === null) {
            return null;
        }

        while (scrollableNode.nodeName !== 'BODY') {
            if (scrollableNode.scrollHeight > scrollableNode.clientHeight) {
                // possibly found one, check computed style has either auto or scroll set for overflowX or overflowY
                var computedStyle = window.getComputedStyle(scrollableNode);
                if (computedStyle.overflowY === 'auto' || computedStyle.overflowY === 'scroll' || computedStyle.overflowX === 'auto' || computedStyle.overflowX === 'scroll') {
                    break;
                }
            }

            scrollableNode = scrollableNode.parentNode;
            if (!scrollableNode) {
                // no parent, shouldn't ever happen unless DOM snippet is detatched from the...