6

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
});

これを行う他の方法についての提案は受け付けていますが、行き詰まっています。

編集- いくつかのコメントにより、Downloadify に関する詳細情報が必要であるように思われました ( https://github.com/dcneiner/Downloadify )。Downloadify は、ブラウザーの [名前を付けて保存] ウィンドウをトリガーするために使用できる Flash オブジェクトです。downloadify() 関数は、Flash オブジェクトを初期化<object/>し、要素にタグを付けるだけです。これは Flash オブジェクトであるため、セキュリティ違反を引き起こさずに Javascript からイベントをトリガーすることはできません。

Canvas要素の画像をダウンロードするためだけにIEに使用しています。他のすべてのブラウザーでは、データ URI を使用できますが、IE は特別な花です。

4

1 に答える 1

5

HTML5機能をIE9で動作させるために一晩を費やす貧しい人々のために、これが私が最終的に使用したものです。IEユーザーが使い勝​​手が悪くなることをそれほど心配しておらず、これは内部アプリケーションであるため、私はちょっとそれを回避することができます。しかし、YMMV。

基本的に、戻り文字列が空白の場合、Downloadifyは何もしません。したがって、html2canvasのレンダリングは非同期であるため、ユーザーが最初にクリックしても何も起こりません。2回目(レンダリングが行われたと仮定すると、それが行われるまで何も起こらない場合)、値は空白ではなく、保存が続行されます。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
    });
于 2013-02-15T02:50:10.340 に答える