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

如何在FileReader加载完成后执行JQuery下载按钮生成代码?

解决异步执行问题:确保下载按钮在SVG加载完成后生成

Got it, the core issue here is that FileReader.readAsDataURL() is an asynchronous operation. Right now, your code that creates the download link runs immediately after starting the file read — before imageIsLoaded has finished processing the SVG and inserting it into the DOM. That's why $('#ss').find('svg')[0] returns undefined when you try to use it.

解决方案:将下载按钮逻辑移到异步回调完成后执行

The fix is straightforward: move the code that creates the download link inside the imageIsLoaded function, or call it explicitly at the end of imageIsLoaded (if you want to keep the logic separate). Here's how to implement both approaches:


方法1:直接将下载逻辑移入imageIsLoaded

Modify your imageIsLoaded function to include the download button creation at the very end, once all SVG processing is done:

function imageIsLoaded(e) {
  var ret = atob(e.target.result.split(',')[1]);
  $('#ss').html(ret);
  var placement_ids = [];

  // 所有你的SVG处理逻辑保持不变...
  $('#PLACEMENTS > g').each(function(){
    id = $(this).attr('id');
    if (id.indexOf("_1_") >= 0 ){
      id = id.replace("_1_", "")
    }
    if (id.length <= 3){
      id = [id.slice(0, 2), "0", id.slice(2)].join('');
    }
    $(this).attr('id',id);
    rect = $(this).find('rect');
    rect_id = rect.attr('id');
    rect_id = rect_id.replace("_x5F", "");
    rect_id = rect_id.replace("_3_", "");
    if (rect_id.length <= 8){
      rect_id = [rect_id.slice(0, 2), "0", rect_id.slice(2)].join('');
    }
    rect.attr('id', rect_id);
    rect_x = rect.attr('x');
    rect_y = rect.attr('y');
    rect_w = rect.attr('width');
    rect_h = rect.attr('height');
    
    // 原有的各个PLxx判断逻辑保持不变
    if (id == "PL01"){
      $('#PL01').attr('available-decoration','TEAM_NAME,PLAYER_NAME,LOGO,GRAPHIC,NUMBERS');
      $(this).append("<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='"+ rect_x +"px' height='"+ rect_h +"px' id='PL01_LOGO_GRAPHIC' y='"+ rect_y +"px' width='"+ rect_w +"px' version='1.1' preserveAspectRatio='xMidYMid' viewBox='0 0 256 405'><g></g></svg>");
    }
    if (id == "PL02"){
      $('#PL02').attr('available-decoration','TEAM_NAME,PLAYER_NAME,LOGO,GRAPHIC,NUMBERS');
      $(this).append("<svg id='PL02_LOGO_GRAPHIC' y='"+ rect_y +"px' height='"+ rect_h +"px' x='"+ rect_x +"px' width='"+ rect_w +"px' viewBox='0 0 256 256' version='1.1' preserveAspectRatio='xMidYMid'><g></g></svg>");
    }
    if (id == "PL03"){
      $('#PL03').attr('available-decoration','TEAM_NAME,PLAYER_NAME,LOGO,GRAPHIC,NUMBERS');
      $(this).append("<svg id='PL03_LOGO_GRAPHIC' y='"+ rect_y +"px' height='"+ rect_h +"px' x='"+ rect_x +"px' width='"+ rect_w +"px' viewBox='0 0 256 256' version='1.1' preserveAspectRatio='xMidYMid'><g></g></svg>");
    }
    if (id == "PL05"){
      $('#PL05').attr('available-decoration','LOGO,NUMBERS');
      rect_t = rect.attr('transform');
      $(this).append("<g id='PL05_ClipPath'><defs><rect id='SVGID_1_' x='"+ rect_x +"' y='"+ rect_y +"' transform='" + rect_t + "' width='" + rect_w + "' height='" + rect_h + "'></rect></defs><clipPath id='SVGID_2_'><use xlink:href='#SVGID_1_' overflow='visible'></use></clipPath><g clip-path='url(#SVGID_2_)'><!--?xml version='1.0' encoding='UTF-8'?--><svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' width='" + rect_w * 2 + "' height='" + rect_h + 9 + "' viewBox='0 0 250 250' version='1.1' preserveAspectRatio='xMidYMid' x='14.571' y='29.721px' id='PL05_LOGO_GRAPHIC' style='overflow: visible;'><g data-rotate-degree='45' data-scale='true' transform='rotate(45 128 124) scale(-1,1) translate(-250, 0)'></g></svg></g></g>");
    }
    if (id == "PL06"){
      $('#PL06').attr('available-decoration','LOGO,NUMBERS');
      $(this).append("<g id='PL061_LOGO_x5F_GRAPHIC'><defs></defs><clipPath id='SVGID_2_1'><use xlink:href='#PL06_RECT' overflow='visible'></use></clipPath><g clip-path='url(#SVGID_2_1)'><!--?xml version='1.0' encoding='UTF-8'?--><svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' height='" + rect_h + "' style='overflow: visible;' x='" + rect_x + "' id='PL06_LOGO_GRAPHIC' y='" + rect_y + "' width='" + rect_w + "' version='1.1' preserveAspectRatio='xMidYMid' viewBox='0 0 300 300' enable-background='new 0 0 300 300' xml:space='preserve'><g data-rotate-degree='-45' data-scale='true' transform='rotate(-45 128 124) scale(-1,1) translate(-300, 0)'></g></svg></g></g>");
    }
    if (id == "PL37"){
      $('#PL37').attr('available-decoration','TEAM_NAME,PLAYER_NAME');
    }
    $(this).append( "<foreignObject id='" + id + "_fo' x='" + rect_x +"' y='" + rect_y +"' fill='none' width='" + rect_w +"' height='" + rect_h +"'><canvas width='" + rect_w +"' height='" + rect_h +"' id='"+ id +"_canvas'></canvas></foreignObject>" );
    placement_ids.push(id);
  });
  $('#PLACEMENTS').attr('used-placements',placement_ids);

  // --- 在这里添加下载按钮逻辑 ---
  var a = document.body.appendChild(document.createElement("a"));
  a.download = "export.svg";
  // 注意:需要用outerHTML获取SVG的字符串内容,而不是直接传元素对象
  a.href = "data:image/svg+xml," + $('#ss').find('svg')[0].outerHTML;
  a.innerHTML = "[Export content]";
}

Then simplify your file change handler to just trigger the FileReader:

$(":file").change(function () {
  if (this.files && this.files[0]) {
    console.log(this.files[0]);
    var reader = new FileReader();
    reader.onload = imageIsLoaded;
    reader.readAsDataURL(this.files[0]);
  }
});

方法2:封装下载逻辑为独立函数(保持代码分离)

If you prefer to keep imageIsLoaded focused on SVG processing, create a separate function for the download button and call it at the end of imageIsLoaded:

// 独立的下载按钮生成函数
function createDownloadButton() {
  var a = document.body.appendChild(document.createElement("a"));
  a.download = "export.svg";
  a.href = "data:image/svg+xml," + $('#ss').find('svg')[0].outerHTML;
  a.innerHTML = "[Export content]";
}

// 修改后的imageIsLoaded
function imageIsLoaded(e) {
  var ret = atob(e.target.result.split(',')[1]);
  $('#ss').html(ret);
  var placement_ids = [];

  // 所有你的SVG处理逻辑保持不变(和上面的完整逻辑一致)
  $('#PLACEMENTS > g').each(function(){
    // 原有的ID修改、元素添加逻辑
    // ...(省略原有代码,保持不变)
  });
  $('#PLACEMENTS').attr('used-placements',placement_ids);

  // 调用下载按钮函数
  createDownloadButton();
}

// 文件change处理函数不变
$(":file").change(function () {
  if (this.files && this.files[0]) {
    console.log(this.files[0]);
    var reader = new FileReader();
    reader.onload = imageIsLoaded;
    reader.readAsDataURL(this.files[0]);
  }
});

额外注意点

  • I added .outerHTML to $('#ss').find('svg')[0] — without this, you're trying to pass the SVG element object directly into the data URI, which won't work. You need the actual SVG markup string.
  • Make sure there are no errors in the SVG processing logic that might prevent the SVG from being inserted into #ss — check your browser console for any DOM manipulation errors.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:29:53