Onresize for div elements?

前端 未结 4 687
花落未央
花落未央 2020-11-30 04:36

Visual Studio highlighted my onresize attribute of my div tag, and says that it isn\'t a valid attribute for HTML5. Is this true? What should I use

相关标签:
4条回答
  • 2020-11-30 05:08

    Microsoft's Internet Explorer supports onresize on all HTML elements. In all other Browsers the onresize is only available at the window object. https://developer.mozilla.org/en-US/docs/Web/API/Window.onresize

    If you wanna have onresize at a div in all browsers check this:

    http://marcj.github.io/css-element-queries/

    This library has a class ResizeSensor which can be used for resize detection.

    0 讨论(0)
  • 2020-11-30 05:14

    Add the following CSS and JavaScript to your page, and use the addResizeListener and removeResizeListener methods to listen for element size changes (blog post for further details: http://www.backalleycoder.com/2013/03/18/cross-browser-event-based-element-resize-detection/):

    Resize Sensor CSS

    .resize-triggers {
        visibility: hidden;
    }
    
    .resize-triggers, .resize-triggers > div, .contract-trigger:before {
      content: " ";
      display: block;
      position: absolute;
      top: 0;
      left: 0;
      height: 100%;
      width: 100%;
      overflow: hidden;
    }
    
    .resize-triggers > div {
      background: #eee;
      overflow: auto;
    }
    
    .contract-trigger:before {
      width: 200%;
      height: 200%;
    }
    

    Resize Event Methods

    The following is the JavaScript you’ll need to enable resize event listening. The first two functions are prerequisites that are used in the main addResizeListener and removeResizeListener methods.

    (function(){
    
    var attachEvent = document.attachEvent;
    
    if (!attachEvent) {
        var requestFrame = (function(){
          var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame ||
                    function(fn){ return window.setTimeout(fn, 20); };
          return function(fn){ return raf(fn); };
        })();
    
        var cancelFrame = (function(){
          var cancel = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame ||
                       window.clearTimeout;
          return function(id){ return cancel(id); };
        })();
    
        function resetTriggers(element){
            var triggers = element.__resizeTriggers__,
                expand = triggers.firstElementChild,
                contract = triggers.lastElementChild,
                expandChild = expand.firstElementChild;
            contract.scrollLeft = contract.scrollWidth;
            contract.scrollTop = contract.scrollHeight;
            expandChild.style.width = expand.offsetWidth + 1 + 'px';
            expandChild.style.height = expand.offsetHeight + 1 + 'px';
            expand.scrollLeft = expand.scrollWidth;
            expand.scrollTop = expand.scrollHeight;
        };
    
        function checkTriggers(element){
          return element.offsetWidth != element.__resizeLast__.width ||
                 element.offsetHeight != element.__resizeLast__.height;
        }
    
        function scrollListener(e){
            var element = this;
            resetTriggers(this);
            if (this.__resizeRAF__) cancelFrame(this.__resizeRAF__);
            this.__resizeRAF__ = requestFrame(function(){
                if (checkTriggers(element)) {
                    element.__resizeLast__.width = element.offsetWidth;
                    element.__resizeLast__.height = element.offsetHeight;
                    element.__resizeListeners__.forEach(function(fn){
                        fn.call(element, e);
                    });
                }
            });
        };
    }
    
    window.addResizeListener = function(element, fn){
        if (attachEvent) element.attachEvent('resize', fn);
        else {
            if (!element.__resizeTriggers__) {
                if (getComputedStyle(element).position == 'static') element.style.position = 'relative';
                element.__resizeLast__ = {};
                element.__resizeListeners__ = [];
                (element.__resizeTriggers__ = document.createElement('div')).className = 'resize-triggers';
                element.__resizeTriggers__.innerHTML = '<div class="expand-trigger"><div></div></div>' +
                                                       '<div class="contract-trigger"></div>';
                element.appendChild(element.__resizeTriggers__);
                resetTriggers(element);
                element.addEventListener('scroll', scrollListener, true);
            }
            element.__resizeListeners__.push(fn);
        }
    };
    
    window.removeResizeListener = function(element, fn){
        if (attachEvent) element.detachEvent('resize', fn);
        else {
            element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1);
            if (!element.__resizeListeners__.length) {
                element.removeEventListener('scroll', scrollListener);
                element.__resizeTriggers__ = !element.removeChild(element.__resizeTriggers__);
            }
        }
    }
    
    })();
    

    Demo-licious!

    Here’s a pseudo code usage of the method.

    var myElement = document.getElementById('my_element'),
        myResizeFn = function(){
            /* do something on resize */
        };
    addResizeListener(myElement, myResizeFn);
    removeResizeListener(myElement, myResizeFn);
    
    0 讨论(0)
  • 2020-11-30 05:18

    Currently all major browser doesn't support a resize event for html-element's, just for the window object.

    What you can to is to intercept the user interaction to build your own listener, like this:

    function detectResize(_element)
    {
        let promise = {};
        let _listener = [];
    
        promise.addResizeListener = function(listener)
        {
            if(typeof(listener) != "function") { return; }
            if(_listener.includes(listener)) { return; };
    
            _listener.push(listener);
        };
    
        promise.removeResizeListener = function(listener)
        {
            let index = _listener.indexOf(listener);
            if(index >= 0) { _listener.splice(index, 1); }
        };
    
        let _size = { width: _element.clientWidth, height: _element.clientHeight };
    
        function checkDimensionChanged()
        {
            let _currentSize = { width: _element.clientWidth, height: _element.clientHeight };
            if(_currentSize.width != _size.width || _currentSize.height != _size.height)
            {
                let previousSize = _size;
                _size = _currentSize;
    
                let diff = { width: _size.width - previousSize.width, height: _size.height - previousSize.height };
    
                fire({ width: _size.width, height: _size.height, previousWidth: previousSize.width, previousHeight: previousSize.height, _element: _element, diff: diff });
            }
    
            _size = _currentSize;
        }
    
        function fire(info)
        {
            if(!_element.parentNode) { return; }
            _listener.forEach(listener => { listener(info); });
        }
    
    
        let mouseDownListener = event =>
        {
    
            let mouseUpListener = event => 
            {
                window.removeEventListener("mouseup", mouseUpListener);
                window.removeEventListener("mousemove", mouseMoveListener);
            };
    
            let mouseMoveListener = event =>
            {
                checkDimensionChanged();
            };
    
            window.addEventListener("mouseup", mouseUpListener);
            window.addEventListener("mousemove", mouseMoveListener);
        };
    
        _element.addEventListener("mousedown", mouseDownListener);
    
        window.addEventListener("resize", event =>
        {
            checkDimensionChanged();
        });
    
        return promise;
    }
    

    How to use it:

    document.addEventListener("DOMContentLoaded", event =>
    {
        let textarea = document.querySelector("textarea");
        let detector = detectResize(textarea);
    
        let listener = info => { console.log("new width: ", info.width, "  new height: ", info.height); };
        detector.addResizeListener(listener);
    });
    

    html:

    <textarea></textarea>
    

    css:

    html, body
    {
        height: 100%;
        box-sizing: border-box;
        overflow: hidden;
        margin: 0px;
    }
    
    textarea
    {
        resize: both;
    
        width: 96px;
        height: 112px;
    
        width: 100%;
        height: 100%;
    
        border: 1px solid black;
    }
    
    0 讨论(0)
  • 2020-11-30 05:20

    Only Window.onResize exists in the specification. Please remember that every IFrame element creates new Window object which supports onResize. Therefore IMO the most reliable method to detect changes to the element's size is to append hidden iframes to the element.

    If you are interested in a neat and portable solution, please check this plugin. It takes 1 line of code to listen the event of changing width or height of your div.

    <!-- (1) include plugin script in a page -->
    <script src="/src/jquery-element-onresize.js"></script>
    
    // (2) use the detectResizing plugin to monitor changes to the element's size:
    $monitoredElement.detectResizing({ onResize: monitoredElement_onResize });
    
    // (3) write a function to react on changes:
    function monitoredElement_onResize() {    
        // logic here...
    }
    
    0 讨论(0)
提交回复
热议问题