马黑黑 发表于 2025-11-3 12:33

自定义元素缩放

本帖最后由 马黑黑 于 2025-11-3 12:35 编辑 <br /><br /><style>
        .artBox { font-size: 18px; padding: 20px; margin: 20px auto; max-width: 1200px; }
        .artBox > p { margin: 10px 0; line-height: 30px; }
        .artBox mark { padding: 4px 6px; background: lightblue; }
</style>

<div class="artBox">
        <p>对业已存在的元素进行缩放,有多种实现方式。最容易想到的方法是利用CSS的 transform 的 scale() 函数,它接收一个倍数数值作为参数对元素进行原地缩放操作,不触发layout重置即不会重排DOM从而不影响排版,性能和用户体验都很理想,但它的应用需要一个前提:此前未对元素使用过 transform 属性,否则实现过程会复杂化——需要检测用过的一系列transform下的函数然后再设计一个插入 scale 机制。第二个想到的方法是使用 zoom 属性,这是一个非CSS标准下的属性,它来源于IE并被绝大多数现代浏览器一直支持(现在的Firefox也已支持)。使用 zoom 非常简单,像设置CSS属性值那样做即可,其值也是一个倍数数值。zoom 的特点主要有,一是会触发layout重置,引发DOM重排;二是缩放后以实际缩放的尺寸占位;三是它以元素的左上角为缩放中心,在Firefox下缩放中心点的表现会有一些古怪的现象。第三个想到的方法就是改变元素的宽高尺寸,本文要谈的就是这个。</p>
        <p>设想是这样:获取元素的宽高尺寸,然后将宽高在 0.5~2 之间随机缩放。下面是完整的示例,里面创建了一个 ranZoom() 函数,可根据需要对函数进行适应性、扩展性修改:</p>
        <div class="codebox" data-prev="1">
&lt;style&gt;
        .mum { margin: 20px auto; width: 800px; height: 600px; border: 1px solid gray; position: relative; }
        .son { margin-bottom: 40px; width: 200px; height: 200px; background: tan; display: grid; place-items: center; position: relative; }
        .son::before { position: absolute; content: attr(data-tip); width: 200px; left: 0; top: -30px; text-align: center; }
        .zoom { zoom: 1.5; }
        #btnZoom { position: absolute; bottom: 20px; right: 20px; }
&lt;/style&gt;

&lt;div class="mum"&gt;
        &lt;div class="son"&gt;200 * 200&lt;/div&gt;
        &lt;div class="son" data-tip="200 * 200"&gt;&lt;/div&gt;
        &lt;button id="btnZoom" type="button" value=""&gt;Zoom&lt;/button&gt;
&lt;/div&gt;

&lt;script&gt;
        const ranZoom = (element) =&gt; {
                const getSize = (str) =&gt; {
                        const match = str.match(/^([+-]?\d*\.?\d+)(+)$/);
                        if (match) return {size: match, unit: match};
                        return null;
                };
               
                const ranNum = (max,min) =&gt; (Math.random() * (max - min) + min).toFixed(2);
                const zoom = ranNum(0.5, 1.5);

                const style = window.getComputedStyle(element);

                let width = style.getPropertyValue('width'),
                        height = style.getPropertyValue('height');

                element.style.width = Math.ceil(getSize(width).size * zoom) + getSize(width).unit;
                element.style.height = Math.ceil(getSize(height).size * zoom) + getSize(height).unit;
                element.dataset.tip = element.clientWidth + ' * ' + element.clientHeight;
                element.innerText = zoom;
        };
       
        const el = document.querySelectorAll('.son');
        ranZoom(el); // 缩放第二个子元素
       
        btnZoom.onclick = () =&gt; ranZoom(el);
&lt;/script&gt;
        </div>
        <p>ranZoom() 函数从 window.getComputedStyle API 中获得元素的宽高尺寸,是元素最终渲染的尺寸,所以,点击按钮对元素进行缩放时总是以元素的上一次实际尺寸为基准。</p>
        <p>上述自定义的实现元素缩放方法,本质上和 zoom 属性实现的手段差不多。事实上,我们还有一个更为简单易用的做法,那就是利用 CSS 的 scale 属性。自 2022年8月起,所有现代浏览器均已完全支持此属性以及 rotate 和 translate,但 skew 尚未得到支持。这些原本是 transform 属性使用的函数升级为独立属性之后具备了足够的灵活性,例如,针对本文开头提出的 transform 问题不再存在,即当一个元素之前使用了 transform 的相关属性,我们仍然可以直接使用 scale 属性对之进行自由缩放,彼此间不存在任何冲突。 </p>
</div>

<script type="module">
        import linenumber from 'https://638183.freep.cn/638183/web/js/linenumber.js';
        linenumber();
</script>

梦江南 发表于 2025-11-3 14:52

谢谢黑黑老师辛苦!学习了!

樵歌 发表于 2025-11-3 17:27

应该非常 实用,可惜,我不会{:4_198:}

马黑黑 发表于 2025-11-3 17:49

樵歌 发表于 2025-11-3 17:27
应该非常 实用,可惜,我不会

用用就会

马黑黑 发表于 2025-11-3 17:50

梦江南 发表于 2025-11-3 14:52
谢谢黑黑老师辛苦!学习了!

{:4_190:}

杨帆 发表于 2025-11-3 19:10

对元素缩放又多了一条新路径,谢谢马老师经典探索{:4_176:}

马黑黑 发表于 2025-11-3 19:15

杨帆 发表于 2025-11-3 19:10
对元素缩放又多了一条新路径,谢谢马老师经典探索

第四种方法最好,tz.v2 使用第四个实现方案

杨帆 发表于 2025-11-3 22:48

马黑黑 发表于 2025-11-3 19:15
第四种方法最好,tz.v2 使用第四个实现方案

谢谢马老师~还是不太明白,文中提到共3个方法呀,尝试一下{:4_173:}

马黑黑 发表于 2025-11-3 23:47

杨帆 发表于 2025-11-3 22:48
谢谢马老师~还是不太明白,文中提到共3个方法呀,尝试一下

你看文章的最后一段

杨帆 发表于 2025-11-4 16:18

马黑黑 发表于 2025-11-3 23:47
你看文章的最后一段

明白了,谢谢老师~最后一段说的就是第四个方法:新增的CSS 的 scale 属性。

红影 发表于 2025-11-4 21:51

“点击按钮对元素进行缩放时总是以元素的上一次实际尺寸为基准。”
原来如此,还以为是200*200为基准呢,点击后感觉有点问题,其实是以上一次的尺寸为准的。{:4_204:}

红影 发表于 2025-11-4 21:52

谢谢黑黑的讲解,又可以多了解点缩放的方法了{:4_187:}

马黑黑 发表于 2025-11-4 21:54

红影 发表于 2025-11-4 21:52
谢谢黑黑的讲解,又可以多了解点缩放的方法了

方法多多,哪个看顺眼用哪个

马黑黑 发表于 2025-11-4 21:55

红影 发表于 2025-11-4 21:51
“点击按钮对元素进行缩放时总是以元素的上一次实际尺寸为基准。”
原来如此,还以为是200*200为基准呢, ...

这和函数设置有关:说明里提到的。

可以设置为其它的方式,总是在 200*200这个基准缩放
页: [1]
查看完整版本: 自定义元素缩放