【问题标题】:Delete a JSON element with JavaScript (from HTML)使用 JavaScript 删除 JSON 元素(来自 HTML)
【发布时间】:2017-11-21 18:13:14
【问题描述】:

我目前正在与

建立一个论坛
  • 基本技术:HTML、CSS、JavaScript 和 NodeJS
  • 使用 JSON 文件名从 API 检索数据。例如。 \json\myfile.json

我能够获取使用 JSON api 的请求,但无法删除它们。

这是我的代码:

JSON:

[
  {
    "title": "Hello World !",
    "content": "1111111"
  },
  {
    "title": "Lorem Ipsum",
    "content": "22222222"
  },
  {
    "title": "azertyuiop",
    "content": "33333333"
  }
]

HTML:

<div id="element"></div>

  <div id="newElement">
    <input id="newTitle" type="text" value="">
    <input id="newContent" type="text" value="">
    <button type="button" name="addElement" onclick="addElement()">Add</button>
  </div>

JavaScript:

 'use strict';

  function loadJSON(callback) {
    var xobj = new XMLHttpRequest();
    xobj.overrideMimeType("application/json");
    xobj.open('GET', 'json/elements.json', true);
    xobj.onreadystatechange = function() {
      if (xobj.readyState == 4 && xobj.status == "200") {
        callback(xobj.responseText);
      }
    };
    xobj.send(null);
  }

  function getElements() {
    loadJSON(function(response) {
      var elements = JSON.parse(response);
      var containerElement = document.getElementById("element");
      var titleElement;
      var contentElement;
      var deleteElement;
      for (var i = 0; i < elements.length; i++) {
        titleElement = document.createElement("h1");
        contentElement = document.createElement("p");
        deleteElement = document.createElement("button");
        containerElement.appendChild(titleElement);
        containerElement.appendChild(contentElement);
        containerElement.appendChild(deleteElement);
        titleElement.innerHTML = elements[i].title;
        contentElement.innerHTML = elements[i].content;
        deleteElement.innerHTML = "Delete";
        deleteElement.addEventListener('click', function() {
          console.log(titleElement[i]);
          console.log(contentElement[i]);
        });
      }
    });
  }

function addElement() {
    loadJSON(function(response) {
      var elements = JSON.parse(response);
      var newTitle = document.getElementById('newTitle').value;
      var newContent = document.getElementById('newContent').value;
      console.log("Title: " + newTitle + "     " + "Content: " + 
newContent);
    });
  }

  getElements();

我查看了闭包是如何工作的,但我不知道如何将它们应用到我的代码中,在我登录 contentElementtitleElement 后,它返回给我 undefined

【问题讨论】:

  • 代码或标记中没有提到删除任何内容。您需要给我们一个简短的基本示例,说明您正在尝试做什么。了解如何创建minimal reproducible example
  • “删除一个 JSON 元素...” 一旦你解析了它,它就不再是 JSON 了。 JSON 是一种用于数据交换的文本表示法(More here.) 如果您正在处理 JavaScript 源代码,而不是处理 字符串,那么您就不是在处理 JSON。
  • 此外,您没有保留解析结果。
  • 推送完整代码我会帮助你
  • 您的个人资料显示您已经回来了。以下任何一个答案是否回答了您的问题?如果没有,也许发表评论询问更多信息,或编辑问题...

标签: javascript html json


【解决方案1】:

你真的很亲密。为contentElementtitleElement 获取undefined 的问题是described in this question's answers,但那里的答案,一般来说,并没有给你最简单的方法来处理你的情况。

见 cmets:

function getElements() {
    loadJSON(function(response) {
        var elements = JSON.parse(response);
        var containerElement = document.getElementById("element");
        var entryElement;
        var titleElement;
        var contentElement;
        var deleteElement;
        for (var i = 0; i < elements.length; i++) {
            // Create a container for the entry; let's give it a class we'll
            //  use later as well
            entryElement = document.createElement("div");
            entryElement.className = "entry";
            titleElement = document.createElement("h1");
            contentElement = document.createElement("p");
            deleteElement = document.createElement("button");
            // Put these in the entry's container
            entryElement.appendChild(titleElement);
            entryElement.appendChild(contentElement);
            entryElement.appendChild(deleteElement);
            titleElement.innerHTML = elements[i].title;
            contentElement.innerHTML = elements[i].content;
            deleteElement.innerHTML = "Delete";
            deleteElement.addEventListener('click', function() {
                // Here, `this` refers to the delete button that was clicked;
                // remove its parent element:
                var parent = this.parentNode;
                parent.parentNode.removeChild(parent);
            });
            // Add the entry to the main container
            containerElement.appendChild(entryElement);
        }
    });
}

另外,无需在addElement 中重新加载 JSON,只需将新元素实时添加到页面即可。事实上,既然我们想在从 JSON 创建元素时和添加新元素时都这样做,让我们把它放在一个函数中,然后重用该函数:

'use strict'

var json = '[{' +
    '"title": "Hello World !",' +
    '"content": "1111111"' +
    '},' +
    '{' +
    '"title": "Lorem Ipsum",' +
    '"content": "22222222"' +
    '},' +
    '{' +
    '"title": "azertyuiop",' +
    '"content": "33333333"' +
    '}' +
    ']';

function loadJSON(callback) {
    // Simulate the ajax
    setTimeout(callback, 200, json);
    /*
    var xobj = new XMLHttpRequest();
    xobj.overrideMimeType("application/json");
    xobj.open('GET', 'json/elements.json', true);
    xobj.onreadystatechange = function() {
        if (xobj.readyState == 4 && xobj.status == "200") {
            callback(xobj.responseText);
        }
    };
    xobj.send(null);
    */
}

function addElement(title, content) {
    // Create a container for the entry
    var entryElement = document.createElement("div");
    entryElement.className = "entry";
    // And the things to put in it
    var titleElement = document.createElement("h1");
    var contentElement = document.createElement("p");
    var deleteElement = document.createElement("button");
    // Put these in the entry's container
    entryElement.appendChild(titleElement);
    entryElement.appendChild(contentElement);
    entryElement.appendChild(deleteElement);
    // You might consider HTML-escaping things, here's how
    titleElement.appendChild(document.createTextNode(title));
    contentElement.appendChild(document.createTextNode(content));
    deleteElement.innerHTML = "Delete";
    deleteElement.addEventListener('click', function() {
        // Here, `this` refers to the delete button that was clicked;
        // remove its parent element:
        var parent = this.parentNode;
        parent.parentNode.removeChild(parent);
    });
    // Add the entry to the main container
    document.getElementById("element").appendChild(entryElement);
}

function getElements() {
    loadJSON(function(response) {
        var elements = JSON.parse(response);
        for (var i = 0; i < elements.length; i++) {
            // Call our reusable function
            addElement(elements[i].title, elements[i].content);
        }
    });
}

function addElementClick() {
    // Just call our reusable function
    addElement(document.getElementById('newTitle').value, document.getElementById('newContent').value);
}

getElements();
<div id="element"></div>
    
      <div id="newElement">
        <input id="newTitle" type="text" value="">
        <input id="newContent" type="text" value="">
        <button type="button" name="addElement" onclick="addElementClick()">Add</button>
      </div>

请注意,我将您原来的 addElement 重命名为 addElementClick 并有一个新的 addElement 函数接受标题和内容作为参数。

如果在某个阶段您想要重建 elements 数组,您可以通过从 DOM 中检索数据来轻松实现:

function getElementsFromUI() {
    var elements = [];
    document.querySelector(".entry").forEach(function(entryElement) {
        elements.push({
            title: entryElement.querySelector("h1").innerHTML,
            content: entryElement.querySelector("p").innerHTML
        });
    });
    return elements;
}

querySelectorAll 返回的NodeList 最近才得到forEach,但您可以在旧版浏览器上轻松地对其进行 polyfill:

if (typeof NodeList !== "undefined" && NodeList.prototype && !NodeList.prototype.forEach) {
    Object.defineProperty(NodeList.prototype, "forEach", {
        value: Array.prototype.forEach,
        configurable: true,
        enumerable: true
    });
}

现场示例:

'use strict'

var json = '[{' +
    '"title": "Hello World !",' +
    '"content": "1111111"' +
    '},' +
    '{' +
    '"title": "Lorem Ipsum",' +
    '"content": "22222222"' +
    '},' +
    '{' +
    '"title": "azertyuiop",' +
    '"content": "33333333"' +
    '}' +
    ']';

if (typeof NodeList !== "undefined" && NodeList.prototype && !NodeList.prototype.forEach) {
    Object.defineProperty(NodeList.prototype, "forEach", {
        value: Array.prototype.forEach,
        configurable: true,
        enumerable: true
    });
}

function loadJSON(callback) {
    // Simulate the ajax
    setTimeout(callback, 200, json);
    /*
    var xobj = new XMLHttpRequest();
    xobj.overrideMimeType("application/json");
    xobj.open('GET', 'json/elements.json', true);
    xobj.onreadystatechange = function() {
        if (xobj.readyState == 4 && xobj.status == "200") {
            callback(xobj.responseText);
        }
    };
    xobj.send(null);
    */
}

function addElement(title, content) {
    // Create a container for the entry
    var entryElement = document.createElement("div");
    entryElement.className = "entry";
    // And the things to put in it
    var titleElement = document.createElement("h1");
    var contentElement = document.createElement("p");
    var deleteElement = document.createElement("button");
    // Put these in the entry's container
    entryElement.appendChild(titleElement);
    entryElement.appendChild(contentElement);
    entryElement.appendChild(deleteElement);
    // You might consider HTML-escaping things, here's how
    titleElement.appendChild(document.createTextNode(title));
    contentElement.appendChild(document.createTextNode(content));
    deleteElement.innerHTML = "Delete";
    deleteElement.addEventListener('click', function() {
        // Here, `this` refers to the delete button that was clicked;
        // remove its parent element:
        var parent = this.parentNode;
        parent.parentNode.removeChild(parent);
    });
    // Add the entry to the main container
    document.getElementById("element").appendChild(entryElement);
}

function getElements() {
    loadJSON(function(response) {
        var elements = JSON.parse(response);
        for (var i = 0; i < elements.length; i++) {
            // Call our reusable function
            addElement(elements[i].title, elements[i].content);
        }
    });
}

function addElementClick() {
    // Just call our reusable function
    addElement(document.getElementById('newTitle').value, document.getElementById('newContent').value);
}

function getElementsFromUI() {
    var elements = [];
    document.querySelectorAll(".entry").forEach(function(entryElement) {
        elements.push({
            title: entryElement.querySelector("h1").innerHTML,
            content: entryElement.querySelector("p").innerHTML
        });
    });
    return elements;
}

document.getElementById("btnShow").addEventListener("click", function() {
    console.log(getElementsFromUI());
});
getElements();
.as-console-wrapper {
  max-height: 100% !important;
}
<input type="button" id="btnShow" value="Show Elements">
<div id="element"></div>
<div id="newElement">
  <input id="newTitle" type="text" value="">
  <input id="newContent" type="text" value="">
  <button type="button" name="addElement" onclick="addElementClick()">Add</button>
</div>

或者,您可以保留 elements 数组的副本,并确保您同时删除条目的 DOM 结构删除条目,并且类似地确保并行完成添加,但是随后您正在编写代码来维护两个事物列表,这几乎不可避免地会导致更新一个而忘记更新另一个。各种“实时绑定”库试图通过让您维护您的元素数组然后基于它更新 DOM 来提供帮助,例如 Knockout、Vue、React、Angular 和其他十几个。 (有些非常简单,很容易融入任何项目;其他的则复杂得多,采用“你用我们的方式做你的应用程序”的方法。:-))对于任何不平凡的事情,可能值得看看类似的东西。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-21
    • 1970-01-01
    • 2020-03-22
    • 2019-06-27
    • 2016-05-17
    • 1970-01-01
    • 2015-10-26
    • 2021-07-29
    相关资源
    最近更新 更多