Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

HTML+CSS+JavaScript

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Проблема с аргументом-функцией в функции setInterval()
 
 автор: SilentChild   (18.02.2012 в 19:21)   письмо автору
 
 

Здравствуйте, участники форума!


Меню

<ul class="menu">
  <li id="lil">Menu
    <ul>
      <li>submenu</li>
    </ul>
  </li>
</ul>


JavaScript

<script language="javascript">
var Int;
function f_Int(f)
{
    var lil = event.srcElement;
    clearInterval(Int);
    if (f) {
        Int = setInterval("f_Drop('true', " + lil + ")", 5);
    }
}
function f_Drop(f, el) 
{
    var u = el.getElementsByTagName('ul')[0];
    var s = window.getComputedStyle(u, "");
    var h = s.getPropertyValue("height");
    if (f) {        
        u.style.height = (parseFloat(h) + 2) + "px";    
        if (parseFloat(u.style.height) >= 70) {
            u.style.height = "70px"; 
            clearInterval(Int);           
        }            
    }
}

var li = document.getElementById('lil');
li.onmouseover = new Function("f_Int('true')");
</script>


Нужно, чтобы дочерний список UL увеличивал свою высоту при наведении мышки на родительский для него элемент Li. Но функция...

Int = setInterval("f_Drop('true', " + lil + ")", 5);

... не желает повторяться, когда вторым аргументом ей передаю элемент инициировавший событие. В чём может быть загвоздка? Если не выполнять setInterval(), а вызвать функцию без повтора, то она выполняется. Но когда ту же функцию вставляю в setInterval(), то она не хочет повторяться.

  Ответить  
 
 автор: из кафе   (19.02.2012 в 08:33)
 
   для: SilentChild   (18.02.2012 в 19:21)
 

setInterval выполняется в глобальном контексте видимости,
а переменная lil локальная.

  Ответить  
 
 автор: SilentChild   (19.02.2012 в 12:59)   письмо автору
 
   для: из кафе   (19.02.2012 в 08:33)
 

Т.е. переменную lil нужно объявлять перед функциями, я правильно понял?


<script language="javascript"> 
var Int; 
var lil = document.getElementById('lil');
function f_Int(f) 
{     
    clearInterval(Int); 
    if (f) { 
        Int = setInterval("f_Drop('true', " + lil + ")", 5); 
    } 



Но так тоже не работает.

  Ответить  
 
 автор: с мобильника   (19.02.2012 в 13:26)
 
   для: SilentChild   (19.02.2012 в 12:59)
 

Я не могу сейчас запустить на выполнение ваш код и проверить, просто глазом зацепил вашу возможную ошибку.
Объявлять да, вне функции, либо внутри функции, но без var,
инициализировать в функции.

  Ответить  
 
 автор: SilentChild   (19.02.2012 в 13:38)   письмо автору
 
   для: с мобильника   (19.02.2012 в 13:26)
 

К сожалению не работает ни так, ни эдак.

  Ответить  
 
 автор: SilentChild   (19.02.2012 в 14:22)   письмо автору
 
   для: SilentChild   (19.02.2012 в 13:38)
 

Если написать вот так:


Int = setInterval("f_Drop('true', document.getElementById('lil'))", 100);


..., то всё прекрасно работает.

  Ответить  
 
 автор: с телефона   (19.02.2012 в 14:34)
 
   для: SilentChild   (19.02.2012 в 14:22)
 

У вас ещё было то, что вы передавали переменную как строковое значение.
Нужно было так:
Int = setInterval("f_Drop(true, lil)",5);

  Ответить  
 
 автор: SilentChild   (19.02.2012 в 14:57)   письмо автору
 
   для: с телефона   (19.02.2012 в 14:34)
 

Благодарю Вас, всё заработало. Но! ... возник попутная проблема, когда я заменил название переменной lil на u, вот так:


<script language="javascript">
var Int;
function f_Int(f)
{
    var u = event.srcElement;
    clearInterval(Int);
    if (f) {
        Int = setInterval("f_Drop('true', u)", 100);
    }
}


....код перестал работать. Когда объявляю переменную за пределами функции, то код снова начинает работать, но переменная с именем lil работает даже тогда, когда её объявляешь локально, в функции, что не наблюдается с другими именами переменной. Очень странно. Заменял названия переменных на разные буквы, вроде y - тоже отказывается работать. Переименовываю обратно в lil - работает отлично! В чём может быть загвоздка?

  Ответить  
 
 автор: ЯСА   (19.02.2012 в 15:13)   письмо автору
 
   для: SilentChild   (19.02.2012 в 14:57)
 

<script language="javascript">
var Int;
function f_Int(f)
{
    var u = event.srcElement;
    clearInterval(Int);
    if (f) {
        Int = setInterval("f_Drop('true', u)", 100);
    }

* var делает переменную u локальной, а нужна глобальная. Уберите var
* true - зарезервированное слово, кавычки не нужны

  Ответить  
 
 автор: SilentChild   (19.02.2012 в 15:34)   письмо автору
 
   для: ЯСА   (19.02.2012 в 15:13)
 

За true спасибо! Почему переменную с именем u нужно делать глобальной, в то время как ту же переменную с именем lil нет?

  Ответить  
 
 автор: ЯСА   (19.02.2012 в 15:45)   письмо автору
 
   для: SilentChild   (19.02.2012 в 15:34)
 

Потому что, прописывая u в виде символа строки
setInterval("f_Drop(true, u)", 100);
, вы заставляете браузер при выполнении setInterval всякий раз искать глобальную переменную с именем u и подставлять её значение.

А когда вы пишете
setInterval("f_Drop('true', " + lil + ")", 5);
, вы РАЗ И НАВСЕГДА заносите в setInterval текущее (на момент записи этой строки кода) значение переменной lil: глобальная она будет или локальная - никакой разницы уже НЕТ. Потому как в методе setInterval прописано константное ЗНАЧЕНИЕ, но не имя переменной.

  Ответить  
 
 автор: SilentChild   (19.02.2012 в 15:54)   письмо автору
 
   для: ЯСА   (19.02.2012 в 15:45)
 

Очень доходчиво объяснили, благодарю. Не понимал, теперь понял схему работы функции в упомянутых Вами двух случаях. Но я немного не о том... а, собственно, вот о чём:


function f_Int(f)
{
    var lil = event.srcElement;
    clearInterval(Int);
    if (f) {
        Int = setInterval("f_Drop(true, lil)", 100);
    }
}


Т.е. я могу переменную с именем lil делать локальной и код прекрасно работает, хотя lil - локальна, но стоит заменить имя на u и код не работает.

  Ответить  
 
 автор: ЯСА   (19.02.2012 в 16:12)   письмо автору
 
   для: SilentChild   (19.02.2012 в 15:54)
 

"f_Drop(true, lil)" - это СТРОКА.
Понимаете, нет?
Это - НАБОР СИМВОЛОВ.
Он, двойными кавычками специально для этого выделен.

При выполнении setInterval
setInterval("f_Drop(true, lil)", 100);

браузер эту строку "f_Drop(true, lil)" РАЗБИРАЕТ и ИНТЕРПРЕТИРУЕТ.
И определяет:
1) надо вызвать функцию с именем f_Drop
2) этой функции при вызове надо передать два аргумента
3) первый аргумент - константа true
4) второй аргумент - значение глобальной переменной с именем lil

Браузер начинает искать глобальную переменную lil и НЕ НАХОДИТ такой. Подставляет поэтому вместо её значения либо null, либо undefined.
А если НАХОДИТ эту переменную среди глобальных - тогда берет её текущее значение и передаёт в качестве второго аргумента функции.
------

Теперь иная запись:
setInterval("f_Drop(true,  " + lil + ")", 100);

СРАЗУ при написании этой конструкции браузер СОЗДАЁТ СТРОКУ, в которой вместо переменной lil СРАЗУ подставляется её текущее значение. Будет lil в этот момент времени равно цифре 5, значит, получится строка "f_Drop(true, 5)", а будет в этот момент lil равен [Object], то браузер так и запишет "f_Drop(true, [Object])"

При исполнении браузер начнёт РАЗБИРАТЬ И ИНТЕРПРЕТИРОВАТЬ эту строку.
И в итоге вторым аргументом будет либо цифра 5, либо та хрень с Object

[поправлено модератором]

  Ответить  
 
 автор: SilentChild   (19.02.2012 в 16:46)   письмо автору
 
   для: ЯСА   (19.02.2012 в 16:12)
 

Ещё доходчивее объяснили, но это я из Вашего 2-го поста уже всё понял. Вопрос Вы не поняли немного. На него уже ответили ниже. Благодарю, что не поленились написать такой подробный ответ не на тот вопрос. =)

  Ответить  
 
 автор: с телефона   (19.02.2012 в 15:51)
 
   для: SilentChild   (19.02.2012 в 15:34)
 

У вас имя идентификатора списка совпадает с именем переменной которую setInterval ищет в глобальной области видимости, и таким образом, вероятно, находит, напрямую.

  Ответить  
 
 автор: SilentChild   (19.02.2012 в 15:55)   письмо автору
 
   для: с телефона   (19.02.2012 в 15:51)
 

Ах вон оно в чём дело, да-да! Спасибо огромное. =)

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования