除了一些之外如何剥离所有元素?

时间:2017-03-12 14:43:22

标签: javascript jquery

我正在生成<ul>和子<ul>,我想要做的是将列表的html结构只包含其值。使用以下代码,我进入文本区域的所有<ul>内容不仅仅是:

HTML

 <div id="mindMap">
   <ul class="list-unstyled margin-bottom-20">
      <li><button class="btn btn-default ul-appending margin-bottom-20">+ voce</button></li>
   </ul>
 </div> 

<div id="mindMapData">
  <textarea name="usp-custom-11" id="usp-custom-11" data-required="false" placeholder="Example Input 11" data-richtext="false" class="usp-input usp-textarea usp-form-365" rows="0" cols="30" style="margin: 0px; width: 871px; height: 291px;"></textarea>
</div>

的jQuery

$('body').on('click', 'button.ul-appending', function() {
  $(this).parent().append(
    $('<ul class="main_ul list-unstyled margin-bottom-20">').addClass('newul').append(
       $('<li class="margin-bottom-20"><div class="input-group margin-bottom-20"><input placeholder="Aggiungi una voce..." class="form-control" type="text"><div class="input-group-btn"><button type="button" class="btn btn-default list">+ sotto voce</button><button type="button" class="btn btn-default removeThis">elimina</button></div></div></li>')
        )
    );
});

$('body').on('click', 'button.list', function() {
    var newLi = '<ul class="sub_ul list-unstyled margin-bottom-20"><li class="listSub margin-bottom-20"><div class="input-group margin-bottom-20"><input placeholder="Aggiungi una sotto voce..." class="form-control" type="text"><div class="input-group-btn"><button type="button" class="btn btn-default list">+ sotto voce</button><button type="button" class="btn btn-default removeThis">elimina</button></div></div></li></ul>';
    var listEl = $(this).parent().parent().parent();
    $(listEl).append(newLi);
});

然后我检查html更改并将html插入textarea,如下所示:

$("#mindMap").on("DOMSubtreeModified",function(){
   $("#mindMapData textarea").val($("#mindMap").html());
});

在文本区域,我得到所有html tho:

<ul class="main_ul list-unstyled margin-bottom-20 newul">
  <li class="margin-bottom-20">
    <div class="input-group margin-bottom-20">
       <input placeholder="Aggiungi una voce..." class="form-control" type="text">
       <div class="input-group-btn">
         <button type="button" class="btn btn-default list">+ sotto voce</button>
         <button type="button" class="btn btn-default removeThis">elimina</button>
      </div>
   </div>
   <ul class="sub_ul list-unstyled margin-bottom-20">
     <li class="listSub margin-bottom-20">
       <div class="input-group margin-bottom-20">
         <input placeholder="Aggiungi una sotto voce..." class="form-control" type="text">
       <div class="input-group-btn">
         <button type="button" class="btn btn-default list">+ sotto voce</button>
         <button type="button" class="btn btn-default removeThis">elimina</button>
       </div>
     </div>
  </li>
</ul>

  

这里是working jsFiddle,看看textarea中的内容是错误的,我试图得到:

<ul>
  <li>Added node
    <ul>
      <li>Added sub node</li>
    </ul>
  </li>
 </ul>

2 个答案:

答案 0 :(得分:2)

您可以使用以下代码遍历DOM:

function ul(indent) {
  indent = indent || 4;
  var node = $(this);
    return node.removeAttr('class').children().map(function() {
    var self = $(this);
    var value = self.find('> .input-group input').val();
    var sub_ul = self.find('> ul');
    var ul_spaces = new Array(indent+4).join(' ');
    var li_spaces = new Array(indent).join(' ');
    if (sub_ul.length && ul) {
        return li_spaces + '<li>' + value + '\n' + ul_spaces +
          '<ul>\n' + ul.call(sub_ul, indent+8) + '\n' + ul_spaces + '<ul>\n' +
          li_spaces + '</li>';
    } else {
        return li_spaces + '<li>' + value + '</li>';
    }
  }).get().join('\n');
}

function updateTree() {
   $("#mindMapData textarea").val('<ul>\n' + $("#mindMap").clone().find('.main_ul').map(ul).get().join('\n') + '\n</ul>');
}

一方面注意你应该在每个输入的keyup上调用updateTree函数,因为当输入更改它的值时不会触发DOMSubtreeModified,请参阅update fiddle http://jsfiddle.net/44yb96Lb/72/

答案 1 :(得分:1)

我认为递归地解析DOM树并过滤掉不需要的标签更容易理解。看看:

/**
 * @param {array<string>} allowedTags A list of tags that are allowed in the output
 * @returns {function} A function that takes a jQuery elements and returns a copy with only the allowed elements
 */
function filterElementsFactory(allowedTags) {
    allowedTags = allowedTags.map(function (tag) { return tag.toUpperCase(); });

    /**
     * @param {object} element jQuery element
     * @returns {documentFragment}
     */
    return function filterElements(element) {
        element = element.clone();
        var elementList = element.contents();
        var finalElem = document.createDocumentFragment();
        for (element of elementList) {
            if (element.nodeType === Node.TEXT_NODE) {
                finalElem.appendChild(element);
            } else if (element.nodeType === Node.ELEMENT_NODE) {
                if (allowedTags.indexOf(element.tagName) !== -1) {
                    var elemFrame = document.createElement(element.tagName);
                    elemFrame.appendChild(filterElements($(element)))
                    finalElem.appendChild(elemFrame);
                } else {
                    finalElem.appendChild(filterElements($(element)));
                }
            } 
        };
        return finalElem;
    }
}

你可以这样使用:

var allowedTags = ['ul', 'li'];
var filterElements = filterElementsFactory(allowedTags);
$("#mindMap").on("DOMSubtreeModified",function(){
   var placeholderDiv = $('<div/>').append(filterElements($("#mindMap")));
   $("#mindMapData textarea").val(placeholderDiv.html());
});