1

我正在使用 HTML5 画布。我在画布元素中加载了大小为 7MB 的图像。在我的页面上,我有一个 ConvertImage 按钮:

var imageUrl;
$("#ConvertImage").click(function() {
  $("#Spinner").show();
  imageUrl = $("#canvas")[0].toDataURL("image/png;base64;");
});

Spinner 只是一个动画 gif。事实证明,当我尝试在下一个语句中检索 imageUrl 时,Spinner 没有立即显示。如果没有第二次操作,微调器会立即显示。感觉就像在 toDataURL() 操作完成后显示了微调器。

这很奇怪,因为 show() 函数是在 toDataURL() 操作之前执行的。

我该如何解决这个问题?

4

2 回答 2

3

要更新微调器,请尝试修改代码以创建额外的更新事件。

您可以使用以下方法执行此操作setTimeout

$("#ConvertImage").click(function() {
  $("#Spinner").show();

  /// add an event to be executed in about 100ms
  setTimeout(function() {
      imageUrl = $("#canvas")[0].toDataURL();
      /// done, optionally call some other function...
  }, 100);

});

这将给.show()一些时间来完成,并且事件setTimeout将在它之后排队。

您可能需要/想要更改我从这里开始的值(100 毫秒)。

代码中还有一个错误,它可能不会影响任何事情,但正确处理并没有什么坏处 -

for 的参数toDataURL只能是图像类型,即。image/png, image/jpeg,image/webp等等。 base64 部分不应该存在(当您从现有数据 uri 复制图像类型时可能会出现)。由于 PNG 是默认的,因此在任何情况下都无需指定它 - 只需使用:

var dataUri = myCanvas.toDataURL(); /// default is image/png, also when it cannot
                                    /// detect a supported type

或者

var dataUri = myCanvas.toDataURL('image/png');
var dataUri = myCanvas.toDataURL('image/jpeg');

等等

于 2013-09-24T02:01:57.187 回答
1

我认为您的问题与以下问题中描述的问题非常相似:innerHTML can't betrusted: Don't always execute synchronously

基本上,DOM 更新并不是真正的“同步”,这意味着您显示微调器的请求只会在您当前的代码完成后发生。

您需要记住,javascript 执行是单线程的,因此任何昂贵的计算都会冻结您的 UI。在执行像 AJAX 请求这样的长异步操作时显示微调器是有意义的,但在执行阻塞同步操作时是无用的,toDataURL因为 UI 在完成之前没有机会更新。

如果您需要执行长同步代码,请查看 Web Workers:http ://www.html5rocks.com/en/tutorials/workers/basics/

于 2013-09-24T01:41:22.027 回答