当Javascript回调无法使用时

mon*_*jbl 6 javascript html5 asynchronous html2canvas downloadify

我知道你不应该在Javascript中做阻塞,而且我从来没有无法重构那些必须这样做.但我遇到了一些我不知道如何处理回调的东西.我正在尝试使用带有html2canvas的Downloadify(这仅适用于IE,下载数据URI在IE中不起作用).您必须指定数据函数,以便Flash对象知道要下载的内容.不幸的是,html2canvas是异步的.在获取数据URI之前,我需要能够等到onrendered事件被填满.

$('#snapshot').downloadify({
        filename: function(){
            return 'timeline.png';
        },
        data: function(){
            var d = null;
            html2canvas($('#timeline'),{
                onrendered:function(canvas){
                    d = canvas.toDataURL();
                }
            });

            //need to be able to block until d isn't null

            return d;
        },
        swf: '../static/bin/downloadify.swf',
        downloadImage: '../static/img/camera_icon_32.png?rev=1',
        width: 32,
        height: 32,
        transparent: true,
        append: false
});
Run Code Online (Sandbox Code Playgroud)

我对其他方法的建议持开放态度,但我被困住了.

编辑 - 有几条评论表明需要有关Downloadify的更多信息(https://github.com/dcneiner/Downloadify).Downloadify是一个Flash对象,可用于触发浏览器的"另存为"窗口.downloadify()函数只是初始化Flash对象并<object/>在元素中粘贴标记.由于它是Flash对象,因此您无法在不导致安全违规的情况下从Javascript触发事件.

我只在IE上使用它来下载Canvas元素的图像.在所有其他浏览器中,我只能使用数据URI,但IE是一种特殊的花.

mon*_*jbl 5

对于那些花费一整夜的穷人来说,试图让HTML5功能在IE9上工作,这就是我最终使用的内容.我可以有点逍遥法外,因为我们并不太关心IE用户获得的用户友好体验,这是一个内部应用程序.但是,YMMV.

基本上,当返回字符串为空时,Downloadify将不执行任何操作.因此,由于html2canvas呈现的异步特性,用户第一次点击时,不会发生任何事情.第二次(假设渲染完成,如果没有任何东西将继续发生,直到它),该值不为空并且保存继续.我使用onCancel和onCoplete回调来再次清空值,以确保下次用户尝试保存时,图像不会太陈旧.

这并不能解释用户在点击之间以某种方式更改DOM的事件,但我不知道可以为此做些什么.我并不为此感到自豪,但IE就是它的本质.它有效,现在已足够了.

    var renderedPng = '';
    var rendering = false;

    $('#snapshot').downloadify({
        filename: function(){
            return 'timeline.png';
        },
        data: function(){
            if(!rendering && renderedPng == ''){
                rendering = true;
                html2canvas($('#timeline'),{
                    onrendered:function(canvas){
                        renderedPng = canvas.toDataURL().replace('data:image/png;base64,','');
                        rendering = false;
                    }
                });
            }
            return renderedPng;
        },
        onComplete:function(){
            renderedPng = '';
        },
        onCancel: function(){
            renderedPng = '';
        },
        dataType: 'base64',
        swf: '../static/bin/downloadify.swf',
        downloadImage: '../static/img/camera_icon_32.png?rev=1',
        width: 32,
        height: 32,
        transparent: true,
        append: false
    });
Run Code Online (Sandbox Code Playgroud)