2

JS/jQueryに基づく小さなJavaScriptファイルと追加のライブラリがあります。独立したファイルとして完全に実行されていますが、Chrome拡張機能で起動して実行するのに問題があります。

スクリプトは、HTMLページの各画像の特定の特性をチェックし、それに応じて画像の周囲に境界線を追加します。

マニフェスト.json

{
    "name": "ImageId",
    "version": "0.1",
    "manifest_version": 2,
    "browser_action":  {
        "default_icon": "icon.png"
    },
    "content_scripts" : [
        {
            "matches" : [
                "http://*/*",
                "https://*/*"
            ],
            "js" : ["jquery-1.8.3.min.js","jquery.exif.js","content_script.js"],
            "run_at" : "document_start",
            "all_frames" : false
        }
    ],
    "icons":{
        "128":"icon.png"
    }
}

content_script.js:

jQuery(window).load(function(){
    $('img').each(function() {

        var gpslo=0;
        var gpsla=0;
        if (typeof(gpslo) != "undefined" && gpslo != null) {
            var gpslo= $(this).exif("GPSLongitude");
            var gpsla = $(this).exif("GPSLatitude");
        }
        console.log(gpslo+"--"+ gpsla);

        if (gpslo!=0) {
            $(this).css('border', "solid 20px red");  
            $(this).click(function() {
                alert("Long: " + $(this).exif("GPSLongitude") + ", Lat: " + $(this).exif("GPSLatitude"));
            });
        }
        else {

            $(this).css('border', "solid 20px gray"); 
        };

    });
});

さて、これをChromeで非常に単純な1枚の画像のみのWebサイトで実行すると、エラーはまったく発生せず、白いページだけが表示されます。

また、拡張システムの外部でスクリプトを実行すると、すべてが正常に機能します。これをもっとうまく説明する方法がよくわかりません。これらはチュートリアル以外の私の最初のステップですので、親切にしてください:)

完全なテストファイルと拡張ファイルをWorking(Html).zipNotWorking(Chrome).zipにアップロードしました。

4

3 に答える 3

3

Sudarshanが答えdocument.writeたように、そのコードをコメントアウトしますjquery.exif.jsdocument.writeコンテンツスクリプトでは、以前のDOMが消去され、VBscriptはChromeでは機能しません。

ただし、問題はそれだけではありません。

  1. 質問のように、コンテンツスクリプトがに設定されて"run_at" : "document_start"いる場合は、を使用する必要があります$(document).ready()。疑わしいときは、$(document).ready()とにかく使用しても問題はありません。

  2. "run_at" : "document_idle"リンクしたファイルのように、 コンテンツスクリプトがに設定されている場合、イベントが発生した後にスクリプトがdocument.load起動することがあります。したがって、$(window).load()常に機能するとは限りません。

  3. Chromeでは、少なくとも指定したテストページでは、Exifデータが届くまでに最大6秒かかります。(Firefoxではほとんど瞬時に実行されます。)つまり、時間遅延後に画像を確認する必要があります。

その他のそれほど重要ではない問題:

  1. CSSクラスを使用して、前述の時限チェックを支援し、インラインCSSを回避します。
  2. ハンドラーが1回だけアタッチされ、AJAXの変更を適切に補正するように、ではなくjQuery.on()を使用します。.click()

すべてをまとめると、content_script.js更新、このスクリプトの下を参照)になります。

$(document).ready ( function () {
    $(window).load (CompForExifPluginInitDelay);

    //--- In a content script, the load event may have already fired.
    if (document.readyState == "complete") {
        CompForExifPluginInitDelay ();
    }

    $(document.head).append ( '                             \
        <style type="text/css">                             \
            img.myExt_HasExif {                             \
                border:     20px solid red !important;      \
            }                                               \
            img.myExt_WithoutExif {                         \
                border:     20px solid gray !important;     \
            }                                               \
        </style>                                            \
    ' );

    //-- Use jQuery .on(), not .click().
    $(document.body).on ("click", "img.myExt_HasExif", popupLatLong);
} );

function CompForExifPluginInitDelay () {
    //-- Exif Init takes somewhere between 1.6 and 6 seconds on Chrome!!!
    var numChecks       = 0;
    var checkInterval   = 444;  //-- 0.4 secs is plenty fast enough
    var maxChecks       = 6 * 1000 / checkInterval + 1;

    var imageCheckTimer = setInterval ( function() {
            numChecks++;

            findImagesWithLatLong (numChecks);

            if (numChecks >= maxChecks) {
                clearInterval (imageCheckTimer);

                //-- All remaining images don't have lat-long data.
                $("img").not(".myExt_HasExif").addClass("myExt_WithoutExif");

                console.log ("***** Passes complete! *****");
            }
        },
        checkInterval
    );
}

function findImagesWithLatLong (passNum) {
    console.log ("***** Pass: ", passNum);
    $("img").not (".myExt_HasExif").each ( function (J) {
        var jThis   = $(this);
        var gpslo   = jThis.exif ("GPSLongitude");
        var gpsla   = jThis.exif ("GPSLatitude");

        console.log (J + ": ", gpslo + "--" + gpsla);
        if (gpslo != 0) {
            jThis.addClass ("myExt_HasExif");
        }
    } );
}

function popupLatLong (zEvent) {
    var jThis   = $(this);
    alert (
        "Longitude: " + jThis.exif ("GPSLongitude")
        + ", Latitude: " + jThis.exif ("GPSLatitude")
    );
}

これは、これまでのすべてのテストで機能します(これを強制終了することに関連して)document.write()




更新:使用.exifLoad()

PAEzが彼の回答で指摘したように、Chromeのタイミングの問題は、で画像を手動でスキャンすることで解決されたよう.exifLoad()です。

これは私がテストしたときに機能し、タイマーを使用するための好ましいアプローチです。

したがって、PAEzの答えは(Sudarshanの答えと組み合わせて)機能しますが、私のバージョンのコード(他の問題に対処する)は次のようになります。

$(document).ready ( function () {
    $(window).load (findImagesWithLatLong);

    //--- In a content script, the load event may have already fired.
    if (document.readyState == "complete") {
        findImagesWithLatLong ();
    }

    $(document.head).append ( '                             \
        <style type="text/css">                             \
            img.myExt_HasExif {                             \
                border:     20px solid red !important;      \
            }                                               \
            img.myExt_WithoutExif {                         \
                border:     20px solid gray !important;     \
            }                                               \
        </style>                                            \
    ' );

    //-- Use jQuery .on(), not .click().
    $(document.body).on ("click", "img.myExt_HasExif", popupLatLong);
} );

function findImagesWithLatLong (passNum) {
    $("img").not (".myExt_HasExif").each ( function (J) {
        $(this).exifLoad ( function () {
            var jThis   = $(this);
            var gpslo   = jThis.exif ("GPSLongitude");
            var gpsla   = jThis.exif ("GPSLatitude");

            console.log (J + ": ", gpslo + "--" + gpsla);
            if (gpslo != 0)
                jThis.addClass ("myExt_HasExif");
            else
                jThis.addClass ("myExt_WithoutExif");
        }.bind (this) );
    } );
}

function popupLatLong (zEvent) {
    var jThis   = $(this);
    alert (
        "Longitude: " + jThis.exif ("GPSLongitude")
        + ", Latitude: " + jThis.exif ("GPSLatitude")
    );
}
于 2012-12-08T06:30:02.247 に答える
1

jquery.exif.jsで次のコードを削除した後に機能します

/*document.write(
    "<script type='text/vbscript'>\r\n"
    + "Function IEBinary_getByteAt(strBinary, iOffset)\r\n"
    + " IEBinary_getByteAt = AscB(MidB(strBinary,iOffset+1,1))\r\n"
    + "End Function\r\n"
    + "Function IEBinary_getLength(strBinary)\r\n"
    + " IEBinary_getLength = LenB(strBinary)\r\n"
    + "End Function\r\n"
    + "</script>\r\n"
);*/

上記のcodeinjquery.exif.jsを削除するだけで機能します

出力

ここに画像の説明を入力してください

さらに情報が必要な場合はお知らせください

于 2012-12-08T04:34:39.733 に答える
1

これは答えというよりはコメントですが、コードが含まれているので、答えとしてやらなければなりませんでした...

私があなたの実際の例を試したとき、ファイルがxhr呼び出しによってまだ取得されていないために、まだ存在していない値を取得しようとしているので、ほとんど機能しませんでした。
コードを以下に変更することで、これを修正できます。CompForExifPluginInitDelayこれは、実際にヒットしたりミスしたり する可能性のある使用を避けるために、BrockAdamsの回答に組み込まれる可能性があります。

jQuery(window).load(function() {
    $('img').each(function() {
        $(this).exifLoad(function() {
            var gpslo = 0;
            var gpsla = 0;
            if(typeof(gpslo) != "undefined" && gpslo !== null) {
                var gpslo = $(this).exif("GPSLongitude");
                var gpsla = $(this).exif("GPSLatitude");
            }
            console.log(gpslo + "--" + gpsla);
            if(gpslo != 0) {
                $(this).css('border', "solid 20px red");
                $(this).click(function() {
                    alert("Longitude: " + $(this).exif("GPSLongitude") + ", Latitude: " + $(this).exif("GPSLatitude"));
                });
            } else {

                $(this).css('border', "solid 20px gray");
            };

        }.bind($(this)));
    });
});

いつものように、私はJQueryを本当に知らないので、これをもっとJQの方法で行うことができるなら、言ってください。

于 2012-12-08T10:37:32.123 に答える