Попробовал nodeValue. Он тоже не подходит т. к. экранирует теги как innerText. Вот:
var TextNode = { each: function(callback, parent) { for (var childNodes = (parent || document.body).childNodes, i = 0, length = childNodes.length; i < length; i++) { var I = childNodes[i]; I.nodeType == 1 ? arguments.callee(callback, I) : I.nodeType == 3 && callback(I, i); } } }; window.onload = function() { TextNode.each(function(noda) { noda.nodeValue = noda.nodeValue.replace(/(http\:\/\/www\.youtube\.com\/watch\?v\=[0-9a-z]{11})/gi, '<a href="$1">$1</a>'); }); }; Или я что то не так делаю? |
Получилось через replaceChild:
var TextNode = { each: function(callback, parent) { for (var childNodes = (parent || document.body).childNodes, i = 0, length = childNodes.length; i < length; i++) { var I = childNodes[i]; I.nodeType == 1 ? arguments.callee(callback, I) : I.nodeType == 3 && callback(I, i); } } }; window.onload = function() { TextNode.each(function(noda) { var elem = document.createElement('div'); elem.innerHTML = noda.nodeValue.replace(/(http\:\/\/www\.youtube\.com\/watch\?v\=[0-9a-z]{11})/gi, '<a href="$1">$1</a>'); noda.parentNode.replaceChild(elem, noda); }); }; |
Цитата:
я не уверен, насчет replaceChild и его кросбраузерности. не проверял. я лично в таком случае использовал insertBefore и removeChild текстовые ноды могут быть не только у body-элемента. они могут быть потомками любого тега, поэтому надо получить всю коллекцию, и для всех тегов перебрать, например |
Riim, а зачем ты div создаешь? Во-первых, ты добавляешь div'ы, которых изначально не было, а во-вторых может поменяться внешний вид
кроме того, я бы не записывал столько всего в for: var childNodes = (parent || document.body).childNodes; length = childNodes.length; for (i = 0; i < length; i++) { и использовал бы if'ы вместо тернарного оператора if( I.nodeType == 1 ) arguments.callee(callback, I); elseif( I.nodeType == 3 ) callback(I, i); а еще, может, регулярное выражение можно проще сделать, но это зависит от наличия других ссылок в тексте |
Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
Что касается читаемости, то, на мой взгляд, при нормальном оформлении тернарного оператора, он читается лучше, чем if-else. |
Цитата:
window.onload = function() { TextNode.each(function(noda) { var div = document.createElement('div'); div.innerHTML = noda.nodeValue.replace(/(http\:\/\/www\.youtube\.com\/watch\?v\=[0-9a-z]{11})/gi, '<a href="$1">$1</a>'); if (div.firstChild && div.innerHTML != noda.nodeValue) { var n = noda.nextSibling, p = noda.parentNode; do p.insertBefore(div.firstChild, n); while (div.firstChild); p.removeChild(noda); } }); }; Теперь нет никаких лишних тегов. |
Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
ИМХО, незначительно. более того это можно было бы назвать преждевременной оптимизацией, и потому подход этот вреден. вам тернарный оператор нормально читается, а большинству нет. то есть ваш подход приемлим, только если вы в одиночку пишите жестко инкапсулированый код, которй предполагаете никто кроме вас дорабатывать не должен. |
Цитата:
Цитата:
У меня код уменьшается минимум на 15%. Думаете, я преувеличиваю? Нет, потому что на результат можно по-разному смотреть. Я, например, смотрю на него после работы YUICompressor-а. Считайте сами, каждая локальная переменная, например "parentNode", становиться одной буквой, то есть "parentNode" уменьшиться в 10 раз. В результате объем операторов в коде, в процентах, становиться довольно значительным и экономить на них уже довольно выгодно. Цитата:
С другой, вот, попадется вам какой ни будь плагин к Jquery (а большинство из них пишутся примерно в этом же стиле) и будите с ним мучиться. У меня с этим проблем нет т. к. свободно воспринимаю самые разные стили. Цитата:
Цитата:
|
Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
мой вариант: window.onload = function() { TextNode.each(function(noda) { var div = document.createElement( 'div' ); div.innerHTML = noda.nodeValue.replace(/(http\:\/\/www\.youtube\.com\/watch\?v\=[0-9a-z]{11})/gi, '<a href="$1">$1</a>'); var f = document.createDocumentFragment(); while( div.childNodes.length ) f.appendChild( div.childNodes[0] ); noda.parentNode.replaceChild( f, noda ); }); }; |
Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
В IE ваш вариант выдал ошибку, т. к. коллекция .childNodes, почему то стала содержать undefined элементы. Можно исправить, подправив TextNode.each. Думаю, получается уже довольно продуманный вариант: var TextNode = { each: function(callback, parent) { for (var childNodes = (parent || document.body).childNodes, i = 0, length = childNodes.length; i < length; i++) { var I = childNodes[i]; if (I) I.nodeType == 1 ? arguments.callee(callback, I) : I.nodeType == 3 && callback(I, i); } } }; window.onload = function() { TextNode.each(function(noda) { var div = document.createElement('div'); div.innerHTML = noda.nodeValue.replace(/(http\:\/\/www\.youtube\.com\/watch\?v\=[0-9a-z]{11})/gi, '<a href="$1">$1</a>'); if (div.firstChild && div.innerHTML != noda.nodeValue) { var f = document.createDocumentFragment(); do f.appendChild(div.firstChild); while (div.firstChild); noda.parentNode.replaceChild(f, noda); } }); }; Вместо .childNodes[0] можно использовать .firstChild Проверка if (div.firstChild && div.innerHTML != noda.nodeValue) { очень не лишняя, т. к. без нее будут перезаписываться и те ноды, что перезаписывать не надо, ну и как следствие while меняем на do-while, чтоб не было лишней проверки в цикле. |
Часовой пояс GMT +3, время: 11:55. |