对于div元素的Onresize?

时间:2013-10-12 01:35:36

标签: javascript html html5

Visual Studio突出显示了我的onresize标记的div属性,并说它不是HTML5的有效属性。这是真的?我应该用什么呢?这种情况似乎有点愚蠢。

5 个答案:

答案 0 :(得分:9)

将以下CSS和JavaScript添加到您的网页,并使用addResizeListenerremoveResizeListener方法来监听元素大小更改(博客文章了解更多详情:http://www.backalleycoder.com/2013/03/18/cross-browser-event-based-element-resize-detection/):

调整传感器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%;
}

调整事件方法的大小

以下是启用调整大小事件监听所需的JavaScript。前两个函数是主addResizeListener和removeResizeListener方法中使用的先决条件。

(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__);
        }
    }
}

})();

<强>演示-licious!

这是该方法的伪代码用法。

var myElement = document.getElementById('my_element'),
    myResizeFn = function(){
        /* do something on resize */
    };
addResizeListener(myElement, myResizeFn);
removeResizeListener(myElement, myResizeFn);

答案 1 :(得分:8)

Microsoft的Internet Explorer支持所有HTML元素上的onresize。 在所有其他浏览器中,onresize仅在window对象上可用。 https://developer.mozilla.org/en-US/docs/Web/API/Window.onresize

如果您想在所有浏览器中div进行onresize检查:

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

此库有一个类ResizeSensor,可用于resize检测。

答案 2 :(得分:6)

规范中仅存在Window.onResize。请记住,每个IFrame元素都会创建支持Window的新onResize对象。因此,IMO检测元素大小变化的最可靠方法是将隐藏的iframe附加到元素。

如果您对整洁便携的解决方案感兴趣,请查看this plugin。 它需要1行代码来监听更改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...
}

答案 3 :(得分:4)

我们现在有 ResizeObserver,今天(2021-01-21)browser support 是 89.6%。

还有适用于旧浏览器的 polyfill,例如 juggle/resize-observer

答案 4 :(得分:2)

目前所有主流浏览器都不支持html-element的resize事件,仅适用于window对象。

您可以截取用户交互以构建自己的侦听器,如下所示:

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;
}

如何使用

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;
}