Определить в Jquery (Обработчик событии) когда создается scrolling прокрутка

256
22 июля 2017, 07:15

Есть обработчик onscroll. Событие onscroll происходит, когда элемент прокручивается. Но мне нужно определить возникновение самого ползунка, а не процесс прокручивание. То есть нужно обработчик событии, который сработает, как только на документе появиться scroll-bar.

Answer 1

На самом деле, проверить, есть ли полоса прокрутки или нет, легко. Сложно выполнить код сразу, как только она появится.

Для запуска функции, когда появляется полоса, я использовал JQuery плагин отслежки изменения размера блока и повесил его на сенсор внутри нужного элемента.

(function () { 
    if (typeof window === "undefined") { 
        return null; 
    } 
    var requestAnimationFrame = window.requestAnimationFrame || 
        window.mozRequestAnimationFrame || 
        window.webkitRequestAnimationFrame || 
        function (fn) { 
            return window.setTimeout(fn, 20); 
        }; 
 
    $.fn.onResize = function (callback) { 
        var $target = $(this); 
 
        function EventQueue() { 
            var q = []; 
            this.add = function (ev) { 
                q.push(ev); 
            }; 
 
            var i, j; 
            this.call = function () { 
                for (i = 0, j = q.length; i < j; i++) { 
                    q[i].call(); 
                } 
            }; 
 
            this.remove = function (ev) { 
                var newQueue = []; 
                for (i = 0, j = q.length; i < j; i++) { 
                    if (q[i] !== ev) newQueue.push(q[i]); 
                } 
                q = newQueue; 
            } 
 
            this.length = function () { 
                return q.length; 
            } 
        } 
 
        function attachResizeEvent($target, resized) { 
            if (!$target) return; 
            if ($target.resizedAttached) { 
                $target.resizedAttached.add(resized); 
                return; 
            } 
 
            $target.resizedAttached = new EventQueue(); 
            $target.resizedAttached.add(resized); 
 
            $target.resizeElement = document.createElement('div'); 
            $target.resizeElement.className = 'resize-sensor'; 
            var style = 'position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: hidden; z-index: -1; visibility: hidden;'; 
            var styleChild = 'position: absolute; left: 0; top: 0; transition: 0s;'; 
 
            $target.resizeElement.style.cssText = style; 
            $target.resizeElement.innerHTML = '<div class="resize-sensor-expand" style="' + style + '"><div style="' + styleChild + '"></div></div><div class="resize-sensor-shrink" style="' + style + '"><div style="' + styleChild + ' width: 200%; height: 200%"></div></div>'; 
            $target.appendChild($target.resizeElement); 
 
            if ($target.resizeElement.offsetParent !== $target) { 
                $target.style.position = 'relative'; 
            } 
 
            var el__expand = $target.resizeElement.childNodes[0]; 
            var el__expandChild = el__expand.childNodes[0]; 
            var el__shrink = $target.resizeElement.childNodes[1]; 
            var dirty, rafId, int__newWidth, int__newHeight; 
            var int__lastWidth = $target.offsetWidth; 
            var int__lastHeight = $target.offsetHeight; 
 
            var reset = function () { 
                el__expandChild.style.width = '100000px'; 
                el__expandChild.style.height = '100000px'; 
 
                el__expand.scrollLeft = 100000; 
                el__expand.scrollTop = 100000; 
 
                el__shrink.scrollLeft = 100000; 
                el__shrink.scrollTop = 100000; 
            }; 
 
            reset(); 
 
            var onResized = function () { 
                rafId = 0; 
 
                if (!dirty) return; 
 
                int__lastWidth = int__newWidth; 
                int__lastHeight = int__newHeight; 
 
                if ($target.resizedAttached) { 
                    $target.resizedAttached.call(); 
                } 
            }; 
 
            var onScroll = function () { 
                int__newWidth = $target.offsetWidth; 
                int__newHeight = $target.offsetHeight; 
                dirty = int__newWidth != int__lastWidth || int__newHeight != int__lastHeight; 
 
                if (dirty && !rafId) { 
                    rafId = requestAnimationFrame(onResized); 
                } 
 
                reset(); 
            }; 
 
            var addEvent = function (el, name, cb) { 
                if (el.attachEvent) { 
                    el.attachEvent('on' + name, cb); 
                } else { 
                    el.addEventListener(name, cb); 
                } 
            }; 
 
            addEvent(el__expand, 'scroll', onScroll); 
            addEvent(el__shrink, 'scroll', onScroll); 
        } 
 
        $target.each(function () { 
            attachResizeEvent(this, callback); 
        }); 
 
        this.detach = function (ev) { 
            $.fn.onResize.detach($target, ev); 
        }; 
    }; 
 
    $.fn.onResize.detach = function ($target, ev) { 
        $target.each(function () { 
            if (!this) return 
            if (this.resizedAttached && typeof ev == "function") { 
                this.resizedAttached.remove(ev); 
                if (this.resizedAttached.length()) return; 
            } 
            if (this.resizeElement) { 
                if (this.contains(this.resizeElement)) { 
                    this.removeChild(this.resizeElement); 
                } 
                delete this.resizeElement; 
                delete this.resizedAttached; 
            } 
        }); 
    }; 
})(); 
 
var $wrap = $('.wrap'), 
    $wrap_sensor = $('.wrap_sensor'); 
 
$wrap_sensor.onResize(function() { 
  var $wrap = $('.wrap'); 
 
  if($wrap.get(0).clientHeight !== $wrap.get(0).scrollHeight) console.log('Появилась полоса'); 
});
.wrap { 
  position: relative; 
  width: 200px; 
  height: 200px; 
  overflow: auto; 
  border: 2px solid red; 
} 
.wrap_body { 
  display: none; 
  width: 100px; 
  height: 800px; 
} 
input:checked ~ .wrap > .wrap_body { 
  display: block; 
} 
 
.wrap_sensor { 
  position: absolute; 
  left: 0; 
  top: 0; 
  width: 100%; 
  height: 100%; 
  visibility: hidden; 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> 
 
Добавить полосу: <input type="checkbox"> 
 
<div class="wrap"> 
  <div class="wrap_sensor"></div> 
  <div class="wrap_body"></div> 
</div>

READ ALSO
Как запустить таймер, а потом отключить его?

Как запустить таймер, а потом отключить его?

Есть событие <button onclick='start()'>Старт</button> и <button onclick='stop()'>Стоп</button>

273
tree for PHP/JS

tree for PHP/JS

нужно реализовать дерево, с возможность (добавление/изменение/перемещение/удаление элемента), можно использовать jquery, плагины к нему и/или...

205
OpenServer блокирует отображение CSS

OpenServer блокирует отображение CSS

Если открываю сайт через OpenServer, то на сайте отображается только html код, а css невиденЕсли же открываю сайт без запуска сервера, то всё отлично

311