これを機能させるために変更する必要があることがいくつかあります.Jimboの答えを取り、他のいくつかのことを追加します:
var dict = {
"dataP": "this is my p tag text"
};
$('[data-text]').each(function () {
if ( $(this).data("text") ) {
var dictAttr = $(this).data("text");
if ( dictAttr && dict[dictAttr] ) {
$(this).html( dict[dictAttr] );
}
}
});
また、物事を簡単にするためにマークアップを変更する必要があります (特に、1 つのオブジェクトのみを扱っているdict
場合)。
<p data-text="dataP"></p>
上記の変更により、期待どおりに機能するはずです。
http://jsfiddle.net/b2zgw/
文字列ベースのオブジェクト ナビゲーション
奇妙なことに、私は現在、文字列ベースのオブジェクト ナビゲーションのフレームワークに取り組んでいます。ただし、スタックオーバーフローの回答の最後に追加するにはコードベースが複雑すぎる場合があります。私のコメントへの追加として、両方の世界で最高の可能性がある3番目のオプションがあることに気付きました(必要なものによって異なります)。
:: 評価
この方法はお勧めしませんが、簡単にするために議論することはできません。以下は上記のコードのスニペットであり、その部分を置き換える必要があります。
var dictNav = $(this).data("text"); /// e.g. say dictNav == 'dict.dataP'
var ref; eval('ref='+dictNav);
if ( ref && red.substr ) {
$(this).html( ref );
}
上記の問題は、eval
任意の JavaScript を評価することです。そのため、攻撃者はdata-text
、ページ上の何かに属性を追加する方法を見つけるだけで、好きな JavaScript を実行できます。
:: 文字列ベースのナビゲーション
以下は、改善できる単純な機能ですが、アイデアを提供する必要があります。
function navigate( obj, path ){
var cur = obj, bits = path.split('.');
for ( var i=0, l=bits.length; i<l && cur; i++ ) {
cur = cur[bits[i]];
}
return cur;
}
dict
上記を使用して、辞書構造をナビゲートできます。「ナビゲーションパス」を特定の var 名 (つまり) で開始するため、トラバースするオブジェクトの 1 レベル下に辞書を配置する必要があることに注意してください。これが理由です{dict:dict}
。複数の辞書をサポートするには、そのオブジェクトをそのように拡張するだけで済みます{dict:dict,dict2:dict2}
— 以下はスニペットであり、元のコードを置き換える必要があります:
var dictNav = $(this).data("text"); /// e.g. say dictNav == 'dict.dataP.test'
var ref = navigate({dict:dict}, dictNav);
if ( ref && red.substr ) {
$(this).html( ref );
}
:: 3 番目のオプション - 辞書を単純化します
3 番目のオプションがおそらく最も最適ですが、ディクショナリをリアルタイムで (または少なくとも簡単に) 変更できないことを意味します。基本的に、残りのコードを実行する前に、その構造を変更する解析関数を介して辞書をプッシュします。
var dict = {
"dataP": "this is a test",
"forms": {
"inputLabel": "this is a second level"
}
};
function simplifyDict( obj, target, path, subpath ){
if ( !target ) { target = {}; }
if ( !path ) { path = ''; }
for( var i in obj ) {
subpath = (path ? path + '.' : '') + i;
if ( typeof obj[i] == 'object' ) {
simplifyDict( obj[i], target, subpath );
}
else {
target[subpath] = obj[i];
}
}
return target;
}
dict = simplifyDict( dict );
上記の単純化関数は、次のようなものを返す必要があります。
{
"dataP" : "this is a test",
"forms.inputLabel" : "this is a second level"
}
次に、この回答の上部にある私の元のコードを使用するだけです。文字列を個別のオブジェクト プロパティに変換して辞書をナビゲートする代わりに、辞書を文字列ベースのルックアップに切り替えたので、文字列を直接使用できるようになりました。dict['forms.inputLabel']