Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > JavaScript: Общие вопросы > Своя реализация innerText для всех браузеров


Автор: Sardar 25.12.2004, 00:04
Иногда требуется достать текстовое содержимое ноды. В ИЕ и Опере есть не описанное в спецификации от 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

Добавленно:
Упс, я проглядел свойство textContent у нод в Мозилле, надобность в моём коде отпала ;-)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)