【问题标题】:How do I dynamically populate html elements with JSON Data with Javascript not jQuery?如何使用 Javascript 而不是 jQuery 使用 JSON 数据动态填充 html 元素?
【发布时间】:2012-01-09 00:37:19
【问题描述】:

我有以下 JSON 数据片段:

{"items": [
 {
   "title": "sample 1",
   "author": "author 1"
 },
 {
  "title": "sample 2",
  "author": "author 2"
 }
]}

如何使用这些数据填充以下 html 元素:

<div class="news-story">
 <h5>sample 1</h5>
 <p>By: author 1</p>
 <h5>sample 2</h5>
 <p>By: author 2</p>
</div>

我想用 Javascript 而不是 jQuery 来完成这项工作。

【问题讨论】:

  • 你为什么不想使用 jQuery?这对我来说似乎是一个更大的问题。
  • 如果你把class改成id我会写的:D
  • @ajax81 对 JavaScript 有深刻理解的人会知道 DOM 功能非常糟糕且跨浏览器不一致,并且会使用跨平台高效且一致的解决方案。它们并不相互排斥。 jQuery 只是简化和扁平化了 JS 的 DOM 操作部分。
  • @SamStriano:因为它经常是矫枉过正。使用本机 API 没有任何问题。
  • @Sam -- 因为太多时候 JavaScript 问题是用 JQuery 的大锤子来回答的,而此时只需要一把十字螺丝刀。 JSON的。或者……什么。

标签: javascript html json


【解决方案1】:
$(document).ready(function () {
    loadfunctionAjax();
});
var loadfunctionAjax = function () {
    $.ajax({
        type: 'GET',
        url: '/Site/SocialLink',
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function (data) {
            var HTML = '';
            for (var i = 0; i < data.length; i++) {
                item = data[i];
                HTML += '<li><a class="" target="_blank" href="' + item.FALink + '"><i class="fa ' + item.FAIcon + '"></i>' + item.Name + '</a ></li > ';
            }
            $('#footerSocialNav').append(HTML);
        }
    });
}

【讨论】:

    【解决方案2】:

    尝试 JsRender 和 JsViews 或小胡子/ember

    【讨论】:

      【解决方案3】:

      迟到总比没有好...我最近做了一个库来做这个!

      FragBuilder 是库.. 用法非常简单:对于您发布的示例,您需要稍微更改 JSON 以使其更具语义...

      var frag = [{"items": [
       {
         "title": "sample 1",
         "author": "author 1"
       },
       {
        "title": "sample 2",
        "author": "author 2"
       }
      ]}];
      

      会变成

      var frag = [ { "childNodes" : [ { "childNodes" : [ { "textContent" : "sample 1" } ],
                "tagName" : "H5"
              },
              { "childNodes" : [ { "textContent" : "By: author 1" } ],
                "tagName" : "P"
              },
              { "childNodes" : [ { "textContent" : "sample 2" } ],
                "tagName" : "H5"
              },
              { "childNodes" : [ { "textContent" : "By: author 2" } ],
                "tagName" : "P"
              }
            ],
          "className" : "news-story",
          "tagName" : "DIV"
        } ];
      

      然后你会通过调用FragBuilder(frag)来生成一个DocumentFragment

      如果您发现使用 HTML 模板然后转换为 JSON https://gist.github.com/2313580 更容易,还有一个反向功能(注意,标签之间的空白不处理,会导致失败)

      【讨论】:

        【解决方案4】:
        var div = document.getElementsByClassName('news-story')[0],
            h5 = div.getElementsByTagName('h5'),
            p = div.getElementsByTagName('p'),
            data = JSON.parse( my_JSON_data );
        
        data.items.forEach(function(v,i) {
            h5[i].innerHTML = v.title;
            p[i].innerHTML = "By: " + v.author;
        });
        

        JSFIDDLE DEMO


        如果需要支持旧版浏览器,可以使用典型的for 语句代替forEach 方法。

        for( var i = 0; i < data.items.length; ++i ) {
            var v = data.items[i];
            h5[i].innerHTML = v.title;
            p[i].innerHTML = "By: " + v.author;
        }
        

        我建议为 news-story 元素使用 ID 而不是类,因此您可以使用 getElementById 代替 (当然,除非您有多个)。 p>

        如果这不可能,您可能需要使用兼容函数from MDN 来替换getElementsByClassName


        如果您需要创建内部元素,那么这是一种方法:

        var div = document.getElementsByClassName('news-story')[0],
            data = JSON.parse( my_JSON_data ),
            html;
        
        html = data.items.map(function(v,i) {
            return '<h5>' + v.title + '</h5>' +
                   '<p>By: ' + v.author + '</p>';
        }).join('');
        
        div.innerHTML = html;
        

        JSFIDDLE DEMO


        @Xeon06 在他的回答中展示了如何使用createElement(),这可以说是一种更好的方法。

        我会这样做:

        var div = document.getElementsByClassName('news-story')[0],
            frag = document.createDocumentFragment(),
            data = JSON.parse( my_JSON_data );
        
        data.items.forEach(function(v,i) {
            frag.appendChild( document.createElement('h5') ).innerHTML = v.title;
            frag.appendChild( document.createElement('p') ).innerHTML = "By: " + v.author;
        });
        div.appendChild( frag );
        

        JSFIDDLE DEMO

        当然,您可以修改它以使用 for 语句代替:

        var div = document.getElementsByClassName('news-story')[0],
            frag = document.createDocumentFragment(),
            data = JSON.parse( my_JSON_data );
        
        for( var i = 0; i < data.items.length; ++i ) {
            var v = data.items[i];
            frag.appendChild( document.createElement('h5') ).innerHTML = v.title;
            frag.appendChild( document.createElement('p') ).innerHTML = "By: " + v.author;
        }
        div.appendChild( frag );
        

        使用documentFragment 的好处是您可以通过片段而不是多个附加来对DOM 进行一次附加。这样可以提供更好的性能,尤其是在您拥有大量数据的情况下。

        【讨论】:

        • 请注意,遗憾的是,forEach 上不可用
        • @Xeon06:getElementsByClassName 也不是。
        【解决方案5】:

        没有 jQuery 的示例:

        <html>
            <head>
                <title>test</title>
            </head>
            <body>
               <div class="news-story">
                    <h5>sample 1</h5>
                    <p>By: author 1</p>
                    <h5>sample 2</h5>
                    <p>By: author 2</p>
                </div> 
                <script type="text/javascript">
                    var json = {
                        "items": [
                            {
                            "title": "sample x",
                            "author": "author x"
                            },
                            {
                            "title": "sample y",
                            "author": "author y"
                            }
                        ]
                    };
        
                    var bindDataToHTML = function(data, element) {
                         var h5 = null;
                         var p = null;
                         h5 = element.getElementsByTagName("h5");
                         p  = element.getElementsByTagName("p");
                         h5[0].innerText = data.items[0].title;
                         h5[1].innerText = data.items[1].title;
                         p[0].innerText = data.items[0].author;
                         p[1].innerText = data.items[1].author;
                    };
        
                    document.getElementsByClassName = function(cl) {
                        var retnode = [];
                        var myclass = new RegExp('\\b'+cl+'\\b');
                        var elem = this.getElementsByTagName('*');
                        for (var i = 0; i < elem.length; i++) {
                            var classes = elem[i].className;
                            if (myclass.test(classes)) { retnode.push(elem[i]); }
                        }
                        return retnode;
                    };
        
                    // For sample purpose, let's imagine this method is a callback
                    // for a request that provides you with your json data
                    var doRequest = function() {
                        var data = json;
                        var element = null;
        
                        var x = document.getElementsByClassName("news-story");
        
                        if((null != x) && (0 < x.length)) {
                            element = x[0];
                        }
                        bindDataToHTML(data, element);
                    };
        
                    (function() {
                        doRequest();
                    })();
        
                </script>
            </body>
        </html>
        

        【讨论】:

          【解决方案6】:

          遍历它们并使用DOM 函数:

          var news = document.getElementsByClassName("news-story")[0];
          var items = json.items;
          for(var i = 0; i < items.length; i++) {
              var h5 = document.createElement("h5");
              h5.innerHTML = items[i].title;
              news.appendChild(h5);
              var p = document.createElement("p");
              p.innerHTML = items[i].author;
              news.appendChild(p);
          
          }
          

          http://jsfiddle.net/AWRAW/

          getElementsByClassName 不能在 IE 9 之前的版本中工作。如果你需要支持这些,你最好使用 jQuery。

          【讨论】:

          • 为了向后兼容 w/o jQuery ,他可以选择添加一个 ID 属性和 getElementById() 代替。
          • var news = document.querySelector(".news-story")[0];
          • @poashoas 这行不通,因为querySelector 不返回一个数组,而是一个元素。所以你不能在之后做[0]。您可以使用querySelectorAll 或使用您当前的代码,只需在最后省略数组调用。
          【解决方案7】:

          我发现创建 DOM 元素最可靠的方法是使用 element.innerHTML 属性。基本上,您将在页面上要呈现新 HTML 的地方有一个 DIV 或 SPAN。然后,您将使用document.getElementById("DIV-ID") 在javascripting 中获取该范围,然后将DIV 的innerHTML 属性设置为您将从JSON 对象生成的新HTML。还有很多其他的 JavaScript 函数可以创建元素,但我发现它们并不总是可靠的,并且并不总是具有最好的跨浏览器支持。

          http://www.w3schools.com/jsref/prop_html_innerhtml.asp

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-10-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-08-17
            • 1970-01-01
            相关资源
            最近更新 更多