Модераторы: Sardar, Aliance
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Своя реализация innerText для всех браузеров, Как вытащить только текст из ноды 
:(
    Опции темы
Sardar
Дата 24.12.2004, 23:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 78
Всего: 317



Иногда требуется достать текстовое содержимое ноды. В ИЕ и Опере есть не описанное в спецификации от W3C поле innerText через которое можно достать/установить текст из/в ноды(у). В Мозиллоподобных браузерах и просто экзотических такого поля нет. Согласно идее от W3C можно пробежатся по списку нод и самому собрать содержимое, что мы и сделаем:
HTML
<div id="test">This <span style="color:red">is</span>&nbsp;<span style="background-color: #7495f6; color: #0b451b; font-weight: bold">a <a href="#">Test</a></span></div>

Код
/**
* Функция достает текстовое содержимое любой ноды. Текстом будем считать
* текстовые ноды и элементы, которые опрашиваем рекурсивно.
*/
function innerText(node) {
//  return node.innerText; //хорошая вещь в ИЕ
//  return node.innerHTML; //из стадарта W3C, но не совсем то что нужно
 var ret = "";
 for(var i=0; i<node.childNodes.length; i++) {
    switch(node.childNodes[i].nodeType) {
   case 1: ret+=innerText(node.childNodes[i]); break; //если элемент
   case 3: ret+=node.childNodes[i].nodeValue; //если текстовая нода
 }
 }
 return ret;
}
alert(innerText(document.getElementById("test")));


Решение рабочее, можно использовать под любым браузером. Но можно пойти дальше, используя механизм getter/setter Мозиллоподобных можно определить свойства для нод:
Код

/*
* Ниже мы используем особый механизм геттеров/сеттеров берущих свои корни еще
* с нетскейповских времён.
*/
//избавляемся от глючной но поддерживающей innerText Оперы
//бродилка имеет Node, но не имеет Node.prototype - бред... =/
if(typeof(Node)!="undefined"&&typeof(Node.prototype)!="undefined"&&typeof(Node.prototype.__defineGetter__)=="function") {  Node.prototype.__defineGetter__("innerText", function()
 {
    var ret = "";
    for(var i=0; i<this.childNodes.length; i++) {
       switch(this.childNodes[i].nodeType) {
         case 1: ret+=this.childNodes[i].innerText; break; //если элемент
      case 3: ret+=this.childNodes[i].nodeValue; break; //если текст
    }
    } return ret;
 });
 
 Node.prototype.__defineSetter__("innerText", function(val)
 {
//и не пытайтесь использовать removeChild, Мозиллу глючит по чёрному
//уж лучше так... через innerHTML =/
   this.innerHTML=""; //очищяем содержимое
   this.appendChild(document.createTextNode(val));
 });
}

var a=document.getElementById("test");
alert(a.innerText);
a.innerText="Vingrad";

Заметим что кот будет работать хорошо только в Опере, ИЕ и Мозилле, так как первые два проигнорируют конструцию, а Мозилла получит новое свойство в интерфейс нод. Особые экзотические браузеры возможно работать не будут, но это не страшно, т.к. 95% народа мы удовлетворим smile


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
mix
Дата 30.12.2004, 20:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 46
Регистрация: 23.2.2003

Репутация: нет
Всего: 1



В догонку:
в мозилле есть похожее на innerText свойство textContent
PM MAIL   Вверх
Sardar
Дата 30.12.2004, 21:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 78
Всего: 317



mix полезное замечание, в Мозилле есть полный эквивалент innerText в IE - textContent, юзаем также как и в ИЕ.
Похоже что вопрос окончательно исчерпан, в моём коде нет нужды.


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
Се ля ви
Дата 2.1.2005, 15:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Java/SOAрхитектор
****


Профиль
Группа: Модератор
Сообщений: 2016
Регистрация: 5.6.2004
Где: place without tim e and space

Репутация: 5
Всего: 127



Цитата(Sardar @ 30.12.2004, 21:05)
Мозилле есть полный эквивалент innerText в IE - textContent

Концептуальный вопрос - а в стандарте W3C это свойство есть?

Тогда изменим патчовый скрипт Sardar`а, что бы делать минимум изменений в коде:
Код
/*
* Ниже мы используем особый механизм геттеров/сеттеров берущих свои корни еще
* с нетскейповских времён.
*/

// Избавляемся от глючной но поддерживающей innerText Оперы - бродилка имеет Node, но не имеет Node.prototype - бред... =/
if ( typeof(Node) != "undefined" &&
    typeof(Node.prototype) != "undefined" &&
    typeof(Node.prototype.__defineGetter__) == "function" ) {
   
    Node.prototype.__defineGetter__(
         "innerText",
         function() { return this.textContent; }
    );
 
    Node.prototype.__defineSetter__(
         "innerText",
         function(val) {
              //И не пытайтесь использовать removeChild, Мозиллу глючит по чёрному, уж лучше так - через innerHTML =/
              this.textContent =""; //очищяем содержимое
              this.appendChild(document.createTextNode(val));
         }
    );
}

var a=document.getElementById("test");
alert(a.innerText);
a.innerText="Vingrad";


P.S. Очень странно, что Mozilla не принимает removeChild - это часть уже старого DOM level 1 - уж его-то она обязана поддерживать. Можешь отловить её ошибку через try..catch и прочитать сообщение?


--------------------
  )
 (
[_])
проф. блог

Кролики думали, что занимаются любовью, а на самом деле их просто разводили...
PM MAIL WWW Skype GTalk   Вверх
Sardar
Дата 2.1.2005, 16:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 78
Всего: 317



Се ля ви устанавливать текст через textContent тоже можно, так что можем ипользовать this.textContent=val;.

В стандартах этого свойства нет, т.к. оно составное, т.е. рекурсивно должно пробегать по всем нодам-потомкам. Для скриптов это очень актуально, т.к. много писать не хочется. Для какого нибудь АПИ для XML это не особо нужно, ибо с базовых возможностей можешь намутить что нибудь своё.

Цитата
P.S. Очень странно, что Mozilla не принимает removeChild - это часть уже старого DOM level 1 - уж его-то она обязана поддерживать. Можешь отловить её ошибку через try..catch и прочитать сообщение?

Нет, removeChild работает, просот в этом контексте почему то Мозилла проглючила... smile


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Форум для вопросов, которые имеются в справочниках, но их поиск вызвал затруднения, или для разработчика требуется совет или просьба отыскать ошибку. Напоминаем: 1) чётко формулируйте вопрос, 2) приведите пример того, что уже сделано, 3) укажите явно, нужен работающий пример или подсказка о том, где найти информацию.
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | JavaScript: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0693 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.