【问题标题】:Extract nested data from HTML with JavaScript使用 JavaScript 从 HTML 中提取嵌套数据
【发布时间】:2015-12-30 13:24:42
【问题描述】:

我有一个包含问题和答案的 HTML 页面。我想从 HTML 页面中提取数据(问题/答案)并将其放入 JavaScript 对象中。

这是我的 HTML 页面中的类结构:

  • 问题块
    • 问题(每个问题块只有 1 个问题)
    • 答案(每个问题可能有多个答案)

这是我的 HTML 代码,结构如下:

<div class="question-block">
    <h3>Question 1</h3>
    <label class="question">Name</label>
    <input type="text" class="answer" />

    <div class="question-block" style="margin-left:20px;">
        <h4>Question 1 a</h4>
        <label class="question">What is your gender?</label>
        <div class="radio">
            <input type="radio" class="answer" name="gender" id="radio-male" value="male">
            <label for="radio-male">Male</label>
        </div>
        <div class="radio">
            <input type="radio" class="answer" name="gender" id="radio-female" value="female">
            <label for="radio-female">Female</label>
        </div>
    </div>
</div>

<div class="question-block">
    <h3>Question 2</h3>
    <label class="question">Occupation</label>
    <input type="text" class="answer" />
</div>
<br />

<button id="extract" type="button">Extract HTML data</button>

<pre id="extract-div"></pre>

我想在 JavaScript 中创建这样的对象结构:

{
    "questions": [
        {
            "question": "Name",
            "answers": [
                {
                    "answer": "Kristof"
                }
            ]
        },
        {
            "question": "What is your gender?",
            "answers": [
                {
                    "answer": "Male"
                }
            ]
        },
        {
            "question": "Occupation",
            "answers": [
                {
                    "answer": "Student"
                }
            ]
        }
    ]
}

一切正常,除了嵌套的“问题块”(1a。你的性别是什么?)。本题的答案也加到第1题中。

如何使用 JavaScript 或 JQlite 仅选择位于当前“问题块”类中的答案(我正在使用 angular)。

应该可以将我的“问题块”类嵌套多个层次。 (不仅仅是示例中的 1 个级别)


如果你想测试它或查看我的 JavaScript 代码,这是我的小提琴:https://jsfiddle.net/aywxte23/

【问题讨论】:

  • 完全翻转这一轮,更长远的方法是已经在 J​​avaScript 中定义了这个结构,然后使用模板系统生成 HTML。使用 KnockoutJS 或 Angular 之类的东西还可以在 JavaScript 中的值在 UI 中更改时动态更新它们。
  • 如果您可以更改 name 属性值,您可以使用我创建的名为 Reaper 的 JavaScript 库,它可以获取所有 inputtextareaselect 元素给定元素并使用表单字段名称属性作为对象属性名称和数据类型的指南创建一个 JavaScript 对象。
  • @JamesThorpe 我使用 AngularJS,我想到了这一点,但在我创建完所有内容后,它们为我们提供了输出对象结构。对我来说,将这个结构映射到我的 UI 需要大量的重构。而且预算并不总是允许这样做:)
  • @GregBurghardt 感谢您的图书馆。我会试一试!

标签: javascript css html jqlite


【解决方案1】:

我通常不喜欢发布吹捧我编写的某些 JavaScript 库的答案,但在这种情况下似乎合适,因为我没有看到任何迹象表明您正在使用外部库或框架。

Reaper 是我编写的一个小型 JavaScript 类,它没有依赖项,可以从表单字段名称创建一个深度嵌套的对象。

您可以通过简单地更改表单字段中的 name 属性值来适应您现有的用户界面,即使使用 AngularJS:

<div id="some-common-parent-element-or-form">
    <div class="question-block">
        <h3>Question 1</h3>
        <label class="question">Name</label>
        <input type="text" class="answer" name="questions[0][answers][0][answer]" />
        <input type="hidden" name="questions[0][question]" value="Name" />

        <div class="question-block" style="margin-left:20px;">
            <h4>Question 1 a</h4>
            <label class="question">What is your gender?</label>
            <input type="hidden" name="questions[1][question]" value="What is your gender?" />
            <div class="radio">
                <input type="radio" class="questions[1][answers][0][answer]" name="gender" id="radio-male" value="male">
                <label for="radio-male">Male</label>
            </div>
            <div class="radio">
                <input type="radio" class="questions[1][answers][0][answer]" name="gender" id="radio-female" value="female">
                <label for="radio-female">Female</label>
            </div>
        </div>
    </div>

    <div class="question-block">
        <h3>Question 2</h3>
        <label class="question">Why do hotdogs come in packages of 10, but hotdog buns come in packages of 8?</label>
        <input type="text" class="answer" name="questions[2][answers][0][answer]" />
        <input type="hidden" name="questions[2][question]" value="Why do hotdogs come in packages of 10, but hotdog buns come in packages of 8?" />
    </div>
</div>

<button id="extract" type="button">Extract HTML data</button>

<pre id="extract-div"></pre>

<script type="text/javascript" src="/path/to/reaper.js"></script>

以及让它工作的 JavaScript:

var extractor = new Reaper(),
    data = null,
    element = document.getElementById("some-common-parent-element-or-form");

extractor.flat = false;
data = extractor.getData(element);

这应该为您提供您正在寻找的数据结构。

【讨论】:

  • 如何避免手动设置问题编号? (questions[0][answers][0]How to Answer) 如果我在两者之间添加一个问题,我不想更新每个名字..
  • 如果您使用某种模板语言生成 HTML,无论是在客户端还是服务器上,您都需要使用当前问题的索引和当前答案的索引。如果您被困在对 HTML 进行硬编码,那么您将被困在对索引进行硬编码。
  • 也许我们可以为您的图书馆添加标签?然后我们可以避免重复的问题或隐藏的输入值..
  • 不错的图书馆。这真的很好。我愿意为此做出贡献。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-30
  • 2021-11-09
  • 2021-06-10
  • 2019-08-25
  • 2021-06-17
相关资源
最近更新 更多