Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 03.02.2011, 21:30
Интересующийся
Отправить личное сообщение для traa Посмотреть профиль Найти все сообщения от traa
 
Регистрация: 03.02.2011
Сообщений: 27

получение контента childNodes
Столкнулся с проблемой, которая, как оказалось, не так уж и тривиально решается.
Есть функция.

function mk_Selection(){ 
  var sel, output; 
  if (window.getSelection) { 
     sel = window.getSelection().getRangeAt(0).cloneContents(); 
  } else if (document.selection) { 
     sel = document.selection.createRange().htmlText; 
  }; 
 return sel;
}


Она берет выделенный фрагмент текста и возвращает его вместе со всей разметкой.
Одно НО!
Полученный результат невозможно вставить куда-то на страницу, поскольку он представляет собой объект Document Fragment.

Попытка получить его посредством
var st = mk_Selection();
 for (var i = 0; i < st.childNodes.length; i++) 
....

Успехом не увенчивается, поскольку у childNodes нет единого формата вывода, а перечислять все возможные виды тэгов и их атрибуты, чтобы сохранить разметку, - нереально.

Может, я что-то где-то пропустил, хотелось бы что-то в духе
var st = mk_Selection();
$(st).text();

(выводит только текст, без разметки, но нужно с разметкой, т.е. что-то типа $(st).html())

Иначе говоря, гуглю, да никак не нагуглю конвертацию чайлдНодов в стринг .

И, напоследок, вот как выглядит в консоли хрома полученный результат. Как бы его теперь из консоли вытащить в обычный хтмл?

Заранее благодарен.
Ответить с цитированием
  #2 (permalink)  
Старый 03.02.2011, 21:45
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,586

documentFragment - это элемент dom, и работа с ним протекает как и с любым другим элементом.
<html>
<head>
<script type="text/javascript">
function mk_Selection(){
  var sel, output;
  if (window.getSelection) {
     sel = window.getSelection().getRangeAt(0).cloneContents();
  } else if (document.selection) {
     sel = document.selection.createRange().htmlText;
  };
 return sel;
}
</script>
</head>
<body onkeypress="document.body.appendChild(mk_Selection())">   
<div>Выделите<b> кусок текста</b> и <i>нажмите</i> любую <u>клавишу</u></div>
</body>
</html>


Кстати в случае ie у вас выдаётся просто строка, так что вам надо определиться с удобным вам вариантом, чтобы функция возвращала универсальный ответ.

Последний раз редактировалось Aetae, 03.02.2011 в 21:51.
Ответить с цитированием
  #3 (permalink)  
Старый 04.02.2011, 00:14
Интересующийся
Отправить личное сообщение для traa Посмотреть профиль Найти все сообщения от traa
 
Регистрация: 03.02.2011
Сообщений: 27

Спасибо большое.

Подскажите пожалуйста, как лучше проверить результат работы функции mk_Selection() на пустоту? Т.е. если ничего не выделено, либо выделен пробел.

Особенно важен первый вариант, т.к. событие показа менюшки, которая появляется по окончании выделения вешается на mouseup, что приводит при любом клике к появлению меню, в то время как меню должно появляться только при не пустом выделении

P.S.: Разумеется, на обычный $.trim проверять объект нет смысла.

Последний раз редактировалось traa, 04.02.2011 в 00:56.
Ответить с цитированием
  #4 (permalink)  
Старый 04.02.2011, 01:03
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,586

var s=mk_Selection()
//Если строка то:
if(s){ ... }
//Если дом элемент то:
if(s.firstChild){ ... }

Надо только определиться таки что должна возвращать функция.
Ответить с цитированием
  #5 (permalink)  
Старый 04.02.2011, 11:24
Интересующийся
Отправить личное сообщение для traa Посмотреть профиль Найти все сообщения от traa
 
Регистрация: 03.02.2011
Сообщений: 27

Снова большое спасибо за ответ, действительно, все хорошо при определение на присутствие выделения, но как проверить то же выделение на $.trim к примеру? Обращение напрямую к firstChild не помогает что-то, вернее, помогает только в консоли.

Т.е. эта конструкция не дает желаемого результата, выделенный пробел по-прежнему проходит условие.
if (st.firstChild && $.trim(st.firstChild)!='')


А насчет того, что возвращает функция, - не подскажете, как заставить ИЕ отдавать подобный объект?

И конечно же, большое спасибо Вам за своевременную помощь!
Ответить с цитированием
  #6 (permalink)  
Старый 04.02.2011, 11:36
Интересующийся
Отправить личное сообщение для traa Посмотреть профиль Найти все сообщения от traa
 
Регистрация: 03.02.2011
Сообщений: 27

как один из вариантов написал следующий костыль.
if ((st.firstChild && st.firstChild.nodeType==3 && $.trim(st.firstChild.nodeValue)!='' && st.childNodes.length==1) || 
 st.childNodes.length>1 ||
 	 (st.firstChild && st.firstChild.nodeType==1))


- Проверяем на наличие вообще firstChild
- Тип ноды у пробелов будет всегда равен текстовой ноде, т.е. троечке, что разумно вроде как.
- Если мы знаем тип нода, то мы можем обратиться к его свойству nodeValue
- чтобы в наше условие не попадали выделения у которых в начале стоит пробела, а затем идут другие ноды, ограничиваем область вхождения только одноНодовым выделением
- альтернативное условие - если несколько нодов, то текст нам подходит, т.к. пробелы разбиваться на несколько нодов явно не будут (правда, будут пробелы с тэгами, в которых пустоты или пробелы. да)
- альтернативное условие - при типе чайлдНода равного тэгу - всегда пропускаем, думаю, там нет нужды фильтровать.

Последний раз редактировалось traa, 04.02.2011 в 13:27.
Ответить с цитированием
  #7 (permalink)  
Старый 04.02.2011, 14:27
Интересующийся
Отправить личное сообщение для traa Посмотреть профиль Найти все сообщения от traa
 
Регистрация: 03.02.2011
Сообщений: 27

правда, при усиленных тестах видно, что такие хитрые условия не спасают особо.
Есть у кого варианты, как проверять и избавляться от пробелов в выделении? ( когда выделены только пробелы или пустоты)
Ответить с цитированием
  #8 (permalink)  
Старый 04.02.2011, 20:25
Интересующийся
Отправить личное сообщение для traa Посмотреть профиль Найти все сообщения от traa
 
Регистрация: 03.02.2011
Сообщений: 27

Один из наиболее простых и вроде как работающих вариантов, -
var s=mk_Selection();

if ($(s).text().trim()!='')
{
//do something
}
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Прелоад полученного контента Check'Yr'Head AJAX и COMET 5 30.09.2010 11:37
Переодическое получение ответа от сервера demoniqus AJAX и COMET 6 22.06.2010 16:09
Скролл окна при добавлении контента "сверху"" yaneblog Events/DOM/Window 0 22.01.2010 23:00
Динамическое изменение контента со скроллом Accessd Элементы интерфейса 0 03.10.2009 17:34
childNodes не работает :( mirniy Общие вопросы Javascript 3 16.01.2009 11:59