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

模态框内滑动事件监听器无法更新图片问题求助

问题

我做了一个带图片模态框的网页,点击图片能在模态框内打开,点击「上一张」「下一张」按钮切换图片都正常。但给移动端添加滑动手势功能时出现问题:已添加对应的事件监听器,逻辑为右滑触发上一张按钮点击、左滑触发下一张按钮点击,检查发现modalImg.src确实已更新,但页面上的图片并未发生变化。

初始化代码

// Get the modal
var modal = document.getElementById(modal);

// Get the image and insert it inside the modal - use its "alt" text as a caption
var img = document.getElementById(img_id);
var modalImg = document.getElementById("work-img");
var captionText = document.getElementById(caption);
var images = document.getElementsByTagName('img'); 
var srcList = [];
var altList = [];
for(var i = 0; i < images.length; i++) {
    if (images[i].src.toString().includes('paintings')) {
        srcList.push(images[i].src);
        altList.push(images[i].alt);
    }
}

按钮及相关函数代码

function updateImage(img_src) {
    //document.write(modalImg.src, captionText.innerHTML);
    modalImg.src = img_src;
    captionText.innerHTML = altList[srcList.indexOf(index)]
    //img = modalImg.src
    //document.write(modalImg.src, captionText.innerHTML);
}

img.onclick = function(){
    modal.style.display = "block";
    modalImg.src = this.src;
    captionText.innerHTML = this.alt;
    /* disable scrolling */
    document.documentElement.style.overflow = 'hidden';
    document.body.scroll = "no";
}

// Get the <span> element that closes the modal
var close = document.getElementsByClassName("close")[0];

// When the user clicks on <span> (x), close the modal
close.onclick = function() {
    modal.style.display = "none";
    /* enable scrolling */
    document.documentElement.style.overflow = 'scroll';
    document.body.scroll = "yes";
}
// Get the <span> element that opens image full-screen
var fullscreen = document.getElementsByClassName("fullscreen-button")[0];

// When the user clicks on <span> (x), close the modal
fullscreen.onclick = function() {
    //Use the specification method before using prefixed versions
    if (modalImg.requestFullscreen) {
        modalImg.requestFullscreen();
    } else if (modalImg.webkitRequestFullscreen) { /* Safari */
        modalImg.webkitRequestFullscreen();
    } else if (modalImg.msRequestFullscreen) { /* IE11 */
        modalImg.msRequestFullscreen();
    }
}
// click image to open in fullscreen
modalImg.onclick = function(){
    fullscreen.click();
}

// Get the <span> element that goes to the next image
var next = document.getElementsByClassName("next")[0];
next.onclick = function() {
    this_img_index = srcList.indexOf(modalImg.src);
    if (this_img_index == srcList.length-1){
        next_img = srcList[0];
    } else {
        next_img = srcList[this_img_index+1];
    }
    updateImage(next_img);
    
}

// Get the <span> element that goes to the previous image
var prev = document.getElementsByClassName("prev")[0];
prev.onclick = function() {
    this_img_index = srcList.indexOf(modalImg.src);
    if (this_img_index == 0){
        prev_img = srcList[srcList.length-1];
    } else {
        prev_img = srcList[this_img_index-1];
    }
    //modalImg.src = prev_img;
    //captionText.innerHTML = altList[srcList.indexOf(prev_img)];
    updateImage(prev_img);
}

// Get the input field
var input = document.getElementById("myInput");
document.onkeydown = checkKey;
function checkKey(e) {
    e = e || window.event;
    //
    if (e.keyCode == '37') {
        // left arrow
        prev.click();
    } else if (e.keyCode == '39') {
        // right arrow
        next.click();
    } else if (e.keyCode == '27') {
        //escape
        close.click();
    }
}

触摸事件监听器代码

var touchStartX;
var touchEndX;
const minSwipeDistance = 50; // Minimum swipe distance threshold
// calculate starting point
function handleTouchStart(event) {
    touchStartX = event.touches[0].clientX;
}
// calculate ending point
function handleTouchMove(event) {
    touchEndX = event.touches[0].clientX;
}
function handleTouchEnd() {
    const swipeDistance = touchStartX - touchEndX;
    if (swipeDistance < -minSwipeDistance) {
        // Swipe to previous
        prev.click();
    } else if (swipeDistance > minSwipeDistance){
        // Swipe to next
        var next = document.getElementsByClassName("next")[0];
        next.click();
        //document.write(modalImg.src);
        //captionText.innerHTML = altList[srcList.indexOf(index)];
        //document.write(modalImg.src);
    }
}
// Attach touch event listeners to the image element
modal.addEventListener('touchstart', function handleTouchStart(event) {
    touchStartX = event.touches[0].clientX;
});
modal.addEventListener('touchmove', function handleTouchMove(event) {
    touchEndX = event.touches[0].clientX;
});
modal.addEventListener('touchend',  function(){ handleTouchEnd(); });
}

问题排查与修复

1. 修复updateImage函数的逻辑错误

函数中altList[srcList.indexOf(index)]的index是未定义变量,导致控制台报错,可能中断图片渲染逻辑。修改为:

function updateImage(img_src) {
    modalImg.src = img_src;
    const imgIndex = srcList.indexOf(img_src);
    captionText.innerHTML = altList[imgIndex];
}

2. 移除触摸事件中重复获取元素的冗余代码

handleTouchEnd中无需重新获取next元素,直接使用全局已定义的变量即可:

function handleTouchEnd() {
    const swipeDistance = touchStartX - touchEndX;
    if (swipeDistance < -minSwipeDistance) {
        prev.click();
    } else if (swipeDistance > minSwipeDistance){
        next.click();
    }
}

3. 阻止触摸滑动的默认行为

移动端触摸时浏览器可能触发默认滚动,干扰手势逻辑,在touchmove事件中添加阻止默认行为的代码:

modal.addEventListener('touchmove', function handleTouchMove(event) {
    event.preventDefault();
    touchEndX = event.touches[0].clientX;
});

4. 修复变量未声明的问题

next.onclick和prev.onclick中的this_img_index未声明,会成为全局变量引发冲突,添加变量声明:

next.onclick = function() {
    const this_img_index = srcList.indexOf(modalImg.src);
    // 后续逻辑不变
}

prev.onclick中的this_img_index同理添加const声明。

5. 解决src路径匹配问题

浏览器会将相对路径转为绝对路径存储在modalImg.src中,若srcList存的是相对路径,indexOf会返回-1导致逻辑出错。初始化srcList时统一存储绝对路径,或给图片添加data属性(如data-img-id)作为匹配标识,替代src字符串匹配。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 17:54:59