Javascript-форум (https://javascript.ru/forum/)
-   jQuery (https://javascript.ru/forum/jquery/)
-   -   Поиск выражения в тексте (https://javascript.ru/forum/jquery/3317-poisk-vyrazheniya-v-tekste.html)

Riim 09.04.2009 11:14

Цитата:

Сообщение от Zeroglif
Кто ж против применения

А я уж подумал, что вы против.

Цитата:

Сообщение от Zeroglif
В вашем конкретном случае равенство строк не гарантировано. Неужели так сложно проверить? Чего будет на странице до и чего после:

text
<p&gt
alone

Цитата:

Сообщение от Zeroglif
http://msdn.microsoft.com/en-us/library/ms533897.aspx
https://developer.mozilla.org/En/DOM/Element.innerHTML


Я еще раз проверил в разных браузерах. Я очень всматривался пытаясь увидеть разницу. И ее нет.
Вероятно вы используете старый вариант. Я же приводил исправленный вариант уже:
var TextNode = {
	each: function(callback, parent) {
		for (var childNodes = (parent || document.body).childNodes, i = 0; i < childNodes.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 v = noda.nodeValue.replace(/(http\:\/\/www\.youtube\.com\/watch\?v\=[0-9a-z]{11})/gi, '<a href="$1">$1</a>');
		if (v != noda.nodeValue) {
			var div = document.createElement('div');
			div.innerHTML = v;
			if (div.firstChild) {
				var f = document.createDocumentFragment();
				do f.appendChild(div.firstChild);
				while (div.firstChild);
				noda.parentNode.replaceChild(f, noda);
			}
		}
	});
};

Dmitry A. Soshnikov 09.04.2009 11:25

Riim,

Цитата:

Сообщение от Riim
var div
var f

Можно один раз объявить, и записать свойством в функцию-коллбэк, иначе, они создаются каждый раз при вызове callback(I, i);.

Riim 09.04.2009 11:47

Цитата:

Сообщение от Zeroglif
Тем более жутко, что нет вообще никакой необходимости replace-ить все текстовые ноды без разбора (на кой ляд это делается?).

Если не хотите приводить свой код, то хоть объясните подробней, как вы предполагаете это сделать, а я уж сам сделаю.

Цитата:

Сообщение от Dmitry A. Soshnikov
Можно один раз объявить, и записать свойством в функцию-коллбэк, иначе, они создаются каждый раз при вызове callback(I, i);.

А стоит так мучиться для одноразового кода. Разве, что ради идеи:

window.onload = function() {
	var callback = function(noda) {
		var v = noda.nodeValue.replace(/(http\:\/\/www\.youtube\.com\/watch\?v\=[0-9a-z]{11})/gi, '<a href="$1">$1</a>');
		if (v != noda.nodeValue) {
			var div = arguments.callee.div;
			div.innerHTML = v;
			if (div.firstChild) {
				var f = arguments.callee.fragment;
				do f.appendChild(div.firstChild);
				while (div.firstChild);
				noda.parentNode.replaceChild(f, noda);
			}
		}
	};
	callback.div = document.createElement('div');
	callback.fragment = document.createDocumentFragment();
	TextNode.each(callback);
};


Странно, что после строки "var f = arguments.callee.fragment;" не нужно отчищать этот самый фрагмент. Видимо после добавления в документ он сам очищается.

x-yuri 09.04.2009 11:59

Riim, речь шла о сравнении innerHTML с nodeValue
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>blank</title>
    <script type="text/javascript">
var TextNode = {
    each: function(callback, parent) {
        for (var childNodes = (parent || document.body).childNodes, i = 0; i < childNodes.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 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);
        }
    });
};
    </script>
</head>
<body>
 
text 
&lt;p&gt
alone
 
</body>
</html>

Цитата:

А стоит так мучиться для одноразового кода. Разве, что ради идеи
так ты определись, что мы обсуждаем. А то сначала ты говоришь про экономию операторов, а потом, что это одно разовый код. Давай тогда представим, что это супер-мега-быстрый фреймворк. Это твой окончательный вариант?
p.s. кто-нибудь может что-то сказать про экономию операторов, кроме Riim, он уже вроде высказался по этому поводу

Dmitry A. Soshnikov 09.04.2009 11:59

Цитата:

Сообщение от Riim
А стоит так мучиться

Ну вы ж тут, вроде, об оптимизации беседуете (хотя, весь топик я не читал)? Поэтому, лучше один раз "помучиться", чем на каждый вызов.

Zeroglif 09.04.2009 12:19

Цитата:

Сообщение от Riim
то хоть объясните подробней

У вас есть признак ноды, которая нужна (некий текст), проверяйте наличие этого текста и меняйте при наличии.

Цитата:

Сообщение от x-yuri
про экономию операторов

Вары через запятую - это нормально, много варов внутри 'for' - необычно, глаз не радует, строку удлиняет, обычно задают не больше двух. Объявление переменной внутри цикла - бессмысленная вешь, провоцирующая ньюбов на лишние вопросы. Условный оператор обязан быть читабелен среди профи (в меру простой, конечно), ничего не имею против, но чаще всего не читабелен для других. Кроме того, с ним не очень приятно дорабатывать код, расширяя список выражений. С логическими операторами картина та же, в отсутствии присваивания они теряют в читабельности, к тому же есть пуристы, которые используют их только в логическом контексте. Конструкция 'do-while' в примере может и была бы правильным выбором, если бы так нужно было проверять 'div.firstChild', а это не нужно, как и 'innerHTML' и проч.

x-yuri 09.04.2009 12:59

Zeroglif, а с производительностью это как-то связано? Или вопрос стиля?

Zeroglif 09.04.2009 13:07

Цитата:

Сообщение от x-yuri
Zeroglif, а с производительностью это как-то связано?

Это больше вопрос стиля, читабельности, удобства, краткости записи. О скорости можно рассуждать только с тестами в руках. Я не вижу иных причин отказываться от той же 'if-else' кроме как из-за экономии букв...

Riim 09.04.2009 13:23

Цитата:

Сообщение от x-yuri
Riim, речь шла о сравнении innerHTML с nodeValue

Я уже давно понял и написал исправленный вариант. Посты № 47 и 51.

Цитата:

Сообщение от Zeroglif
У вас есть признак ноды, которая нужна (некий текст), проверяйте наличие этого текста и меняйте при наличии.

Я так и думал, что вы про это. Если проверять БЕЗ regexp-а, то почему бы и нет.

Цитата:

Сообщение от x-yuri
А стоит так мучиться для одноразового кода. Разве, что ради идеи
так ты определись, что мы обсуждаем. А то сначала ты говоришь про экономию операторов, а потом, что это одно разовый код

Экономил операторы я в TextNode.each, а это уже НЕ одноразовый код.
Я давно определился и уже объяснял как именно.
Я говорю про:
1) производительность
2) объем кода
3) логичность кода
4) читабельность
Приоритеты меняются в зависимости от кода.
В TextNode.each на первом месте производительность (универсальный код).
В window.onload объем кода (одноразовый код).
Читабельность всегда на последнем.

Почему именно такой порядок, я уже объяснял (с примерами) выше. Например, объяснял, как из-за не оптимизированного универсального кода появляются проблемы с производительностью, т. к. рано или поздно, он все равно становится узким местом в приложении.

Оптимизация одного часто делается в ущерб остальному. Вопрос в том, насколько эффективна эта оптимизация, и каков ущерб.
Дмитрий предложил вариант оптимизации производительности в ущерб объему кода. Ущерб слишком большой, а выигрыш в скорости мизерный (теоретически, не тестировал). Вариант предложенный Zeroglif (с проверкой до regexp-а), даст заметно большее увеличение производительности и меньший ущерб. Вполне приемлемый вариант.

Во всех случаях выше, где я отходил от своих приоритетов, я пояснял, почему это делаю.
В случае с предложенным Дмитрием вариантом, я пояснил, что делаю это просто что бы попробовать идею.
Надеюсь, что на этот раз я все достаточно подробно изложил, и вопросов на счет моих приоритетов больше не будет.

Цитата:

Сообщение от Zeroglif
много варов внутри 'for' - необычно, глаз не радует, строку удлиняет, обычно задают не больше двух. Объявление переменной внутри цикла - бессмысленная вешь, провоцирующая ньюбов на лишние вопросы. Условный оператор обязан быть читабелен среди профи (в меру простой, конечно), ничего не имею против, но чаще всего не читабелен для других. Кроме того, с ним не очень приятно дорабатывать код, расширяя список выражений. С логическими операторами картина та же, в отсутствии присваивания они теряют в читабельности, к тому же есть пуристы, которые используют их только в логическом контексте

Я не хочу (без обид) вообще ни чего слышать про читабельность (в универсальном коде) в ущерб даже плюс одному байту кода после компрессора или плюс одному лишнему действию интерпретатора. Мой стиль не формируется, он уже сформирован, и до javascript2.0 я менять себя не собираюсь.


Цитата:

Сообщение от Zeroglif
Конструкция 'do-while' в примере может и была бы правильным выбором, если бы так нужно было проверять 'div.firstChild', а это не нужно

Как не нужно? Как же цикл тогда остановится?

Zeroglif 09.04.2009 13:38

Цитата:

Сообщение от Riim
Как не нужно? Как же цикл тогда остановится?

Вы используете 'if' плюс 'do-while', если уйти от 'if', который не нужен вообще, то достаточно 'while'. Остановка цикла не при чём.


Часовой пояс GMT +3, время: 13:05.