Erlend Jones
Erlend Jones

Reputation: 15

Javascript split by spaces, but not within html-tags

My first goal is to split a string by spaces, but not the ones within html-tags.

I've tried to rewrite the following, unsuccessfully: Javascript split by spaces but not those in quotes

What would the regex look like in: arr = fullHtmlString.split(?); ?


My main goal is to shift an IMG-tag by one space at a time. After that I'll iterate over the array, search for the img-tag, remove it, and add it the next item, and finally join the array.

The code I use at the moment is quite comprehensive and use jQuery extensively to achive the goal.

Input:

<div>
    <p><img class=something>Some text.</p>
    <p>Some more text.</p>
</div>

Deisred output first time:

<div>
    <p>Some<img class=something> text.</p>
    <p>Some more text.</p>
</div>

...second time:

<div>
    <p>Some text.<img class=something></p>
    <p>Some more text.</p>
</div>

...third time:

<div>
    <p>Some text.</p>
    <p><img class=something>Some more text.</p>
</div>

Upvotes: 1

Views: 1212

Answers (1)

Patrick Evans
Patrick Evans

Reputation: 42736

You should not try to do this with a regular expression, why explained here.

You can use DOM properties and methods though

function run(){
  var img  = document.querySelector(".something"),
   sibling = img,
   parent  = img.parentNode,
   next    = parent.nextElementSibling;

  //Search for the next textNode
  while((sibling = sibling.nextSibling) && sibling.nodeType !=3);

  if(sibling) {
    //split the text only once, 
    //so "some more text" becomes ["some","more text"]
    var textParts = sibling.textContent.split(/ (.*)?/,2);

    //put the first split item before the sibling
    parent.insertBefore(document.createTextNode(textParts[0]+" "),sibling);

    //replace the sibling with the img element
    parent.replaceChild(img,sibling);

    //finally if there was more text insert it after the img
    textParts[1] && parent.insertBefore(document.createTextNode(textParts[1]),img.nextSibling);    
  } else if(!sibling && next) {
    //no sibling in the current parent, 
    //so prepend it to the next available element in parent
    next.insertBefore(img,next.firstChild);
  } else {
    clearInterval(timer);
  }
}

var timer = setInterval(run,2000);
<div>
    <p><img class="something" src="http://placehold.it/10x10">Some text.</p>
    <p>Some <span>skip me</span> more text.</p>
</div>

Upvotes: 2

Related Questions