2

我正在尝试一些东西...

说我有这个:

<div id="helloworld" 
     call="chart" 
     width="350" height="200" 
     value="[[4, 8, 1, 88, 21],[45, 2, 67, 11, 9],[33, 4, 63, 4, 1]]" 
     label="['test1', 'test2', 'test3', 'test4', 'test5']"/>

我正在使用 jQuery 将我的所有元素属性获取到一个对象数组中,这部分工作,我得到了这样的东西:

Object { id="helloworld", call="chart" ... }

我需要做的第二部分是将“数组的字符串表示形式”转换为实际数组,它适用于我的,使用 JASON.parse() 作为值...但是尝试对标签做同样的事情没用,它不喜欢我在里面的单引号 (') ...尝试用 \" 逃脱它仍然没有骰子。

有谁知道将其转换回数组的优雅方法?

4

6 回答 6

5

当您使用 jQuery 和自定义属性时,首先要修复的是属性:

代替:

<div id="helloworld" 
     call="chart" 
     width="350" height="200" 
     value="[[4, 8, 1, 88, 21],[45, 2, 67, 11, 9],[33, 4, 63, 4, 1]]" 
     label="['test1', 'test2', 'test3', 'test4', 'test5']" />

你应该使用:

<div id="helloworld" 
     data-call="chart" 
     width="350" height="200" 
     data-value="[[4, 8, 1, 88, 21],[45, 2, 67, 11, 9],[33, 4, 63, 4, 1]]" 
     data-label='["test1", "test2", "test3", "test4", "test5"]'></div>

请务必为您的数据使用有效的 JSON 编码。

当你这样做时,你可以使用jQuery 的.data()方法访问属性的值

$('#helloworld').data('label'); //returns the actual array

在某些情况下,您可能希望使用.attr()字符串表示来访问属性。


如果您绝对必须保持数据原样,并且可以保证“字符串”不包含特殊字符,则可以调用$.parseJSON($('#helloworld').attr('data-label').replace("'", '"'));,但如果字符串包含引号或其他未正确编码的特殊字符,它将失败/逃脱了。

于 2013-08-16T15:58:36.657 回答
1

由于您的字符串看起来像是 JSON,因此您使用JSON.parse. JSON 不允许',因此您无法解析标签。

您是否有机会更改 HTML 的生成方式?如果您使用正确的 HTML 编码生成它,您可以轻松地将其解析为 JSON。

<div label="[&quot;test1&quot;, &quot;test2&quot;, &quot;test3&quot;, &quot;test4&quot;, &quot;test5&quot;]">

JSON.parse(elm.label); // should work
于 2013-08-16T15:54:29.943 回答
1

如果您可以控制生成代码的方式 - 尝试切换引号,因此单引号将围绕标签属性:

label='["test1", ..., "test5"]'

但正如 zzzzBov 所建议的,将自定义属性转换为 data-* 属性将是我要迈出的第一步。看看这篇小文章 - http://www.broken-links.com/2010/11/18/data-attributes-in-html-and-jquery/

于 2013-08-16T16:06:05.920 回答
0

由于它不是有效的 JSON,因此一种选择是:

arr = x.replace(/[\[\]']/g, '').replace(/\,\s/g, ',').split(',');

x在哪里"['test1', 'test2', 'test3', 'test4', 'test5']"

以上将为您提供一个数组:

["test1", "test2", "test3", "test4", "test5"]
于 2013-08-16T15:57:58.947 回答
0

另一种方法是使用eval()javascript的功能。它将字符串转换为 js 变量。

var arr = eval($('#helloworld').attr('label'));

jsFiddle

于 2013-08-16T16:13:06.813 回答
0

好的,所以最终的解决方案,结合我在网上找到的东西加上@Vega 和@adeneo 的答案,我们开始......

使用以下 jQuery 方法,我可以通过调用空白 attr() 来获取所有内容:

(function($) {
    var _old = $.fn.attr;
    $.fn.attr = function() {
        if (this[0] && arguments.length === 0) {
            var map = {};
            var i = this[0].attributes.length;
            while (i--) {
                map[this[0].attributes[i].name.toLowerCase()] = this[0].attributes[i].value;
            }
            return map;
        } else {
            return _old.apply(this, arguments);
        }
    }
}(jQuery));

我可以像这样获取所有属性:

var data = $(document.getElementById(id)).attr();

有了这个,我将我的元素属性保持原样(通过 HTML5 调整):

<div id="helloworld"
     data-call="chart"
     data-width="350"
     data-height="200"
     data-stacked="true"
     data-value="[[4, 8, 1, 88, 21],[45, 2, 67, 11, 9],[33, 4, 63, 4, 1]]" 
     data-label="['test1', 'test2', 'test3', 'test4', 'test5']"/>

然后我使用 JSON.parse() 处理数据值,然后使用@adeneo 的方法处理字符串数组。

    data.value = JSON.parse(data.value);
    data.label = data.label.split(',').map(function(val) { return val.trim().replace(/(\'|\[|\])/g,''); });

出于我自己的其他 js 代码的目的,我只是从密钥中删除数据,现在一切都是 kosher !

for (key in data) {
    var newKey = key.replace("data-","");
    if (newKey != key) {
        data[newKey] = data[key];
        delete data[key];
    }
}

现在我可以将数据传递给我现有的函数了!!!!:)

我之前是如何调用我的函数的:

var data = {
    id: 'helloworld',
    width: 350,
    height: 200,
    value: [
        [4, 8, 1, 88, 21],
        [45, 2, 67, 11, 9],
        [33, 4, 63, 4, 1]
    ],
    stacked: true,
    label: ["test1", "test2", "test3", "test4", "test5"]
};
chart(data);

现在我可以使用 jQuery,找到具有特定类名的所有元素,然后只需解析属性即可触发调用。:)

于 2013-08-16T17:07:58.730 回答