You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Sweet Alert嵌入HTML添加图片悬停放大功能

实现Sweet Alert中嵌入式图片的悬停放大功能

问题描述

现有如下Sweet Alert代码,需要为其中的嵌入式<embed>元素添加鼠标悬停放大细节的功能(鼠标移到图片上显示局部放大效果),此前尝试在Swal内部添加相关JS和CSS未成功,求可行实现方案:

Swal.fire({
    type: 'success',
    title: 'Please verify document',
    html: `
        &lt;div style=&quot;display: flex; flex-direction: column; justify-content: center; align-items: center&quot;&gt;
            &lt;embed src=&quot;${reader.result}&quot; width=&quot;250&quot;/&gt; &amp;nbsp;
            &lt;div class=&quot;my-2&quot;&gt;
                The NIC is:&amp;nbsp;
                &lt;input type=&quot;text&quot; class=&quot;form-style form-control&quot; id=&quot;nic&quot; placeholder=&quot;NIC No&quot; 
                    style=&quot;text-align: center; width:170px; font-weight: bold;&quot; maxlength=&quot;12&quot;&gt;
            &lt;/div&gt;
        &lt;/div&gt;`,
    confirmButtonText: 'OK',
    focusConfirm: false,
    allowOutsideClick: false,
    width: 800,
    onOpen: function () {
        (&lt;HTMLInputElement&gt;Swal.getPopup().querySelector('#nic')).value = NICDATA;
    },
    preConfirm: () =&gt; {
        const nic = (&lt;HTMLInputElement&gt;Swal.getPopup().querySelector('#nic')).value;
        if (!nic) {
            Swal.showValidationMessage(`Please enter NIC no`)
        }
        return { nic: nic }
    }
}).then((result) =&gt; {
    if (result.value) {
        this.nicNo = `${result.value.nic}`;
        sessionStorage.removeItem(&quot;NICNO&quot;);
        sessionStorage.setItem(&quot;NICNO&quot;, `${result.value.nic}`);
        this.upload();
    } else if (result.dismiss == Swal.DismissReason.cancel) {
        this.fileUploadEvent.target.value = null;
    }
});

解决方案

Swal弹窗是动态生成的DOM元素,静态CSS/JS无法直接绑定生效,需结合动态DOM操作和事件绑定实现,具体步骤如下:

1. 调整Swal的HTML结构

将原<embed>包裹在容器内,新增一个用于显示放大区域的<div>,修改后的html内容:

&lt;div style=&quot;display: flex; flex-direction: column; justify-content: center; align-items: center&quot;&gt;
    &lt;div class=&quot;nic-zoom-container&quot; style=&quot;position: relative;&quot;&gt;
        &lt;embed id=&quot;nic-document&quot; src=&quot;${reader.result}&quot; width=&quot;250&quot; style=&quot;cursor: zoom-in;&quot;/&gt;
        &lt;div id=&quot;nic-zoom-preview&quot; style=&quot;position: absolute; border: 1px solid #ccc; width: 300px; height: 300px; overflow: hidden; display: none; z-index: 9999;&quot;&gt;&lt;/div&gt;
    &lt;/div&gt;
    &lt;div class=&quot;my-2&quot;&gt;
        The NIC is:&amp;nbsp;
        &lt;input type=&quot;text&quot; class=&quot;form-style form-control&quot; id=&quot;nic&quot; placeholder=&quot;NIC No&quot; 
            style=&quot;text-align: center; width:170px; font-weight: bold;&quot; maxlength=&quot;12&quot;&gt;
    &lt;/div&gt;
&lt;/div&gt;

2. 在onOpen钩子中绑定放大逻辑

利用Swal的onOpen回调获取动态DOM元素,绑定鼠标事件实现跟随放大效果:

onOpen: function () {
    // 原有NIC赋值逻辑
    (<HTMLInputElement>Swal.getPopup().querySelector('#nic')).value = NICDATA;

    // 获取放大相关元素
    const embed = Swal.getPopup().querySelector('#nic-document');
    const preview = Swal.getPopup().querySelector('#nic-zoom-preview');

    // 等待embed资源加载完成后计算缩放比例
    embed.addEventListener('load', () => {
        preview.style.backgroundImage = `url(${embed.src})`;
        const scale = embed.naturalWidth / embed.clientWidth;
        preview.style.backgroundSize = `${embed.naturalWidth}px ${embed.naturalHeight}px`;
    });

    // 鼠标移入显示预览区
    embed.addEventListener('mouseover', () => {
        preview.style.display = 'block';
    });

    // 鼠标移出隐藏预览区
    embed.addEventListener('mouseout', () => {
        preview.style.display = 'none';
    });

    // 鼠标移动时同步预览区位置与背景偏移
    embed.addEventListener('mousemove', (e) => {
        const rect = embed.getBoundingClientRect();
        const x = e.clientX - rect.left;
        const y = e.clientY - rect.top;
        const scale = embed.naturalWidth / embed.clientWidth;
        
        // 计算背景偏移量,实现局部放大跟随
        const bgX = -(x * scale - preview.clientWidth / 2);
        const bgY = -(y * scale - preview.clientHeight / 2);
        
        preview.style.left = `${x + 10}px`;
        preview.style.top = `${y + 10}px`;
        preview.style.backgroundPosition = `${bgX}px ${bgY}px`;
    });
}

3. 完整修改后的代码

Swal.fire({
    type: 'success',
    title: 'Please verify document',
    html: `
        &lt;div style=&quot;display: flex; flex-direction: column; justify-content: center; align-items: center&quot;&gt;
            &lt;div class=&quot;nic-zoom-container&quot; style=&quot;position: relative;&quot;&gt;
                &lt;embed id=&quot;nic-document&quot; src=&quot;${reader.result}&quot; width=&quot;250&quot; style=&quot;cursor: zoom-in;&quot;/&gt;
                &lt;div id=&quot;nic-zoom-preview&quot; style=&quot;position: absolute; border: 1px solid #ccc; width: 300px; height: 300px; overflow: hidden; display: none; z-index: 9999;&quot;&gt;&lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;my-2&quot;&gt;
                The NIC is:&amp;nbsp;
                &lt;input type=&quot;text&quot; class=&quot;form-style form-control&quot; id=&quot;nic&quot; placeholder=&quot;NIC No&quot; 
                    style=&quot;text-align: center; width:170px; font-weight: bold;&quot; maxlength=&quot;12&quot;&gt;
            &lt;/div&gt;
        &lt;/div&gt;`,
    confirmButtonText: 'OK',
    focusConfirm: false,
    allowOutsideClick: false,
    width: 800,
    onOpen: function () {
        (<HTMLInputElement>Swal.getPopup().querySelector('#nic')).value = NICDATA;

        // 图片放大逻辑
        const embed = Swal.getPopup().querySelector('#nic-document');
        const preview = Swal.getPopup().querySelector('#nic-zoom-preview');

        embed.addEventListener('load', () => {
            preview.style.backgroundImage = `url(${embed.src})`;
            const scale = embed.naturalWidth / embed.clientWidth;
            preview.style.backgroundSize = `${embed.naturalWidth}px ${embed.naturalHeight}px`;
        });

        embed.addEventListener('mouseover', () => {
            preview.style.display = 'block';
        });

        embed.addEventListener('mouseout', () => {
            preview.style.display = 'none';
        });

        embed.addEventListener('mousemove', (e) => {
            const rect = embed.getBoundingClientRect();
            const x = e.clientX - rect.left;
            const y = e.clientY - rect.top;
            const scale = embed.naturalWidth / embed.clientWidth;
            
            const bgX = -(x * scale - preview.clientWidth / 2);
            const bgY = -(y * scale - preview.clientHeight / 2);
            
            preview.style.left = `${x + 10}px`;
            preview.style.top = `${y + 10}px`;
            preview.style.backgroundPosition = `${bgX}px ${bgY}px`;
        });
    },
    preConfirm: () => {
        const nic = (<HTMLInputElement>Swal.getPopup().querySelector('#nic')).value;
        if (!nic) {
            Swal.showValidationMessage(`Please enter NIC no`)
        }
        return { nic: nic }
    }
}).then((result) => {
    if (result.value) {
        this.nicNo = `${result.value.nic}`;
        sessionStorage.removeItem("NICNO");
        sessionStorage.setItem("NICNO", `${result.value.nic}`);
        this.upload();
    } else if (result.dismiss == Swal.DismissReason.cancel) {
        this.fileUploadEvent.target.value = null;
    }
});

关键说明

  • 绑定embed的load事件确保资源加载完成后再计算尺寸,避免缩放比例错误。
  • 预览区的尺寸(300x300)、偏移量(+10px)可根据需求自行调整。

内容的提问来源于stack exchange,提问作者chmodk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 14:37:04