jQuery - обтекание <span> вокруг выделенного текста - ошибка дублирующегося экземпляра
Этот вопрос относится к аналогичному вопросу, заданному здесь о том, как применить тег к выделенному тексту. На вопрос был дан ответ, но у этого ответа был один существенный недостаток, заключающийся в том, что если тот же текст, который выбран, существует в другом месте документа, <span>
оборачивает дубликат, а не рассматриваемый текст.
Я понимаю, что это может быть против какого-либо протокола stackru, но я публикую здесь без реального понятия о том, как действовать дальше. Моим лучшим предположением было бы как-то найти длину строки перед выделенным текстом (что-то вроде этих строк), но как включить это в саму функцию замены... ну, я мог бы использовать толчок. Кто-нибудь?
(Я вставил решение к предыдущему посту (от Mathias Bynens) ниже.)
$("p").live("mouseup",function() {
selection = getSelectedText();
if(selection.length >= 3) {
var spn = '<span class="selected">' + selection + '</span>';
$(this).text($(this).html().replace(selection, spn));
}
});
//Grab selected text
function getSelectedText(){
if(window.getSelection){
return window.getSelection().toString();
}
else if(document.getSelection){
return document.getSelection();
}
else if(document.selection){
return document.selection.createRange().text;
}
}
3 ответа
Я обманул и использовал document.execCommand, чтобы обернуть выделенный текст, затем использовал href (третий параметр CreateLink execCommand), чтобы найти элемент, обернуть его тем, что я хотел, и затем удалить ссылку:
$("p").live("mouseup",function() {
document.execCommand('CreateLink', false, 'uniqueid');
var sel = $('a[href="uniqueid"]');
sel.wrap('<span class="selected" />')
sel.contents().unwrap();
});
document.execCommand поддерживается всеми основными браузерами, поэтому вы должны безопасно взломать его таким образом. В протестированных мною браузерах сам браузер закрывает и открывает для вас теги, поэтому, если вы выбираете от середины одного тега html до середины другого, он должен правильно вкладывать теги.
Я думаю, что ваш ключ в том, чтобы выяснить, что возвращает getSelection и работать с этим.
На Firefox я смог сделать это:
$(document.getSelection().anchorNode).wrap('<div style="color:blue">')
У document.selection.createRange() должна быть похожая вещь, которая позволяет вам найти вещь, которая была выбрана.
так что-то вроде:
$("p").live("mouseup",function() {
var $sel = getSelectedElem();
if($.trim($sel.text()).length >= 3) {
$sel.warp('<span class="selected">');
}
});
//Grab selected text
function getSelectedElem(){
if(window.getSelection){
return $(window.getSelection().anchorNode);
}
else if(document.getSelection){
return $(document.getSelection().anchorNode)
}
else if(document.selection){
//todo figure out what to return here:
return document.selection.createRange().text;
}
return $([]);
}
Как насчет этого?
document.execCommand("insertHTML", false, "<span class='own-class'>"+ document.getSelection()+"</span>");