首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

ajaxFileUpload + Jcrop 圖片裁剪:圖片載入時序導致尺寸為 0 的完美修復

     編輯:程式設計綜合問答

故障現象

上傳圖片後,將返回 URL 設置給 <img id="target">,隨即調用 $('#target').Jcrop() 初始化裁剪區域,但 Jcrop 讀到的圖片寬高均為 0,裁剪框不顯示。

根因:異步載入競態

$('#target').attr('src', url) 只是發起網絡請求,瀏覽器異步下載圖片。JS 繼續執行 Jcrop() 時,圖片尚未解碼完成,naturalWidth/naturalHeight 為 0,Jcrop 以此計算選區導致失效。

修復方案:onload 回調中初始化

方法一:HTML 內聯 onload(最簡潔)

<img id="target" src="" onload="$(this).Jcrop();" />

方法二:jQuery 綁定 load 事件(推薦,可控性強)

function ajaxFileUpload() {
    // ... 省略上傳邏輯 ...
    success: function(data) {
        if (data.status === 'ok') {
            $('#result').text('上傳成功');
            const $img = $('#target');
            // 先卸載舊實例,防止重複綁定
            if ($img.data('Jcrop')) $img.data('Jcrop').destroy();
            // 設置 src 並綁定一次性 load 事件
            $img.one('load', function() {
                $(this).Jcrop({ aspectRatio: 1, setSelect: [0,0,200,200] });
            }).attr('src', data.imgUrl);
        }
    }
}

方法三:原生 JS Image 對象預載入(最穩健)

const img = new Image();
img.onload = () => {
    $('#target').attr('src', data.imgUrl).Jcrop({...});
};
img.src = data.imgUrl;

Jcrop 重複初始化避坑

  • 每次上傳前調用 $('#target').data('Jcrop')?.destroy() 銷燬舊實例,否則會疊加多層選區。
  • 銷燬後需移除 Jcrop 生成的包裝元素:$('#target').parent().replaceWith($('#target')) 或手動清理 .jcrop-holder。

完整流程圖解

  1. 用戶選擇文件 → ajaxFileUpload 提交。
  2. 後端保存文件,返回 {status:'ok', imgUrl:'/upload/xxx.jpg'}。
  3. 前端 success 回調:$img.one('load', initJcrop).attr('src', imgUrl)。
  4. 瀏覽器下載完成,觸發 load,執行 initJcrop,圖片尺寸已就緒。
  5. 用戶拖拽選區 → 獲取座標 → 提交後端裁剪。

總結

「先綁定 onload,再設置 src」是處理所有圖片依賴操作(裁剪、壓縮、預覽、OCR)的鐵律。ajaxFileUpload + Jcrop 只需在 success 回調中加一行 .one('load', ...) 即可徹底解決尺寸為 0 的問題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved