div元素的onresize?

Posted

技术标签:

【中文标题】div元素的onresize?【英文标题】:Onresize for div elements? 【发布时间】:2013-10-20 04:56:51 【问题描述】:

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

【问题讨论】:

那篇文章是关于Window的resize事件,是否适用于div之类的元素?不是规范的一部分并没有告诉我它有多少浏览器支持,或者它是否有更有效的规范解决方案。 @leaf68 首先你用什么来调整 div 的大小?提供相关代码可以让我们更轻松地为您提供帮助 javascript 中,我有 resize 事件调整其他几个元素的大小。我知道每次设置 div 的一侧时我都可以调用我的 resize 函数,但是如果这种方式有效,那会容易得多,因为我不必每次都记住这一点。 你可以编写一个函数来监听改变你的div的宽度或高度的事件。 感谢@Oztaco 无视这种居高临下的评论。因为你发布了这个问题,我的“10 秒谷歌搜索”把我带到了这里,通过讨论和替代方案得到了一个简单的答案。 +1。 【参考方案1】:

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

如果您想在所有浏览器中使用div 调整大小,请检查:

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

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

【讨论】:

我已经更新了我的方法,它现在比以前的版本更简单,更准确。马克,你应该更新元素查询的东西来使用这个最新的代码(backalleycoder 是我的博客) @csuwldcat,是的,它更简单,但初始化速度较慢,所以我没有进一步遵循object 方法。【参考方案2】:

规范中仅存在Window.onResize。请记住,每个IFrame 元素都会创建支持onResize 的新Window 对象。因此,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】:

将以下 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__);
        
    


)();

Demo-licious!

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

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

【讨论】:

似乎对我不起作用:jsfiddle.net/t2Aqa/7 resize 事件应该通过按下切换按钮或调整呈现 HTML 的区域的大小来调用,但它似乎只被调用一次布局完成后。我错过了什么吗? @suamikim 是的,在您的 addResizeListener 处理程序中,您通过覆盖目标 target.html(target.width() + 'x' + target.height()); 的所有内容来吹走该方法注入的传感器元素以侦听调整大小。 @csuwldcat 如果您要从其他资源中复制并粘贴答案,请至少给它一个参考和确认:backalleycoder.com/2013/03/18/… @JamieBarker 你是对的,我为无耻地从一个显然是天才的人那里偷窃而感到难过。我敢打赌,他更关心这里发布的内容以帮助他人,只是忘记了包含指向他的博客的链接。我找他道歉,结果发现他几乎和我一样帅:github.com/csuwildcat。一个家伙,如果你问我的话;) @JamieBarker 将链接添加到我的帖子中。【参考方案4】:

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

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

【讨论】:

【参考方案5】:

目前所有主流浏览器都不支持 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;

【讨论】:

【参考方案6】:

一个纯粹而简单的 JavaScript 实现。

.resizable 
  resize: both;
  overflow: auto;
  width: 200px;
  border: 1px solid black;
  padding: 20px;
  margin-bottom: 120px;
<div class='resizable' onresize="this.innerText = this.w + ',' + this.h" onmousemove="if ((this.w && this.w !== this.offsetWidth) || (this.h && this.h !== this.offsetHeight))  eval(this.getAttribute('onresize'))  this.w = this.offsetWidth; this.h = this.offsetHeight;">
test
</div>

【讨论】:

以上是关于div元素的onresize?的主要内容,如果未能解决你的问题,请参考以下文章

onscroll事件,onresize事件

onresize的定义方式

window.onresize事件

关于window.onresize

监控浏览器可视大小onresize

vue中在mounted中window.onresize不生效