2012-02-26 2 views
1

Я хочу окружить кучу блочных тегов (p, div) своим тегом span на основе выбора пользователя, и мне интересно, как это сделать? Я просмотрел функции range.insertNode() и range.surroundNode(), но нет возможности передать ему несколько узлов для окружения.JavaScript - Как окружить теги блоков тегом span?

Моя текущая реализация выглядит следующим образом:

var selection = window.getSelection(); 

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

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

Это работает, если выделение содержит только один узел (т.е. пользователь выбирает только часть абзаца), но перерывы, если выбор пользователя проходит через многократный P-х или Divs (среди прочих тегов, я уверен).

В качестве примера рассмотрим следующую DOM структуру:

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

Я хотел бы, чтобы в конечном итоге с чем-то вроде следующего, если пользователю выбрать части из обоих пунктов (Предположим, что пользователь выбирает «там Мэри Привет »):

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

Подождите, вы используете jQuery? – Blender

+0

Вы, кажется, используете jQuery, хотя вы не отметили вопрос как таковой, поэтому вы можете посмотреть http://api.jquery.com/wrapAll/ – nnnnnn

+0

wrapAll точно не решает проблему как пользователь может выбрать только часть абзаца/предложения, а не обязательно весь узел. – Jon

ответ

1

Вам нужно найти все текстовые узлы в пределах диапазона выбора и окружить каждый отдельно. Я написал библиотеку, которая делает это: Rangy, в частности CSS class applier module.

+0

Хорошо, что я написал это! Хотелось бы, чтобы у меня было что-то подобное, когда я писал свой редактор еще в 2005 году. –

+0

@ AnthonyMills: Я тоже: я написал некоторые ужасные вещи для моего редактора прерывистого редактора середины 2000-х годов. –

1

Это может быть сложной проблемой, поскольку диапазон может охватывать множество разных узлов на разных уровнях DOM. (Например, что, если пользователь выбирает последнее слово из одного абзаца и первое слово следующего абзаца?) Таким образом, вы не можете думать о вставке только одного span. Возможно, вам придется вставить несколько.

Один из способов, которым я решил это в прошлом, - выдать команду для применения поддельного шрифта к выбору. Затем я просматриваю DOM контейнера, ищущего <font face="fakefont">, и я заменяю каждый свой тег span. Это работает хорошо.

+0

Можете ли вы подробнее рассказать о том, как применить поддельный шрифт к выбору? – Jon

+0

Вы бы сделали что-то вроде 'range.execCommand (" fontname ", false," fakefont ");'. –

Смежные вопросы