如何用span打包标题的第一个单词

时间:2016-07-30 10:14:04

标签: javascript

我想实现something similar,但要用<h1>标记包装每个<span>标记的第一个单词。它应该是这样的:

 <h1><span>This</span> is a title</h1>

我认为没有插件就可以实现......

3 个答案:

答案 0 :(得分:1)

使用JavaScript String#repalce 方法

&#13;
&#13;
var tag = document.querySelector('h1');

tag.innerHTML = tag.innerHTML.replace(/^\s*\w+/, '<span style="color:red">$&</span>');
&#13;
<h1>This is a title </h1>
&#13;
&#13;
&#13;

FYI:由于它会重新创建内部元素,因此会破坏附加到其后代元素的任何处理程序。

更新:如果您要更新所有h1代码,则需要获取所有h1并对其进行迭代。

&#13;
&#13;
Array.from(document.querySelectorAll('h1')).forEach(function(ele) {
  ele.innerHTML = ele.innerHTML.replace(/^\s*\w+/, '<span style="color:red">$&</span>');
});
&#13;
<h1>This is a title </h1>
<h1>This is a title </h1>
<h1>This is a title </h1>
<h1>This is a title </h1>
<h1>This is a title </h1>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

真诚的,这项任务非常困难!好问题! 顺便说一下,我认为可接受的解决方案可能如下: 我取代了所有h1标签的第一个单词而没有丢失听众...... 希望它有所帮助!

function WrapFirstH1WordCtrl() {
  let titles = this.querySelectorAll("h1");
  let test = this.getElementById('test');
  
  test.onclick = () => console.log("HELLO GUYS");
  
  
  Array.prototype.forEach.call(titles, (title) => {
    let value = title.firstChild.nodeValue;
    let t = /^(\w+)/.exec(value).pop();
    let span = this.createElement('span');
    span.innerHTML = t || "";
    
    title.firstChild.nodeValue = value.replace(t, "")
    title.insertBefore(span, title.firstChild);
    
  });
  
}
document.addEventListener('DOMContentLoaded', WrapFirstH1WordCtrl.bind(document))
span {
  background: lightseagreen;
}
<h1>foo 1 <button id="test">HELLO AND KEEP LISTENERS</button></h1>
<h1>foo 2</h1>
<h1>foo 3</h1>
<h1>foo 4</h1>
<h1>foo 5</h1>
<h1>foo 6</h1>
<h1>foo 7</h1>
<h1>foo 8</h1>
<h1>foo 9</h1>
<h1>foo 10</h1>
<h1>foo 11</h1>
<h1>foo 12</h1>
<h1>foo 13</h1>
<h1>foo 14</h1>
<h1>foo 15</h1>
<h1>foo 16</h1>
<h1>foo 17</h1>
<h1>foo 18</h1>
<h1>foo 19</h1>
<h1>foo 20</h1>
<h1>foo 21</h1>
<h1>foo 22</h1>
<h1>foo 23</h1>
<h1>foo 24</h1>
<h1>foo 25</h1>
<h1>foo 26</h1>
<h1>foo 27</h1>
<h1>foo 28</h1>
<h1>foo 29</h1>
<h1>foo 30</h1>

答案 2 :(得分:0)

这可能是一种选择。不是很优雅,但应该做的工作。如果我没有误会,这应该仅影响textNode元素的第一个h1。其余的只是在现有元素之前插入创建的span,而不影响后代元素。如果我错了,请纠正我。 ;)

var titles = document.querySelectorAll('.title');

titles.forEach(function(e) {
  var childNodes = [].slice.call(e.childNodes),
      txtContent = childNodes.shift().textContent, 
      span;
  e.childNodes[0].textContent = '';
  txtContent.split(' ').forEach(function(s, i) {
    if(i > 0) {
      e.insertBefore(document.createTextNode(" " + s), e.children[1]);
    } else {
      span = document.createElement('span');
      span.textContent = s;
      e.insertBefore(span, e.firstChild);
    }
  })
})
span {
  color: red;
}

.baz {
  color: green;
}
<h1 class="title">Hello World</h1>
<h1 class="title">Hello Foo Bar <span class="baz">Baz</span></h1>