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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проскальзывает рег 
V
    Опции темы
Innuendo
Дата 14.10.2006, 14:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 745
Регистрация: 24.12.2005
Где: Молдова

Репутация: 2
Всего: 6



Я опять со своими регами (наверное некоторых уже достал) но вот в чём проблема:
Есть, к примеру 2 массива с регами: a,b. (ну у меня их на самом деле больше)
И есть массив divs с HTML-элементами, а именно к примеру с <div> на странице.
Надо пробежаться по всему массиву divs и проверить на каждый рег. И найденные реги подчеркнуть.
Код

<html>
<head>
<script>
<!--
function mytest(){
var a =  new Array(/green/gi, /white/gi, /black/gi, /yellow/gi, /red/gi);
var b =  new Array(/nicolay/gi, /sereja/gi, /vasea/gi, /ibrahim/gi, /petea/gi);
var divs = document.getElementsByTagName("div");
var a2 = {};
var b2 = {};
var aa = [];
var bb = [];
var i,j;
for (j=0; j<divs.length; j++){

 for (i=0; i<a.length; i++){
   if (a[i].test(divs[j].innerHTML)) a2['~' + j]=true; 
 }
  for (i=0; i<b.length; i++){
   if (b[i].test(divs[j].innerHTML)) b2['~' + j]=true;
 }

}
for(i in a2) {
   if(i.charAt(0)!='~') continue; 
   aa.push(i.substr(1));
}

for(i in b2) {
   if(i.charAt(0)!='~') continue; 
   bb.push(i.substr(1));
}

// zamena //
if (aa.length!=0){
    for (j=0; j<aa.length; j++){
        var tempStr = divs[aa[j]].innerHTML;
        for (i=0; i<a.length; i++){
            tempStr=tempStr.replace(a[i],
            (function(x) {return '<u>' + x + '</u>'}))
        }        
        divs[aa[j]].innerHTML = tempStr;
    }
}

if (bb.length!=0){
    for (j=0; j<bb.length; j++){
        var tempStr = divs[bb[j]].innerHTML;
        for (i=0; i<b.length; i++){
            tempStr=tempStr.replace(b[i],
            (function(x) {return '<u>' + x + '</u>'}))
        }        
        divs[bb[j]].innerHTML = tempStr;
    }
}
}
window.onload = mytest;
//-->
</script>
</head>
<body>
<div> test green and black </div>
<div> test green and black </div>
<div> vasea da petea test</div>
<div> i nicolay k tomu je </div>
</body>


И возникла проблема. Когда 2 дива с одинаковым содержимым, то оно не подчёркивает (как у нас с дивом 2)
Но содержимое должно быть не приблизительно равное... Я толком не понял все случаи, когда он не заменяет. Но вот тут он не заменил во втором диве


--------------------
=)
PM MAIL ICQ Jabber   Вверх
12345c
Дата 14.10.2006, 15:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Круглый
****


Профиль
Группа: Vingrad developer
Сообщений: 2018
Регистрация: 26.12.2005
Где: наша не пропадала ?

Репутация: 57
Всего: 101



Код

for (j=0; j<divs.length; ){

 for (i=0; i<a.length; i++){
   if (a[i].test(divs[j].innerHTML)) a2['~' + j++]=true;
   if(j==divs.length) break
 }
  for (i=0; i<b.length; i++){
   if (b[i].test(divs[j].innerHTML)) b2['~' + j++]=true;
   if(j==divs.length) break
 }
так будет работать - обычная логическая ошибка. Я бы не пользовался for...in, если там важен порядок выборки - разные браузеры выбирают элементы каждый в своём порядке.

Такие примеры, которые других ничему особенному не учат и особенностей языка не открывают, разбирают в разделе "для начинающих". (Это написано в заголовке раздела для начинающих (" ...или для неопытного разработчика требуется совет или просьба отыскать ошибку"), но надо будет написать и в основном разделе.)
PM WWW   Вверх
Innuendo
Дата 14.10.2006, 20:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 745
Регистрация: 24.12.2005
Где: Молдова

Репутация: 2
Всего: 6



Цитата(12345c @  14.10.2006,  15:30 Найти цитируемый пост)
Такие примеры, которые других ничему особенному не учат и особенностей языка не открывают, разбирают в разделе "для начинающих". (Это написано в заголовке раздела для начинающих (" ...или для неопытного разработчика требуется совет или просьба отыскать ошибку"), но надо будет написать и в основном разделе.) 

ok, учту.

Цитата(12345c @  14.10.2006,  15:30 Найти цитируемый пост)
так будет работать - обычная логическая ошибка. Я бы не пользовался for...in, если там важен порядок выборки - разные браузеры выбирают элементы каждый в своём порядке.


попробую. Порядок не важен, а по-поводу браузеров - это только для Мозиллы так как скрипт вызывается из xul-приложения

Добавлено @ 20:40 
Подставил именно в этот скрипт - работает.
А добавил ещё один массив с регами ( в этот же скрипт), назвал его с, и добавил ещё один цикл для c и скрипт вообще не работает. Пишет что divs[i] is undefined =((

Это сообщение отредактировал(а) Innuendo - 14.10.2006, 21:00


--------------------
=)
PM MAIL ICQ Jabber   Вверх
12345c
Дата 14.10.2006, 21:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Круглый
****


Профиль
Группа: Vingrad developer
Сообщений: 2018
Регистрация: 26.12.2005
Где: наша не пропадала ?

Репутация: 57
Всего: 101



Ну в цикле с массивом с, значит, подобная ошибка с выходом за пределы массива. Посмотри на мой код - везде, где значение индекса массива может выйти, там стоит проверка.
PM WWW   Вверх
Innuendo
Дата 14.10.2006, 21:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 745
Регистрация: 24.12.2005
Где: Молдова

Репутация: 2
Всего: 6



ну вот я вот так добавил:
Код

for (j=0; j<divs.length; ){

 for (i=0; i<a.length; i++){
   if (a[i].test(divs[j].innerHTML)) a2['~' + j++]=true;
   if(j==divs.length) break
 }
 for (i=0; i<b.length; i++){
   if (b[i].test(divs[j].innerHTML)) b2['~' + j++]=true;
   if(j==divs.length) break
 }
 for (i=0; i<c.length; i++){
   if (c[i].test(divs[j].innerHTML)) c2['~' + j++]=true;
   if(j==divs.length) break
 }
}

И кстати, скрипт не работает, если я в одном диве напишу Green Ibrahim - 2 рега из разных массивов... А мне нужно чтоб он подсвечивал абсолютно везде


--------------------
=)
PM MAIL ICQ Jabber   Вверх
12345c
Дата 14.10.2006, 22:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Круглый
****


Профиль
Группа: Vingrad developer
Сообщений: 2018
Регистрация: 26.12.2005
Где: наша не пропадала ?

Репутация: 57
Всего: 101



Код

labelj:for (j=0; j<divs.length; ){

 for (i=0; i<a.length; i++){
   if (a[i].test(divs[j].innerHTML)) a2['~' + j++]=true;
   if(j==divs.length) break labelj
 }
 for (i=0; i<b.length; i++){
   if (b[i].test(divs[j].innerHTML)) b2['~' + j++]=true;
   if(j==divs.length) break labelj
 }
 for (i=0; i<c.length; i++){
   if (c[i].test(divs[j].innerHTML)) c2['~' + j++]=true;
   if(j==divs.length) break
 }
}
Надо так, как оказалось (выход за цикл по j), но, суда по постановке, я бы вообще выбросил лишние циклы.

Добавлено @ 22:47 
Вот так (для случая с 2 массивами). Для больше 2 - цепочка конкатенации увеличивается:
Код

var aAll=a.concat(b);
for (j=0; j<divs.length;j++){
  s=divs[j].innerHTML;
  for (i=0; i<aAll.length; i++){
    s=s.replace(aAll[i],'<u>'+aAll[i].source+'</u>')
  }divs[j].innerHTML=s;  
}


Добавлено @ 22:48 
Код
var aAll=a.concat(b).concat(c); //и так далее


Добавлено @ 22:50 
И здесь не предусмотрен случай, если в innerHTML попадётся подстрока, совпадающая с регом. Нужны контекстные проверки в регах (если нужны).
PM WWW   Вверх
Innuendo
Дата 15.10.2006, 10:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 745
Регистрация: 24.12.2005
Где: Молдова

Репутация: 2
Всего: 6



Последний случай не подходит =) У меня вообщ-то 5 массивов с регами, и в каждом по 5-6 регов. И если их все сразу в одну проверку запизнуьт, то страница будет пол часа сканить свои элементы, а их там за сотню.
Поэтому я специально разбил на этапы:
1) сначала бежим по элементам, и просто смотрим где совпадениеи если есть, то номер элемента загоняем в объекты
2) объеты делаем в массивы
3) бежим уже по этим массивам - чисто с номерами элементов, где должны быть изменения и там изменяем.

А вот почему в моём самом первом случае не заносит в массив, если 2 абсолютно одинаковых содержания элемента к примеру? Там же вроде цикл как надо: пробегаем все элементы (j=0 --> divs.length) , и там уже с каждым элементом пробегаем все циклы по регам...


--------------------
=)
PM MAIL ICQ Jabber   Вверх
Innuendo
Дата 15.10.2006, 15:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 745
Регистрация: 24.12.2005
Где: Молдова

Репутация: 2
Всего: 6



Урааа! Проблема решена. Это баг всё-таки получается.
Спасибо Anton'у с форуму мозиллы =)
Код

for (i=0; i<a.length; i++){
   if (a[i].test(divs[j].innerHTML)) { a2['~' + j]=true; f=a[i].test(divs[j].innerHTML) }
 }



--------------------
=)
PM MAIL ICQ Jabber   Вверх
Zeroglif
Дата 15.10.2006, 17:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: 28
Всего: 66



Цитата(Innuendo @  15.10.2006,  15:16 Найти цитируемый пост)
Урааа! Проблема решена. Это баг всё-таки получается.
Спасибо Anton'у с форуму мозиллы =)

Баг говоришь... ну-ну. Передавай привет форуму мозиллы, пусть к нам сюда почаще заходят..., за знаниями, так сказать. Теперь по сути проблемы. Ты используешь в своём скрипте метод объекта RegExp под симпатишным названием test. Согласно EcmaScript (15.10.6.3) - это не что иное как:
Код

RegExp.prototype.exec(string) != null


То есть по большому счёту за спиной test работает всё тот же наиглавнейший и наиважнейший метод exec, а у exec есть особенность, связанная с флагом g (global), если global=false (флаг не задан), то свойство регулярного по имени lastIndex стоит и не шевелится, а если global=true (флаг задан), lastIndex может перемещаться... В переводе на русский это означает, что если в регулярное мы засунем g, то при каждом вызове метода exec поиск совпадения будет начинаться с последней точки lastIndex. 

Два примера (в одном g задан, в другом нет):

Код

var re = /\d/g;        //задаём флаг global
alert(re.exec('3x2')); //найдено число 3
alert(re.exec('4x6')); //найдено число 6

var re2 = /\d/;         //не задаём флаг global
alert(re2.exec('3x2')); //найдено число 3
alert(re2.exec('4x6')); //найдено число 4


В первом примере при первом же вызове было найдено число 3 и lastIndex встал в позицию 1. При втором вызове поиск начался уже с позиции 1, и, само собой, число 4 пролетело лесом, нашлось только число 6.

Во втором примере lastIndex для второго вызова стоит в позиции 0, и всё находится, как и должно.

!!!Несмотря на то, что в твоём примере всё такое циклично-цикличное постоянно меняющееся smile, не стоит забывать, что регулярные выражения заданы литерально, то есть никакого для них рантайма нет, объекты RegExp были созданы интерпретатром на "нулевой строке" раз и навсегда:

Цитата

7.8.5 Regular Expression Literals 
A regular expression literal is an input element that is converted to a RegExp object (section 15.10) when it is scanned. The object is created before evaluation of the containing program or function begins. Evaluation of the literal produces a reference to that object; it does not create a new object.


Вот как бы так. Предположу, что теперь-то ты все баги должен победить. smile




Это сообщение отредактировал(а) Zeroglif - 15.10.2006, 17:51
PM MAIL WWW   Вверх
Innuendo
Дата 15.10.2006, 21:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 745
Регистрация: 24.12.2005
Где: Молдова

Репутация: 2
Всего: 6



я там ещё где-то прочитал, что это так устроен этот test(), если он вернёт true, то следующее что он вернёт false и т.д.
Я ещё когда мучался со скриптом, для проверки добавлял alert(totreg.test(obj)) он выводил false, но подсвечивал!!! а если без алерта этого, то не подсвечивал (не было совпадения)

а что если аттрибут действительно нужен? ну я вроде 'g' оставил, и уже работает вроде...


--------------------
=)
PM MAIL ICQ Jabber   Вверх
Zeroglif
Дата 15.10.2006, 22:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: 28
Всего: 66



Цитата(Innuendo @  15.10.2006,  21:23 Найти цитируемый пост)
а что если аттрибут действительно нужен? ну я вроде 'g' оставил, и уже работает вроде...


Сейчас работает, а завтра перестанет. Каждому методу - своё место. Я даже не представляю себе, зачем тебе этот скрипт реально нужен, имхо это больше похоже на некое экзаменационное задание на тему - придумайте самый сложный и тернистый путь замены в строке. А можно ведь что-то вроде:

Код

function mytest() { 
    var d = document.getElementsByTagName('div'), i = d.length;
    while (i--) {
        d[i].innerHTML = d[i].innerHTML.replace(
            /(green|white|black|yellow|red|nicolay|sereja|vasea|ibrahim|petea)/gi, '<u>$1</u>');
    }
}

PM MAIL WWW   Вверх
Innuendo
Дата 15.10.2006, 22:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 745
Регистрация: 24.12.2005
Где: Молдова

Репутация: 2
Всего: 6



этот скрипт тестовый - реги выдуманы и т.д. (в качестве примера всё)
вообще скрипт открывается из xul-приложения и подсвечивает все маты (на русском, на транслите), номера ась, телефонов, словечки ещё разные и т.д. во всех элементах <td> определенного класса =)

я с самого начала сделал как в твоём предыдущем скрипте. Но так как там 5 массивов с регами, и около сотни элементов для пробега, он к каждому обращался через innerHTML неведомо сколько раз в цикле и страница была секунды 2 в ступоре пока он это всё делал =)

Это сообщение отредактировал(а) Innuendo - 15.10.2006, 22:18


--------------------
=)
PM MAIL ICQ Jabber   Вверх
Zeroglif
Дата 15.10.2006, 22:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: 28
Всего: 66



Цитата(Innuendo @  15.10.2006,  22:16 Найти цитируемый пост)
страница была секунды 2 в ступоре пока он это всё делал

Понятно. Тогда посмотри сюда, мы там обсуждали самый быстрый кроссбраузерный способ замены символов для транслита. Это по сути почти тот же вариант, что и у тебя, тоже много образцов и т.п. Выбери, что быстрее всего под гекко.
PM MAIL WWW   Вверх
Innuendo
Дата 15.10.2006, 23:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 745
Регистрация: 24.12.2005
Где: Молдова

Репутация: 2
Всего: 6



cпасибо, почитаю


--------------------
=)
PM MAIL ICQ Jabber   Вверх
smartov
Дата 16.10.2006, 22:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


свой собственный
****


Профиль
Группа: Экс. модератор
Сообщений: 4225
Регистрация: 2.2.2006
Где: NJ

Репутация: 7
Всего: 259



Innuendo, а к чему такие сложности?
Может стоит сделать вот так?

Код

<html>
<body>
<script>

function callbackReplace($0)
{
    return "<u>"+$0+"</u>";
}

function mytest()
{
var a =  new Array(/green/gi, /white/gi, /black/gi, /yellow/gi, /red/gi);    
var b =  new Array(/nicolay/gi, /sereja/gi, /vasea/gi, /ibrahim/gi, /petea/gi);    
var divs = document.getElementsByTagName("div");

for (var i=0;i<divs.length;i++)
{
    for (var k=0; k<a.length; k++)
        divs[i].innerHTML = divs[i].innerHTML.replace(a[k], callbackReplace);
        
    for (var k=0; k<b.length; k++)
        divs[i].innerHTML = divs[i].innerHTML.replace(b[k], callbackReplace);
}

}

window.onload = function() { mytest(); }
</script>

<div> test green and black </div>    
<div> test green and black </div>    
<div> vasea da petea test</div>    
<div> i nicolay k tomu je </div>

</body>
</html>


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


 




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


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

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