JavaScript在div中查找动态字符串并将其包装起来

时间:2016-02-03 15:46:45

标签: javascript html angularjs

<div class="side">
    <a>Link 1</a>
    <a>Link 2</a>
    <input value="1"/>
      / 12
</div>

我有上述内容,并且我正在尝试弄清/ 12 <span> 12 var input = angular.element( document.querySelectorAll( '.side input')); angular.element(input).append('<span>'); 更改的内容。

我试过

<div class="side">
    <a>Link 1</a>
    <a>Link 2</a>
    <span class="page-count">
        <input value="1"/>
          / 12
    </span>
</div>

期望的结果

{{1}}

3 个答案:

答案 0 :(得分:1)

如果你想要包装一组元素(输入和“/ 12”文本节点),

wrap()单独将不起作用,因为它会单独包装每个元素。

您需要找到相关节点,即输入和文本节点,detach()来自DOM,append()它们到您的新范围,然后将范围附加到原始div。

您可以使用contents()添加文本节点,并按nodeType中所述检查this answer

的jQuery

使用完整的jQuery,这不是坏:

$('.side').append(function() {

    // create the span, add the detached nodes to it, then append to the container
    $('<span class="page-count"/>').append($(this).contents().filter(function(){

        // filter() contents down to textNodes and the input element, then detach() them all in one jQuery object
        return((this.nodeType === 3 && this.textContent.trim().length > 0)
            || (this.tagName && this.tagName.toUpperCase() === 'INPUT'))

    }).detach()).appendTo(this);

});

$('.side').append(function() {

    // create the span, add the detached nodes to it, then append to the container
	$('<span class="page-count"/>').append($(this).contents().filter(function(){

        // filter() contents down to textNodes and the input element, then detach() them all in one jQuery object
  	    return((this.nodeType === 3 && this.textContent.trim().length > 0)
    	    || (this.tagName && this.tagName.toUpperCase() === 'INPUT'))

    }).detach()).appendTo(this);

});
span.page-count {
  border:1px solid red;
  padding:5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class="side">
    <a>Link 1</a>
    <a>Link 2</a>
    <input value="1"/>
      / 12
</div>

使用jqLit​​e,它不是那么整洁。用$(this)替换angular.element(this)不起作用,即使jqLit​​e支持大多数这些jQuery函数。问题归结为filter()不受支持,这使得detach()一次性使用所有必要元素变得尴尬。

我通过将上面的陈述改为forEach()并一次分离/附加一个来解决这个问题:

// store the '.side' container
var sideElem = angular.element(document.querySelectorAll('.side'));
// create the new span
var pageCount = angular.element('<span class="page-count"/>');

// loop through contents of '.side'
angular.forEach(sideElem.contents(), function(val) {
    // if node matches, detach() it from '.side' and append() to the span
    if((val.nodeType === 3 && val.textContent.trim().length > 0)
        || (val.tagName && val.tagName.toUpperCase() === 'INPUT')) {
    pageCount.append(angular.element(val).detach());
  }
});

// add the span to the '.side' container
sideElem.append(pageCount);

// store the '.side' container
var sideElem = angular.element(document.querySelectorAll('.side'));
// create the new span
var pageCount = angular.element('<span class="page-count"/>');
    
// loop through contents of '.side'
angular.forEach(sideElem.contents(), function(val) {
    // if node matches, detach() it from '.side' and append() to the span
    if((val.nodeType === 3 && val.textContent.trim().length > 0)
        || (val.tagName && val.tagName.toUpperCase() === 'INPUT')) {
        pageCount.append(angular.element(val).detach());
    }
});
    
// add the span to the '.side' container
sideElem.append(pageCount);
span.page-count {
  border:1px solid red;
  padding:5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<div class="side">
    <a>Link 1</a>
    <a>Link 2</a>
    <input value="1"/>
      / 12
</div>

答案 1 :(得分:0)

我认为您可以使用nextSibling来实现这一目标。

它看起来像这样:

var input = angular.element( document.querySelectorAll( '.side input'));
var textNode = input.nextSibling();
angular.element(textNode).append('<span>');

虽然我并不完全确定,但我认为接近它应该做的事情。

答案 2 :(得分:-1)

var lastText = addDiv[0].childNodes;
var lastTextIndex = addDiv[0].childNodes.length;
angular.element( lastText[lastTextIndex-1]).wrap('<span class="page-count">')