Jon
Jon

Reputation: 8531

JavaScript - How to surround block tags with span tag?

I want to surround a bunch of block tags (p, div) with my own span tag based on the selection of the user and I am wondering how to do it? I've looked into range.insertNode() and range.surroundNode() functions, but there's no way to pass it multiple nodes to surround.

My current implementation looks like this:

var selection = window.getSelection();

var range = selection.getRangeAt(0);
var $startSpan = $("<span class=\"SelectSpan\"/>");

range.insertNode($startSpan[0]);
range.surroundContents($startSpan[0]);

This works if the selection only contains one node (i.e. the user only selects part of a paragraph), but breaks if the user's selection traverses through multiple P's or Divs (among other tags, I'm sure).

As an example, consider the following DOM structure:

<div>
  <p>Hello there Mary</p>
  <p>Hello there Jake</p>
</div>

I would like to end up with something like the following if the user select parts from both paragraphs (Assume the user selects "there Mary Hello there"):

<div>
  <p>Hello <span>there Mary</span></p>
  <p><span>Hello there</span> Jake</p>
</div>

Upvotes: 1

Views: 829

Answers (2)

Tim Down
Tim Down

Reputation: 324607

You need to find all the text nodes within the selection range and surround each individually. I have written a library that does this: Rangy, specifically the CSS class applier module.

Upvotes: 1

Anthony Mills
Anthony Mills

Reputation: 8784

This can be a difficult problem because the range can encompass many different nodes at different levels in the DOM. (For instance, what if the user selects the last word of one paragraph and the first word of the next paragraph?) So you can't really think of inserting just one span. You might have to insert multiple ones.

One way I've solved this in the past is to issue a command to apply a fake font to the selection. Then I go through the DOM of the container looking for <font face="fakefont"> and I replace each one with my span tag. That tends to work well.

Upvotes: 1

Related Questions