上傳圖片後,將返回 URL 設置給 <img id="target">,隨即調用 $('#target').Jcrop() 初始化裁剪區域,但 Jcrop 讀到的圖片寬高均為 0,裁剪框不顯示。
$('#target').attr('src', url) 只是發起網絡請求,瀏覽器異步下載圖片。JS 繼續執行 Jcrop() 時,圖片尚未解碼完成,naturalWidth/naturalHeight 為 0,Jcrop 以此計算選區導致失效。
<img id="target" src="" onload="$(this).Jcrop();" />
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);
}
}
}
const img = new Image();
img.onload = () => {
$('#target').attr('src', data.imgUrl).Jcrop({...});
};
img.src = data.imgUrl;
$('#target').data('Jcrop')?.destroy() 銷燬舊實例,否則會疊加多層選區。$('#target').parent().replaceWith($('#target')) 或手動清理 .jcrop-holder。ajaxFileUpload 提交。{status:'ok', imgUrl:'/upload/xxx.jpg'}。success 回調:$img.one('load', initJcrop).attr('src', imgUrl)。load,執行 initJcrop,圖片尺寸已就緒。「先綁定 onload,再設置 src」是處理所有圖片依賴操作(裁剪、壓縮、預覽、OCR)的鐵律。ajaxFileUpload + Jcrop 只需在 success 回調中加一行 .one('load', ...) 即可徹底解決尺寸為 0 的問題。