【问题标题】:Save the dynamically created DOM and create a JSON保存动态创建的 DOM 并创建 JSON
【发布时间】:2017-04-10 19:50:59
【问题描述】:

我需要帮助来创建具有完全相同格式的动态创建的 dom 对象的 JSON,这是在接收 JSON 以创建动态元素时。

请查看下面的 JS Fiddle 链接和源代码。 现在,如果您看到,在表中我通过 JSON 获取数据。 表中的复选框值是 JSON 对象。 当我选择任何一个复选框并单击保存时,会生成并显示相应的 div。

现在,我想使用“保存显示的数据并创建 json”按钮来保存这个动态创建的 DOM 结构,并创建格式相同的 JSON(包含所有属性(不管事实如何,是否它们是否显示在相应的父级中。例如,电话号码、图像所有数据都应该在 JSON 中可用,即使它没有显示但在原始 JSON 中可用)。

JS Fiddle

<!doctype html>
<html>
    <head>
        <style>
            table, th, td {
                border: 1px solid #ddd;
                border-collapse: collapse;
                padding: 10px;
            }

            table {
                margin: auto;
            }

            .parent {
                height: 25%;
                width: 90%;
                padding: 1%;
                margin-left: 1%;
                margin-top: 1%;
                border: 1px solid black;
            }

            .parent:nth-child(odd){
                background: skyblue;
            }

            .parent:nth-child(even){
                background: green;
            }
        </style>
        <body>
          <button onclick="createTable()">Load Table</button>
          <button onclick="saveData()">Save Table data</button>
                <table id="datatable" align="center">
                    <tr><th>Select</th><th>Name</th><th>DOB</th></tr>
                </table>

            <br />
            <button onclick="createJson()">Save displayed data & create JSON</button>
            <br />
            <div class="container">
                <
            </div>

            <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
            <script>
                function createTable() {
                    $.getJSON("https://api.randomuser.me/?results=5", function(data) {
                        // First, clear the table
                        $('#datatable tr:has(td)').remove();
                        data.results.forEach(function (record) {
                            var json = JSON.stringify(record);
                            $('#datatable').append(
                                $('<tr>').append(
                                    $('<td>').append(
                                        $('<input>').attr('type', 'checkbox')
                                                    .addClass('selectRow')
                                                    .val(json)
                                    ),
                                    $('<td>').append(
                                        $('<a>').attr('href', record.picture.thumbnail)
                                                .addClass('imgurl')
                                                .attr('target', '_blank')
                                                .text(record.name.first)
                                    ),
                                    $('<td>').append(record.dob)
                                )
                            );
                        })
                    }).fail(function(error) {
                        console.log("**********AJAX ERROR: " + error);
                    });            
                }

                function saveData(){
                    // Scrape the URLs that were already collected into a Set:
                    var used = new Set($('.myLink').map(function () {
                        return $(this).attr('href');
                    }).get());
                    var errors = [];
                    $('input.selectRow:checked').each(function(count) {
                        // Get the JSON that is stored as value for the checkbox
                        var obj = JSON.parse($(this).val());
                        // See if this URL was already collected (that's easy with Set)
                        if (used.has(obj.weburl)) {
                            errors.push(obj.title);
                        } else {
                            // Append it to the collection (use jQuery for appending)
                            $('.container').append(
                                $('<div>').addClass('parent').append(
                                    $('<label>').addClass('dataLabel').text('Name: '),
                                    obj.name.first + ' ' + obj.name.last,
                                    $('<br>'), // line-break between name & pic
                                    $('<img>').attr('src', obj.picture.thumbnail), $('<br>'),
                                    $('<label>').addClass('dataLabel').text('Date of birth: '),
                                    obj.dob, $('<br>'),
                                    $('<label>').addClass('dataLabel').text('Address: '), $('<br>'),
                                    obj.location.street, $('<br>'),
                                    obj.location.city + ' ' + obj.location.postcode, $('<br>'),
                                    obj.location.state, $('<br>')
                                )
                            );
                        }
                        // Clear checkbox:
                        $('input', this).prop('checked', false)
                    });
                    if (errors.length) 
                        alert('The following were already selected:\n' + errors.join('\n'))
                }
            </script>

        </body>
    </head>
</html>

示例 JSON

{
  "results": [
    {
      "gender": "male",
      "name": {
        "title": "mr",
        "first": "romain",
        "last": "hoogmoed"
      },
      "location": {
        "street": "1861 jan pieterszoon coenstraat",
        "city": "maasdriel",
        "state": "zeeland",
        "postcode": 69217
      },
      "email": "romain.hoogmoed@example.com",
      "login": {
        "username": "lazyduck408",
        "password": "jokers",
        "salt": "UGtRFz4N",
        "md5": "6d83a8c084731ee73eb5f9398b923183",
        "sha1": "cb21097d8c430f2716538e365447910d90476f6e",
        "sha256": "5a9b09c86195b8d8b01ee219d7d9794e2abb6641a2351850c49c309f1fc204a0"
      },
      "dob": "1983-07-14 07:29:45",
      "registered": "2010-09-24 02:10:42",
      "phone": "(656)-976-4980",
      "cell": "(065)-247-9303",
      "id": {
        "name": "BSN",
        "value": "04242023"
      },
      "picture": {
        "large": "https://randomuser.me/api/portraits/men/83.jpg",
        "medium": "https://randomuser.me/api/portraits/med/men/83.jpg",
        "thumbnail": "https://randomuser.me/api/portraits/thumb/men/83.jpg"
      },
      "nat": "NL"
    }
  ],
  "info": {
    "seed": "2da87e9305069f1d",
    "results": 1,
    "page": 1,
    "version": "1.1"
  }
}

【问题讨论】:

  • 更好地分享你的json而不是api调用数据
  • 我已经用示例 JSON 更新了问题。
  • 听起来您需要一个用户选择模型和一个源数据模型。然后,您只需要对该选择进行投影,将项目替换为源数据。您不需要在 DOM 中执行此操作,也不应该这样做。
  • 我需要这个来使用完全相同的代码在另一个页面中显示所选用户的个人资料。因此,我由此创建的 Json 将被用作其他页面的输入,就像我在这里使用它来显示表中的数据一样。
  • 为了保存 DOM,我想我们可以使用 "html.clone()" !!为了检查 DOM 中的内容,我们可以使用 myLink 类!此外,我们可以使用包含所有“myLink”网址的“已使用”变量。如何从所有这些值中创建 JSON?

标签: javascript jquery json dom dynamic


【解决方案1】:

您可以更改代码,以便在每次保存操作时,不仅将数据添加到 div,还添加到全局变量,您可以在其中添加与复选框值完全相同的数据属性。

然后,在另一个操作中,您只需将其作为 JSON 输出到您需要的任何地方(发布到 URL,保存在 localStorage 中,...)。

这里是代码,它有一个额外的按钮,用于将收集到的项目的 JSON 输出到控制台:

function createTable() {
    $.getJSON("https://api.randomuser.me/?results=25", function(data) {
        $('#datatable tr:has(td)').remove();
        data.results.forEach(function (record) {
            var json = JSON.stringify(record);
            $('#datatable').append(
                $('<tr>').append(
                    $('<td>').append(
                        $('<input>').attr('type', 'checkbox')
                                    .addClass('selectRow')
                                    .val(json)
                    ),
                    $('<td>').append(
                        $('<a>').attr('href', record.picture.thumbnail)
                                .addClass('imgurl')
                                .attr('target', '_blank')
                                .text(record.name.first)
                    ),
                    $('<td>').append(record.dob)
                )
            );
        })
    }).fail(function(error) {
        console.log("**********AJAX ERROR: " + error);
    });            
}

var savedData = new Map; // Keyed by image URL. Start with nothing.

function saveData(){
    var errors = [];
    // Add selected to map
    $('input.selectRow:checked').each(function(count) {
        // Get the JSON that is stored as value for the checkbox
        var obj = JSON.parse($(this).val());
        // See if this URL was already collected (that's easy with Set)
        if (savedData.get(obj.picture.thumbnail)) {
            errors.push(obj.name.first);
        } else {
            // Append it to the Map:
            savedData.set(obj.picture.thumbnail, obj);
        }
    });
    refreshDisplay();
    if (errors.length) {
        alert('The following were already selected:\n' + errors.join('\n'));
    }
}

function refreshDisplay() {
    $('.container').html('');
    savedData.forEach(function (obj) {
        // Reset container, and append collected data (use jQuery for appending)
        $('.container').append(
            $('<div>').addClass('parent').append(
                $('<label>').addClass('dataLabel').text('Name: '),
                obj.name.first + ' ' + obj.name.last,
                $('<br>'), // line-break between name & pic
                $('<img>').addClass('myLink').attr('src', obj.picture.thumbnail), $('<br>'),
                $('<label>').addClass('dataLabel').text('Date of birth: '),
                obj.dob, $('<br>'),
                $('<label>').addClass('dataLabel').text('Address: '), $('<br>'),
                obj.location.street, $('<br>'),
                obj.location.city + ' ' + obj.location.postcode, $('<br>'),
                obj.location.state, $('<br>'),
                $('<button>').addClass('removeMe').text('Delete')
            )
        );
    })
    // Clear checkboxes:
    $('.selectRow').prop('checked', false);
}

function logSavedData(){
    // Translate Map to array of values:
    var data = Array.from(savedData, function (pair) {
        return pair[1];
    });
    // Convert to JSON and log to console. You would instead post it
    // to some URL, or save it to localStorage.
    console.log(JSON.stringify(data, null, 2));
}

$(document).on('click', '.removeMe', function() {
    var key = $('.myLink', $(this).parent()).attr('src');
    // Delete this from the saved Data
    savedData.delete(key);
    // And redisplay
    refreshDisplay();
});
table, th, td {
    border: 1px solid #ddd;
    border-collapse: collapse;
    padding: 10px;
}

.parent {
    height: 25%;
    width: 90%;
    padding: 1%;
    margin-left: 1%;
    margin-top: 1%;
    border: 1px solid black;

}

.parent:nth-child(odd){
    background: skyblue;
}

.parent:nth-child(even){
    background: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button onclick="createTable()">Create Table</button>
<table id="datatable">
    <tr><th>Select</th><th>Name</th><th>DOB</th></tr>
</table>
<button onclick="saveData()">Save Selected</button>
<br />
<div class="container"></div>
<button onclick="logSavedData()">Get Saved Data</button>

【讨论】:

  • 在这种情况下有一个小问题。它允许我从表中添加相同的用户,尽管它存在于 div.container 中。
  • 另外,假设每个 div.parent 中都有一个删除按钮,单击它可以删除相应的 div.parent。如何从已保存的数据 JSON 以及已删除的 div.parent 中删除相同的内容?我的按钮 - ;
  • savedData.set 方法调用的键中有错误,因此您可以添加两次相同的条目。现在已经纠正了。我更改了项目在div 中的显示方式:它现在总是首先清除div 并从头开始填充它。这样它就可以重复用于删除操作。现在每个条目中还有一个删除按钮。注意:如果您有更多功能要添加,但在添加时遇到问题,请提出一个新问题。
  • 嗯是的..对不起!下次会记住这一点!顺便说一句,变量“key”到底是什么? div.parent 是如何被删除的?
  • 关键是缩略图URL(存储在img标签的src属性中)。 div.parent 的删除由 refreshDisplay 函数覆盖,该函数首先删除所有内容,然后从内存映射 (savedData) 中再次创建这些 div。
【解决方案2】:

我认为将 jquery 数据表用于此功能会更有帮助。您可以做很多事情,例如直接/每列在数据表上绑定来自 ajax 调用的 JSON,并自定义呈现的 html 内容的 DOM。还有一个fileSave函数可以导出数据。

注意:任何$('cssselector').Datatable 内容都必须采用 Json 格式。

有关更多信息,请查看 API 文档中的 datatables ajax data sourcecustom buttons extension 以获取数据表。使用带有适当 parseandSaveJson 函数的自定义按钮将完成您需要的工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多