2

在一个页面中,我调用外部 js 文件,它包含一个字典。我想用他们的属性替换元素文本。

<p data-text="dict.dataP"></p>
<p data-text="dict.data.P2"></p>

我想用外部文件字典填充它

var dict = {
    "dataP1": "this is my p text",
    "data" : {
         "p2": "my another paragraph"
    },

};

我试着用这个

$.each(function () {
    if ($(this).attr("data-text").length > 0) {
        $(this).html(
        $(this).attr('data-text') /*we got a problem here. it returns string*/ );
    }
});

此处的代码笔: codepen.io

JSFiddle 这里 jsfiddle.net

我怎样才能做到这一点?

编辑的字典。我们在字典中有字典。

4

3 回答 3

5

要访问数据属性,请使用:

$(this).data('text');

文本是属性声明中连字符后的部分。

于 2013-01-18T11:00:32.213 回答
2

您想将字典中的文本设置为具有匹配数据属性的元素,对吗?

试试这个:

var dict = {
    "dataP": "this is my p tag text",
    "dataDiv": "dummy div"
};

$('p').each(function () {
    var data = $(this).data('text');
    $(this).html(dict[data.split('.')[1]])
});

http://jsfiddle.net/eB6E2/1/

于 2013-01-18T11:08:20.360 回答
2

您应该更改一些内容以使其正常工作,采用 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] );
    }
  }
});

您还应该更改标记以使事情变得更容易(特别是如果您只处理一个dict对象):

<p data-text="dataP"></p>

通过上述更改,您应该可以按预期工作。

http://jsfiddle.net/b2zgw/

基于字符串的对象导航

奇怪的是,正如我们所说,我实际上正在研究基于字符串的对象导航框架。但是,如果代码库过于复杂,无法仅在 stackoverflow 答案的末尾添加。作为我评论的补充,我意识到还有第三种选择可能是两全其美的选择(取决于您的需要)。

:: 评估

我不推荐这种方法,但为了简单起见,不能与之争论——以下是上面代码的片段,应该替换该部分:

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

使用上述内容,您可以导航您的字典结构 - 请注意,因为您以特定的 var 名称开始您的“导航路径”(即dict),您必须将您的字典放置在您希望遍历的对象的下一级;这就是原因{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 );
}

:: 第三个选项 - 简化你的字典

第三个选项可能是最理想的,但意味着不能实时修改字典(或至少不容易)。基本上在运行其余代码之前,通过修改其结构的解析函数推送字典:

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']

于 2013-01-18T11:09:30.527 回答