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

x-yuri 08.04.2009 13:57

Цитата:

Не зарекайтесь
я периодически копаюсь в jQuery, проблем пока не было
Цитата:

И вы что то друг за друга отвечаете. Прям наехали тут на меня вдвоем
значит у нас просто совпадают мнения, зови своего одномышленника, похоливарим ;-)
Цитата:

В IE ваш вариант выдал ошибку, т. к. коллекция .childNodes почему то стала содержать undefined элементы
а можно содержимое body? А то на моих довольно простых данных не было проблем ни в ie6, ни в ie7. И неужели работа с childNodes напрямую (через n) решило эту проблему?
p.s. считаю, вполне можно на ты ;-)

Riim 08.04.2009 14:13

<!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, 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 n = noda.nextSibling, p = noda.parentNode;
			do p.insertBefore(div.firstChild, n);
			while (div.firstChild);
			p.removeChild(noda);
		}
	});
	*/
	
    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 );
    });
	
	/*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>
<div class="authForm">
	<form action="/Default.aspx" method="post" onsubmit="return $(this).validate();">
	<input type="hidden" name="auth" value="auth" />
	<br />
	<div id="ctl00_Authorization1_messages">
		<br />
	</div>
	имя<br />
	<input type="text" name="username" value="" maxlength="20" class="v-required v-name v-minlength2" />
	<br />
	пароль<br />
	<input type="password" name="password" maxlength="40" class="v-required" />
	<br />
	<br />
	<input type="submit" value="  Войти  " />
	<br />
	<br />
	</form>
	<a href="Registration.aspx">регистрация</a>
	<br />
	<br />
</div>
<table class="list">
	<tr>
		<td>
			mmm
		</td>
		<td>
			dsfssssssss
		</td>
		<td>
			fdgfdgd f 111 http://www.youtube.com/watch?v=iuOcLoqo5e0 23423 rgfd
		</td>
		<td>
			01.04.2009 1:32:11
		</td>
	</tr>
	<tr>
		<td>
			sawewq
		</td>
		<td>
			django
		</td>
		<td>
			
		</td>
		<td>
			http://www.youtube.com/watch?v=iuOcLoqo5e0
		</td>
	</tr>
	<tr>
		<td>
			asddddd
		</td>
		<td>
			django
		</td>
		<td>
			
		</td>
		<td>
			30.03.2009 2:47:18
		</td>
	</tr>
</table>
http://www.youtube.com/watch?v=iuOcLoqo5e0
</body>
</html>

Riim 08.04.2009 14:34

<!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, 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>');
        var f = document.createDocumentFragment();
        //if (div.firstChild) {
			while (div.firstChild)
				f.appendChild(div.firstChild);
			noda.parentNode.replaceChild(f, noda);
        //}
    });
	
	/*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>

	<form>
	<input type="text" />
	<input type="text" />
	</form>

</body>
</html>



При этом если форму записать в одну линию, то ошибка исчезает:

<form><input type="text" /><input type="text" /></form>

x-yuri 08.04.2009 14:41

значит удаляются (исключаются) пустые текстовые ноды, а length считается в начале цикла
upd: а точнее, во всех браузерах, кроме IE получаем 1:
var div = document.createElement('div');
div.innerHTML = ' ';
alert(div.childNodes.length);

Riim 08.04.2009 15:07

var f = document.createDocumentFragment();
	while (div.firstChild)
		f.appendChild(div.firstChild);
	noda.parentNode.replaceChild(f, noda);


а так как div пустой то и div.firstChild-а нету, т. е. содержимое while не разу не сработает. И потом нода заменяется на пустой DocumentFragment.
Так в .childNodes попадают undefined.
Решение:
1) В TextNode.each добавляем if (I)
(в последнем моем посте он закоментирован)
И не только для этого случая.
Мало ли в каких ситуациях такое может случиться.
2) Зачем перезаписывать текстовые узлы содержащие пробельные символы.
Добавляем проверку: if (div.firstChild) {
(она тож закоментирована)
В результате пустых div-ов просто не будет.
3) Зачем вообще перезаписывать текстовые узлы содержание которых не изменилось.
Добавляем к проверке еще условие if (div.firstChild && div.innerHTML != noda.nodeValue) {


В посте №20 был пока лучший вариант.

x-yuri 08.04.2009 15:51

Цитата:

Так в .childNodes попадают undefined
они туда не попадают, дело в уменьшении размера childNodes
Цитата:

И не только для этого случая.
Мало ли в каких ситуациях такое может случиться
с такими "как бы чего не вышло" можно далеко зайти, поэтому я предпочитаю знать, зачем я что-то делаю
Цитата:

Зачем перезаписывать текстовые узлы содержащие пробельные символы
это случайно получилось, я на это не рассчитывал
я бы написал так:
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))
                return;
        var f = document.createDocumentFragment();
        while( div.firstChild )
            f.appendChild( div.firstChild );
        noda.parentNode.replaceChild( f, noda );
    });
};

не знаю, если бы это была какая-то общедоступная библиотека, стоило бы ее как-то оптимизировать, но такого опыта у меня пока нету. И я бы скорее искал узкие места в реальных приложениях, чем оптимизировал все по максимуму
кстати, по поводу читабельности можно вспомнить http://en.wikipedia.org/wiki/Unix_philosophy , там несколько раз отдается предпочтение читабельности, а не наоборот

Riim 08.04.2009 17:54

Цитата:

Сообщение от x-yuri
while( div.firstChild )
f.appendChild( div.firstChild );

Я уже писал, что в данном случае while нужно заменить на do-while, т. к. проверка div.firstChild происходит прямо перед циклом. Зачем делать ее 2 раза подряд.


Цитата:

Сообщение от x-yuri
if (! div.firstChild ||
(div.innerHTML == noda.nodeValue))
return;

медленней чем:
if (div.firstChild && div.innerHTML != noda.nodeValue) {


и кода больше.

Riim 08.04.2009 18:15

Цитата:

Сообщение от x-yuri
они туда не попадают, дело в уменьшении размера childNodes

Если точнее то да. Длинна уменьшается, а в цикле используется запомненная в переменной length длинна.
Можно ее просто не запоминать:
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);
		}
	}
};

x-yuri 08.04.2009 19:04

Цитата:

Я уже писал, что в данном случае while нужно заменить на do-while, т. к. проверка div.firstChild происходит прямо перед циклом. Зачем делать ее 2 раза подряд
я видел, я тоже уже писал, что у меня не производительность на первом месте. А если бы я оптимизировал, то искал бы скорее узкие места, а не экономил на спичках. По-крайней мере, я не видел авторитетных источников, которые бы проповедовали такое делать, зато видел много противоположных, один привел выше, т.е. там на самом деле даже несколько человек высказались за оптимизацию узких мест. Для меня был бы аргументом реальный проект, использующий именно эту функцию, который тормозит из-за того, что do-while был заменен на while
Цитата:

медленней чем...и кода больше
зато нету лишнего уровня вложенности

Riim 08.04.2009 19:31

Цитата:

Сообщение от x-yuri
А если бы я оптимизировал, то искал бы скорее узкие места, а не экономил на спичках.

Универсальные функции обычно и становятся узкими местами. Не лучше ли подумать об этом сразу, чем возвращаться потом.
Что касается window.onload, то это одноразовый код, минусы которого не будут перетекать с сайта на сайт. Так что, действительно, пусть себе тормозит сколько угодно.

Цитата:

Сообщение от x-yuri
зато нету лишнего уровня вложенности

А чем плох лишний уровень вложенности? Ты же за читаемость.

Цитата:

Сообщение от x-yuri
который тормозит из-за того, что do-while был заменен на while

Из-за одного такого случая вряд ли что-то изменится. Но если весь код писать так, то меняется, и очень даже заметно.

Цитата:

Сообщение от x-yuri
Для меня был бы аргументом реальный проект

Я вот только что был на qip.ru. У меня почта там. Зайди и посмотри, как тормозит почтовый интерфейс напичканный ajax-ом. При нажатии на ссылку запускающую javascript аж флеш-банеры подвисают. А теперь зайди на gmail.


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