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 中运行它时,我根本没有收到任何错误,而只是一个白页。

在扩展系统之外运行脚本也一切正常。我不太确定如何更好地解释这一点。这些是我在教程之外的第一步,所以请善待:)

我将完整的测试和扩展文件上传到: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. 使用jQuery 的.on(), 而不是.click(), 以便处理程序只附加一次并优雅地补偿 AJAX 更改。

把它们放在一起,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"
);*/

只需在 jquery.exif.js 中消除上面的代码就可以了

输出

在此处输入图像描述

如果您需要更多信息,请与我们联系

于 2012-12-08T04:34:39.733 回答
1

这更像是评论而不是答案,但它涉及代码,所以我不得不将其作为答案......

当我尝试您的工作示例时,它几乎没有对我有用,因为您试图获取由于 xhr 调用尚未获得文件而尚未出现的值。
您可以通过将代码更改为以下来解决此问题。这可能会被纳入 Brock Adams 的答案中,以避免使用CompForExifPluginInitDelay可能会被击中和错过的答案。

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 回答