0

私は最初の Chrome 拡張機能に取り組んでいます。jquery に関するいくつかの興味深い概念を学んだ後、"Rob W" のおかげで生の JavaScript コードに移行しました。

実際には、拡張機能はいくつかのパラメーターを使用してリモート ページに XMLHttpRequest を実行し、結果を操作した後、HTML リストをポップアップ ウィンドウにレンダリングします。

これですべてが稼働しているので、いくつかのオプションを追加するために移動しています。最初のものは、リストの要素に制限を設定するための「ロードする要素の数」でした。

オプションを管理するために派手な設定を使用していますが、ここに問題があります。

拡張機能は、ローカル ストレージ設定に関する「キャッシュ」があるかのように動作します。何も設定せずに拡張機能のクリーン インストールを実行すると、デフォルトの数の要素が正しく読み込まれます。

値を変更した場合。変更を確認するには、拡張機能をリロードする必要があります。設定を削除した場合にのみ、拡張機能がすぐに意図したとおりに機能することがわかります。

さて、具体的な情報をもう少し掘り下げていきます。

これは popup.js スクリプトです。

chrome.extension.sendRequest({action: 'gpmeGetOptions'}, function(theOptions) {
    //Load the limit for topic shown
    console.log('NGI-LH -> Received NGI "max_topic_shown" setting ('+theOptions.max_topic_shown+')');
    //Initializing the async connection
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'http://gaming.ngi.it/subscription.php?do=viewsubscription&pp='+theOptions.max_topic_shown+'&folderid=all&sort=lastpost&order=desc');
    xhr.onload = function() {
        var html = "<ul>";
        var doc = xhr.response;
        var TDs = doc.querySelectorAll('td[id*="td_threadtitle_"]');
        [].forEach.call(TDs, function(td) {
            //Removes useless elements from the source
            var tag = td.querySelector('img[src="images/misc/tag.png"]'); (tag != null) ? tag.parentNode.removeChild(tag) : false;
            var div_small_font = td.querySelector('div[class="smallfont"]'); (small_font != null ) ? small_font.parentNode.removeChild(small_font) : false;
            var span_small_font = td.querySelector('span[class="smallfont"]'); (small_font != null ) ? small_font.parentNode.removeChild(small_font) : false;
            var span = td.querySelector('span'); (span != null ) ? span.parentNode.removeChild(span) : false;
            //Change the look of some elements
            var firstnew = td.querySelector('img[src="images/buttons/firstnew.gif"]'); (firstnew != null ) ? firstnew.src = "/img/icons/comment.gif" : false;
            var boldtext = td.querySelector('a[style="font-weight:bold"]'); (boldtext != null ) ? boldtext.style.fontWeight = "normal" : false;
            //Modify the lenght of the strings
            var lenght_str = td.querySelector('a[id^="thread_title_"]');
            if (lenght_str.textContent.length > 40) {
                lenght_str.textContent = lenght_str.textContent.substring(0, 40);
                lenght_str.innerHTML += "<span style='font-size: 6pt'> [...]</span>";
            }
            //Removes "Poll:" and Tabulation from the strings
            td.querySelector('div').innerHTML = td.querySelector('div').innerHTML.replace(/(Poll)+(:)/g, '');
            //Modify the URL from relative to absolute and add the target="_newtab" for the ICON
            (td.querySelector('a[id^="thread_title"]') != null) ? td.querySelector('a[id^="thread_title"]').href += "&goto=newpost" : false;
            (td.querySelector('a[id^="thread_goto"]') != null) ? td.querySelector('a[id^="thread_goto"]').href += "&goto=newpost": false;
            (td.querySelector('a[id^="thread_title"]') != null) ? td.querySelector('a[id^="thread_title"]').target = "_newtab": false;
            (td.querySelector('a[id^="thread_goto"]') != null) ? td.querySelector('a[id^="thread_goto"]').target = "_newtab": false;

            //Store the td into the main 'html' variable
            html += "<li>"+td.innerHTML+"</li>";
    //      console.log(td);
        });
        html += "</ul>";
        //Send the html variable to the popup window
        document.getElementById("content").innerHTML = html.toString();
    };
    xhr.responseType = 'document'; // Chrome 18+
    xhr.send();
});

background.js に従います (HTML は /fancy-settings/source/lib/store.js をロードするだけで、このスクリプトは Fancy-Setting How-To で説明されています)。

//Initialization fancy-settings
var settings = new Store("settings", {
    "old_logo": false,
    "max_topic_shown": "10"
});
//Load settings
var settings = settings.toObject();

//Listener who send back the settings
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
    if (request.action == 'gpmeGetOptions') {
        sendResponse(settings);
    }
});

私が言ったように、console.logはキャッシュされた値を表示します。値を「20」に設定すると、拡張機能をリロードするまでデフォルトのままになります。30 に変更すると、拡張機能をリロードするまで 20 のままになります。

さらに何かが必要な場合は、お尋ねください。質問を編集します。

4

1 に答える 1

1

問題は概念的な誤解にあるようです。Chrome 拡張機能のbackground.jsスクリプトは一度読み込まれ、拡張機能または Chrome ブラウザが再起動されるまで実行され続けます。

これは、現在のコードではsettings、拡張機能が最初に開始されたときにのみ変数値が読み込まれることを意味します。拡張機能がロードされてから更新された値にアクセスするには、settings変数の値をbackground.js再ロードする必要があります。

これを実現するには、いくつかの方法があります。最も簡単な方法は、settings関連するコードを のchrome.extension.onRequest.addListenerコールバック関数に移動することbackground.jsです。これは、設定が実際に更新されたかどうかに関係なく、リクエストごとに再ロードされるため、最も非効率的なソリューションでもあります。

より良い解決策は、オプション ページで値が更新された場合settingsにのみ値をリロードすることです。background.jsこれにより、設定変数の永続性またはキャッシュが有利に使用されます。実装の詳細についてはドキュメントを確認する必要がありますが、オプション ページからページにメッセージを送信し、新しい設定が保存された後background.jsに更新するように指示することをお勧めします。settings

余談ですvarが、行内のキーワードvar settings = settings.toObject();は必要ありません。変数を再宣言する必要はありません。既に上で宣言されています。

于 2012-11-12T21:53:36.140 に答える