Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript/jquery - Wrap text with tag at specific position

I have some text:

<p>hello world. This is a test paragraph.</p>

I want to add an <em> tag at start positions and </em> at end positions giving us:

<p>
  <em>hello</em> world. This is a <em>test</em> paragraph.
</p>

I have a list of start and end positions

<lst name="offsets">
  <int name="start">0</int>
  <int name="end">5</int>
  <int name="start">22</int>
  <int name="end">27</int>
</lst>

Is there an easy way of doing this?

Here is how I did it (slight modification of the answer):

var p = doc+=" "//document.querySelector("#content"),//I added a space to the end of the document because if we try to wrap the em tags around the word we are looking for and it is at the end of the document then it gives us undefined.
    textArray = p.split('');
    //offsets = [{ start: 0, end: 5 }, { start: 22, end: 27 }];

    offsets.forEach(function (offset) {    
    textArray[offset.start] = '<em>' + textArray[offset.start];
    textArray[offset.end] = '</em>' + textArray[offset.end];
});

document.querySelector("#content").innerHTML += textArray.join('');
document.querySelector("#content").innerHTML += "<hr>";
like image 691
Kevin Avatar asked Sep 14 '25 15:09

Kevin


2 Answers

Here is a simple example that doesn't require jQuery.

Example Here

Start with an offset array of objects to determine the start/end values.

[
  { start: 0, end: 5 },
  { start: 22, end: 27 }
]

Then iterate over the offset array:

var p = document.querySelector('p'),
    textArray = p.innerText.split(''),
    offsets = [{ start: 0, end: 5 }, { start: 22, end: 27 }];

offsets.forEach(function (offset) {    
    textArray[offset.start] = '<em>' + textArray[offset.start];
    textArray[offset.end] = '</em>' + textArray[offset.end];
});

p.innerHTML = textArray.join('');
<p>hello world. This is a test paragraph.</p>

If you would like to parse the list elements in order to create the offset array:

Example Here

var p = document.querySelector('p'),
    textArray = p.innerText.split(''),
    offsets = [];

Array.prototype.forEach.call(document.querySelectorAll('lst > int[name="start"]'), function (el) {
    offsets.push({start: el.innerText, end: el.nextElementSibling.innerText});
});

offsets.forEach(function (offset) {    
    textArray[offset.start] = '<em>' + textArray[offset.start];
    textArray[offset.end] = '</em>' + textArray[offset.end];
});

p.innerHTML = textArray.join('');
<p>hello world. This is a test paragraph.</p>

<lst name="offsets">
  <int name="start">0</int>
  <int name="end">5</int>
  <int name="start">22</int>
  <int name="end">27</int>
</lst>
like image 83
Josh Crozier Avatar answered Sep 16 '25 04:09

Josh Crozier


Would it be better to list the particular words you want to change?

var arr = ["hello", "test"];
$('p').html(function(i,html) {
    return html.split(/\s+/).map(function(u,j) {
        return arr.indexOf(u) > -1 ? '<em>' + u + '</em>' : u;
    })
    .join(' ');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p>
hello world. This is a test paragraph.
</p>
like image 25
PeterKA Avatar answered Sep 16 '25 05:09

PeterKA