猿问

检测用户启动的元素大小调整(与文档流大小调整不同)

我希望 iframe 能够水平占用所有可用空间,并自动垂直调整自身大小以适应其内容(包括内容更改或窗口大小调整),但也可由用户使用 CSS 属性手动调整大小resize: both。目的是嵌入设计,默认情况下填充可用空间,但也让用户看到它在不同屏幕尺寸下的工作方式。


iframe 是同源的,所以不存在安全问题——父窗口可以对iframe.contentDocument.


自动调整 iframe 大小以适应其内容非常简单:


<iframe srcdoc="<h1>The quick brown fox jumps over the lazy doggerel."

        style="width:calc(100% - 2px);border:1px solid black"

        onload="

    recalculate = () => {

        this.style.height = this.contentDocument.documentElement.offsetHeight + 'px';

    }

    new ResizeObserver(recalculate).observe(this.contentDocument.documentElement);

    recalculate();

"></iframe>

(哇,HTML 语法突出显示真的崩溃了!此外,这里没有正确的“片段”,因为 CSP 似乎中断了contentDocument访问。)


制作用户可调整大小的 iframe 非常简单:


<iframe srcdoc="<h1>The quick brown fox jumps over the lazy doggerel."

        style="resize:both"></iframe>

…但是这些技术并不能很好地结合起来,因为用户调整大小的方式与由于窗口大小变化等原因调整大小的方式相同,所以一旦用户调整大小,自动高度代码就会启动并忽略他们刚刚指定的高度。


因此,如果用户手动调整 iframe 的大小,我希望自动调整大小能够断开 ResizeObserver 的连接。


有什么方法可以区分由于用户操作(通过角夹调整 iframe 大小)导致的调整大小和由于环境变化(iframe 内的内容更改,或没有 iframe 的布局更改,包括视口调整大小)导致的调整大小?


12345678_0001
浏览 70回答 1
1回答

绝地无双

当您手动调整大小时,element.style.{width, height}请进行设置。因此,自动调整大小的一种解决方案是不使用这些属性,而是以其他方式设置宽度和高度,以便您可以区分这些值。对于width,这很简单,因为自动调整大小仅设置height:如果width设置了(或者,如果设置了类似 的值calc(100% - 2px),则设置为其他值),则断开自动调整大小。为了身高?这更难,但我想到了两种技巧:在单独的样式表中设置高度(以便element.style.height根本不设置),并继续更新该样式元素的文本。使用height: var(--height), 并将其设置--height为实际值。除非用户调整大小,否则这种方式element.style.height不会改变。我推荐这种技术,因为它更容易推理,而且我怀疑它可能会更快一点(尽管我根本没有测试过)。<style>iframe {&nbsp; &nbsp; width: calc(100% - 2px);&nbsp; &nbsp; border: 1px solid black;&nbsp; &nbsp; resize: both;}</style><iframe srcdoc="<h1>The quick brown fox jumps over the lazy doggerel."&nbsp; &nbsp; &nbsp; &nbsp; style="height:var(--height)"&nbsp; &nbsp; &nbsp; &nbsp; onload="&nbsp; &nbsp; recalculate = () => {&nbsp; &nbsp; &nbsp; &nbsp; // (var(--height) could just as easily be shifted to the stylesheet,&nbsp; &nbsp; &nbsp; &nbsp; // but I’m demonstrating a point here in how it can be done.)&nbsp; &nbsp; &nbsp; &nbsp; if (this.style.width || this.style.height !== 'var(--height)') {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // User resizing has occurred.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (observer) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; observer.disconnect();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; this.style.setProperty('--height', this.contentDocument.documentElement.offsetHeight + 'px');&nbsp; &nbsp; }&nbsp; &nbsp; var observer = window.ResizeObserver && new ResizeObserver(recalculate);&nbsp; &nbsp; if (observer) {&nbsp; &nbsp; &nbsp; &nbsp; observer.observe(this.contentDocument.documentElement);&nbsp; &nbsp; }&nbsp; &nbsp; recalculate();"></iframe>
随时随地看视频慕课网APP

相关分类

Html5
我要回答