当包含 base64 数据作为 href 的 HTML 链接元素 (<a/>) 准备好时,是不是会触发事件?
Posted
技术标签:
【中文标题】当包含 base64 数据作为 href 的 HTML 链接元素 (<a/>) 准备好时,是不是会触发事件?【英文标题】:Is an event triggered when an HTML link element (<a/>) containing base64 data as href is ready?当包含 base64 数据作为 href 的 HTML 链接元素 (<a/>) 准备好时,是否会触发事件? 【发布时间】:2016-03-12 12:19:46 【问题描述】:我创建了一个 webpage,它基本上并排显示 2 个图像。
它有一个“下载”按钮,该按钮触发一个普通的 javascript 函数,该函数创建一个<canvas>
html 元素并将其中的两个图像连接起来。然后它会创建一个带有 base64 编码结果图像的链接 href
并点击它:
<a download="image.png" id="dllink" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABQAAAAMnCAYAAABhnf9DAAAgAElEQVR4nOzdR48kD3rn96j03pfv6qo21dVd3qT3JryP9Jll281..."></a>
我正在使用的函数如下所示:
/** * 创建画布,在其中绘制两个图像,创建一个带有结果的链接 * "href" 字段中 base64 格式的图像,将链接附加到文档中, * 并点击它 */ 函数保存图像() // 获取左图 var imgLeft = 新图像(); imgLeft.setAttribute('crossOrigin', '匿名'); imgLeft.src = "imgleft/" + idxImageShownLeft + ".jpg"; imgLeft.onload = 函数() // 左图准备好后,获取右图 var imgRight = 新图像() imgRight.setAttribute('crossOrigin', '匿名'); imgRight.src = "imgright/" + idxImageShownRight + ".jpg"; imgRight.onload = 函数() // 准备好正确的图像后,创建画布 var canv = document.createElement("canvas"); var widthLeft = parseInt(imgLeft.width); var widthRight = parseInt(imgRight.width); 变量宽度 = widthLeft + widthRight; 变量高度 = imgLeft.height; canv.setAttribute("宽度", 宽度); canv.setAttribute("高度", 高度); canv.setAttribute("id", "myCanvas"); canv.setAttribute('crossOrigin', '匿名'); var ctx = canv.getContext("2d"); // 在画布中绘制两个图像 ctx.drawImage(imgLeft, 0, 0); ctx.drawImage(imgRight, widthLeft, 0); // 从画布中创建 PNG 图像 var img = canv.toDataURL("image/png"); // 创建链接元素 var aHref = document.createElement('a'); aHref.href = img; aHref.setAttribute("id", "dlllink"); aHref.download = "image.png"; // 将链接附加到文档 var renderDiv = document.getElementById("render"); renderDiv.replaceChild(aHref, document.getElementById("dlllink")); // 点击链接 aHref.click();
我的问题是这在 Firefox 上运行良好,但在 Chrome 上却不行。
经过一番调查,我意识到通过在 Chrome 中的 aHref.click();
行之前设置断点,它可以正常工作。我认为这意味着aHref.click();
被调用之前 <a href="data:image/png;base64,...></a>
准备好被点击,但我不确定。
aHref.click();
?
【问题讨论】:
它适用于我,我在 ubuntu 上使用 chrome 46.0.2490.86(64 位)。有什么问题??renderDiv.replaceChild(aHref, document.getElementById("dllink"));
的目的是什么? aHref
, #dlink
是同一个元素吗?
@Alessandro.Vegna:问题是当我点击“下载”按钮时,有时结果图像会在我的图像编辑器中打开,有时什么也没有发生。
@guest271314:我正在做的是将之前的#dllink 元素替换为新元素 (aHref)。
与您的问题无关,但画布没有 crossorigin
属性。对于您的问题,您确定触发了图像onload
事件吗?我个人总是更喜欢在声明 onload 处理程序后设置 src。另外,我认为在某些 UA 上,链接必须是可见的,这样click()
才能工作。
【参考方案1】:
您可以将它包装在一个 init 函数中,该函数在窗口完成加载时被调用。
function init()
aHref.click();
window.onload = init;
它类似于 jQuery 的 .ready() 方法。
【讨论】:
不幸的是,我在my code 中已经有一个window.onload
函数...有没有办法绕过这个?
你总是可以把它放在一个超时函数中,让 SVG 在点击它之前有机会加载。将其设置为 1 秒。不理想,但可以解决。
感谢您的建议,它帮助我解决了这个问题。显然,使用这样的东西没有帮助:setTimeout(function() aHref.click(); , 3000);
。但是,由于某种原因,这效果更好:setTimeout(function() alert("About to click..."); aHref.click(); , 3);
。奇怪...【参考方案2】:
aHref
,document.getElementById("dllink")
似乎是同一个元素?虽然"dllink"
在调用.replaceChild
时尚未附加到document
?
尝试替换
renderDiv.appendChild(aHref);
为
renderDiv.replaceChild(aHref, document.getElementById("dllink"));
【讨论】:
是的,document.getElementById("dllink")
是之前使用的元素,aHref
是新创建的元素。我使用.replaceChild
将旧的替换为新的。在此之前,我一直在追加,因此每次单击时都会在我的文档中创建一个新元素。不幸的是,上述问题在当时也存在。
@AlfredDupont 为了避免文档中可能出现重复的id
s,是否可以在添加新的#dllink
之前删除现有的#dllink
?可以创建 stacksn-ps blog.***.com/2014/09/… , jsfiddle jsfiddle.net 来演示问题吗?见***.com/help/mcve
我已经在使用repaceChild
而不是appendChild
,因此在任何给定时间,只有一个ID 为dllink
的元素。我试过制作jsfiddle,但由于某种原因我没有成功......对不起。明天我将阅读如何制作一个最小、完整和可验证的示例,然后再试一次。以上是关于当包含 base64 数据作为 href 的 HTML 链接元素 (<a/>) 准备好时,是不是会触发事件?的主要内容,如果未能解决你的问题,请参考以下文章