简体   繁体   English

使用 Javascript 解析的 HTML5 嵌套数据-* 属性不返回嵌套对象

[英]HTML5 nested data-* attributes parsed with Javascript don't return a nested object

I am stuck in a concept of html5 data attributes.我被困在 html5 数据属性的概念中。 That attributes allows nesting like:该属性允许嵌套,如:

<div data-user--name="John" data-user--surname="Doe"></div>

I have seen plugins in the past (like select2 ) and some of them use the following similar syntax to make an AJAX call:我过去看过插件(如select2 ),其中一些使用以下类似的语法来进行 AJAX 调用:

<div data-ajax--url="my/url" data-ajax--method="POST">

This code in background converts to a dataset in javascript and it returns something like this:这段后台代码在 javascript 中转换为数据集,并返回如下内容:

data = { 
    ajax: { 
        url: "my/url", 
        method: "POST"
    }
}

But in the practice, vanilla javascript's dataset and jQuery data() methods return different object content.但在实践中,vanilla javascript 的dataset和 jQuery data()方法返回不同的对象内容。

Javascript Javascript

 var el = document.getElementsByTagName("div")[0]; el.innerHTML = "<pre>"+JSON.stringify(el.dataset)+"</pre>";
 <div data-ajax--url="my/url" data-ajax--method="POST"></div>

jQuery 1.x jQuery 1.x

 $('div').html("<pre>"+JSON.stringify($('div').data())+"</pre>");
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <div data-ajax--url="my/url" data-ajax--method="POST"></div>

jQuery 2.x jQuery 2.x

 $('div').html("<pre>"+JSON.stringify($('div').data())+"</pre>");
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div data-ajax--url="my/url" data-ajax--method="POST"></div>


The code in error seems to be the jQuery 1.x versions, because in 2.x versions jQuery returns the same as vanilla Javascript.错误代码似乎是 jQuery 1.x 版本,因为在 2.x 版本中 jQuery 返回与 vanilla Javascript 相同的代码。 I found a related bug so it's confirmed: https://github.com/select2/select2/issues/2969我发现了一个相关的错误,所以确认了: https : //github.com/select2/select2/issues/2969

But I can't find where to construct a nested javascript object with the nested html syntax, like the following example:但是我找不到使用嵌套 html 语法构造嵌套 javascript 对象的位置,如下例所示:

{ 
    ajax: { 
       url: "my/url"
       method: "POST"
    }
}

Is there any Javascript method, or a polyfill, that makes this kind of objects reading the data-* HTML attributes?是否有任何 Javascript 方法或 polyfill 使此类对象读取data-* HTML 属性? Is it possible to parse the data javascript strings (ie ajax-Method ) and return a nested object ( ajax.method ) ?是否可以解析数据 javascript 字符串(即ajax-Method )并返回嵌套对象( ajax.method )?

Ran into exact same need, but @artofcode's answer parses only 2 levels.遇到了完全相同的需求,但@artofcode 的回答只解析了 2 个级别。 So I had to figure out how to parse unlimited number of levels.所以我必须弄清楚如何解析无限数量的级别。 Here's my solution without limiting levels, based on original answer.这是我的解决方案,没有限制级别,基于原始答案。

function parseNestedDataSet(data_set) {
    var keys = Object.keys(data_set);
    var data = {};
    for (var i = 0; i < keys.length; i++) {
        var key = keys[i];
        var value = data_set[key];
        var splat = key.split('-');

        data = parseNestedDataSetKey(splat, value, data);
    }

    return data;
}

function parseNestedDataSetKey(keys, value, data) {
    data = data || {};
    var key = keys[0].toLowerCase();

    // Not tested, but should convert to camel case
    // var key = keys[0].replace(/-([a-z])/g, function (g) {
    //      return g[1].toUpperCase();
    // });

    if (!data[key]) {
        data[key] = {};
    }

    if (keys.length > 1) {
        keys.splice(0, 1);
        data[key] = parseNestedDataSetKey(keys, value, data[key]);
    } else {
        data[key] = value;
    }

    return data;
}

Didn't test it thoroughly, but it works in my case, like:没有彻底测试它,但它适用于我的情况,例如:

  • data-buttons--btn1--title ; data-buttons--btn1--title ;
  • data-buttons--btn1--icon ; data-buttons--btn1--icon ;
  • data-buttons--btn2--title . data-buttons--btn2--title
function parseDataset(dataset) {
    data = {};
    for(var i = 0; i < Object.keys(dataset).length; i++) {
        var key = Object.keys(dataset)[i];
        var value = dataset[key];
        var splat = key.split("-");
        console.log(key, data, splat);
        if(!data[splat[0]]) {
            data[splat[0]] = {};
        }
        data[splat[0]][splat[1]] = value;
    }
    return data;
}

Untested, but should work.未经测试,但应该工作。 Pass el.dataset into the method, get a data object out like:el.dataset传入该方法,得到一个data对象,如:

data = {
    'ajax': {
        'Method': 'POST',
        'Url': 'my/url'
    }
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM