Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
260 views
in Technique[技术] by (71.8m points)

html - Jquery - Create multiple DOM elements inside a programmatically created parent element

I'm creating a data-driven list with jquery. I can't figure out how to add multiple children to a parent element using jQuery's method for creating HTML elements. What am I missing here?

I've re-organized the <a> elements inside the so they all can be a new element inside the rendered <td>. Instead it every "html" key overwrites the previous key and only the last "html" key and value are rendered. In this case the "a#deleteModal" element is the only one rendered.

This is what I need it to print:

<ul class="list-10" style="">
    <li data-info="line91" name="documentationmenunull">
        <table width="100%">
            <tbody>
                <tr>
                    <td>
                        <a href="#" data-toggle="dropdownArrow" data-target="documentationmenu1"><i class="fa fa-minus-square-o"></i></a> 
                        <a href="#" class="editItem" data-target="documentation_1" data-type="Documentation" id="adocumentationmenu1">Main</a> 
                        <a href="#deleteModal"><span class="fa fa-trash-o deleteMenuItem" rel="tooltip" title="" data-original-title="Delete"></span></a>
                    </td>
                </tr>
            </tbody>
        </table>
    </li>
</ul>

This is how I'm trying to accomplish that:

function getList(item, $list) {
  if (item) {
    if (item.title) {
      $list.append($("<li/>", {
        "name": "documentationMenu",
        "html": $("<table/>", {
          "width": "100%",
          "html": $("<tbody/>", {
            "html": $("<tr/>", {
              "html": $("<td/>", {
                "html": $("<a/>", {
                  "href": '#',
                  "data-toggle": "dropdownArrow",
                  "data-target": "documentationMenu" + item.id,
                  "html": $("<i/>", {
                    "class": "fa fa-minus-square-o"
                  }),
                }),
                "html": $("<a/>", {
                  "href": '#',
                  "data-toggle": "dropdownArrow",
                  "data-target": "documentation_" + item.id,
                  "data-type": "documentation",
                  "id": "aDocumentationMenu" + item.id,
                  "html": item.title
                }),
                "html": $("<a/>", {
                  "href": '#deleteModal',
                  "html": $("<span/>", {
                    "class": "fa fa-trash-o deleteMenuItem",
                    "data-toggle": "tooltip",
                    "title": "Delete"
                  })
                })
              })
            })
          })
        })
      }));
    }
    if (item.children) {
      var $sublist = $("<ul/>");
      $.each(item.children, function(key, value) {
        getList(value, $sublist);
      });
      $list.append($sublist);
    }
  }
}

Essentially you can ignore the last if block for item.children. I just need to figure out how to place several anchor tags inside the <td>. Any ideas?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I'm a big fan of avoiding putting HTML into my JavaScript. If I'm changing layout, I want to work with HTML and CSS, not javascript.

Make a template in your HTML, clone it, populate the clone and append it. We'll also use a doumentFragment so we don't repeatly update the DOM causing redraws.

var listItems = [{id: 1, title: "Main"}, {id:101, title: "Yellow Submarine"}];


function generateList(items, listElement) {
  //Set Up Template
  var s = $("#listItem")[0].innerHTML.trim(); 
  var holder = document.createElement('div');
  holder.innerHTML = s;
  var template = holder.childNodes;

  //Create doucument fragment 
  var frag = document.createDocumentFragment();
  
  //iterate the items
  items.forEach(function(item){
    //console.log(item)
    //Clone the template
    var newItem = $(template).clone();    
    //UPdate the data 
    newItem.html(newItem.html()
      .replace(/{{id}}/g, item.id)
      .replace(/{{title}}/g, item.title));
      //console.log(newItem.html());
    //Append to the fragment
    $(frag).append(newItem);
  }) ;

  //Append the fragment to the list
  $(listElement).append(frag);
}

generateList(listItems, $(".list-10"));
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="list-10" style="">    
</ul>

<template id="listItem">
    <li data-info="line91" name="documentationmenunull">
        <div>           
          <a href="#" data-toggle="dropdownArrow" data-target="documentationmenu{{id}}"><i class="fa fa-minus-square-o"></i></a> 
          <a href="#" class="editItem" data-target="documentation_{{id}}" data-type="Documentation" id="adocumentationmenu{{id}}">{{title}}</a> 
          <a href="#deleteModal"><span class="fa fa-trash-o deleteMenuItem" rel="tooltip" title="" data-original-title="Delete"></span></a>
          </div>
      </li>
</template>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...