Предоставление нескольких аргументов анонимной функции в setInterval

Я не уверен, что этот вопрос о Javascript задавался раньше - я не смог его найти, но если я его пропустил, приношу свои извинения.

Я пытаюсь создать страницу с флажками, которые будут отображать/исчезать соответствующее изображение. Затухание займет 1 секунду, каждые 100 мс непрозрачность изображения увеличивается или уменьшается на 0,1; когда непрозрачность достигает 0 или 1, вызов setInterval останавливается. Однако я не уверен, как передать аргументы анонимному вызову функции. Я пытаюсь передать две переменные: первая - это идентификатор изображения, полученный из значения флажка, а другая - установлен флажок или нет, чтобы функция знала, следует ли исчезать или исчезать.

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

Например:

<form action="">
<input type="checkbox" onclick='handleClick(this);' name="skymap" value="aurora">Aurora
<input type="checkbox" onclick='handleClick(this);' name="skymap" value="mainindex">Main Index
</form>

И функция следующая (пока)

function handleClick(cb) 
{

var myInterval = setInterval(function () 
{
  if (cb.checked) // tick box checked - fade in.
  {
    document.getElementById( cb.value ).style.opacity+=0.1;  // I'll refactor all these style.opacity calls later on :)

    if( document.getElementById( cb.value ).style.opacity>1 ) // full opacity - stop the timer
    {
        document.getElementById( cb.value ).style.opacity = 1;
        clearInterval(myInterval);
    }
}
else // fade out
{
    document.getElementById( cb.val ).style.opacity-=0.1;

    if( document.getElementById( cb.val ).style.opacity<0 )
    {
        document.getElementById( cb.val ).style.opacity = 0;
        clearInterval(myInterval);
    }
}


}, 100);


}

Изображения называются такими вещами, как:

<img id="aurora" src="aurora.png" />

person EventHorizon    schedule 22.02.2016    source источник
comment
Я не вижу, чтобы какие-либо параметры передавались прямо сейчас?   -  person colecmc    schedule 23.02.2016
comment
Вот в чем проблема - не знаю как...   -  person EventHorizon    schedule 23.02.2016


Ответы (5)


Вы столкнулись с непростой проблемой.

Во-первых, вы написали «cb.val» вместо «cb.value» в разделе else.

Во-вторых, свойство непрозрачности объекта "cb" имеет строковый тип. Операция -= преобразует значение непрозрачности в число, так как вы не можете выполнить операцию минус над строкой. Вместо этого операция += преобразует число (0,1) в строку и добавляет в конец строки непрозрачности (например, если непрозрачность равна 0,1, результатом будет «0,10,1»). Поскольку это значение недопустимо, оно будет установлено на последнее действительное значение, и вы застряли в цикле.

Вот рабочий пример:

function handleClick(cb) 
{

var myInterval = setInterval(function () 
{
  if (cb.checked) // tick box checked - fade in.
  {
    document.getElementById( cb.value ).style.opacity = parseFloat(document.getElementById( cb.value ).style.opacity) + 0.1  // I'll refactor all these style.opacity calls later on :)

    if( document.getElementById( cb.value ).style.opacity>1 ) // full opacity - stop the timer
    {
        document.getElementById( cb.value ).style.opacity = 1;
        clearInterval(myInterval);
    }
}
else // fade out
{
    document.getElementById( cb.value ).style.opacity-=0.1;

    if( document.getElementById( cb.value ).style.opacity<0 )
    {
        document.getElementById( cb.value ).style.opacity = 0;
        clearInterval(myInterval);
    }
}


}, 100);


}

Другая проблема, с которой вы можете столкнуться, заключается в том, что свойство opacity не установлено по умолчанию (или, по крайней мере, вы не можете быть в этом уверены). Итак, в первый раз opacity = "", пустая строка. Это вызовет скачки в вашей анимации. Обязательно инициализируйте непрозрачность, если обнаружите пустую строку.

person Daniel F.    schedule 22.02.2016
comment
Спасибо, это именно то, что мне нужно! Cb.val и отсутствие начальной непрозрачности были вызваны моим неаккуратным копированием и вставкой, но это работает отлично, большое спасибо! - person EventHorizon; 26.02.2016

Вы можете просто использовать cb.checked в своем существующем коде, но чтобы ответить на заданный вопрос: с setInterval и setTimeout вы просто используете функцию закрытия для передачи переменных, потому что значения из внешней области (функции) во время оценки доступны для вас. На очень простом уровне вы можете сделать что-то вроде:

function myTimeoutClosure(greeting, subject) {
    return function() {
        console.log(greeting + " " + subject);
    };
}
// ...
setTimeout(myTimeoutClosure("Hello", "World"), 500);
person Jim Driscoll    schedule 22.02.2016

Вы можете использовать дополнительные параметры функции setInterval(function(arg1, arg2, ..){...}, intervalTime, arg1, arg2,...)

function handleClick(cb) 
{

    var myInterval = setInterval(function (checked, imgId) 
        {
          if (checked) // tick box checked - fade in.
          {
            document.getElementById( imgId ).style.opacity+=0.1;  // I'll refactor all these style.opacity calls later on :)

            if( document.getElementById( imgId ).style.opacity>1 ) // full opacity - stop the timer
            {
                document.getElementById( imgId ).style.opacity = 1;
                clearInterval(myInterval);
            }
        }
        else // fade out
        {
            document.getElementById( imgId ).style.opacity-=0.1;

            if( document.getElementById( imgId ).style.opacity<0 )
            {
                document.getElementById( imgId ).style.opacity = 0;
                clearInterval(myInterval);
            }
        }
        }, 100, cb.checked, cb.value);

}
person Z.Z.    schedule 22.02.2016

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

function fadeElement(elem, increment) {

  elem.style.opacity = parseFloat(elem.style.opacity) + increment;

  if (elem.style.opacity >= 1) {
    elem.style.opacity = 1
  } else if (elem.style.opacity <= 0) {
    elem.style.opacity = 0
  } else {
    clearTimeout(elem.getAttribute('data-timeout'))
    elem.setAttribute('data-timeout', setTimeout(function() {
      fadeElement(elem, increment)
    }, 100))
  }
}

function handleClick(cb) {

  var chkbox = document.getElementById(cb.value);
  var direction = cb.checked ? 0.1 : -0.1;

  fadeElement(chkbox, direction)


}
<form action="">
  <input type="checkbox" checked onclick='handleClick(this);' name="skymap" value="aurora">Aurora
  <input type="checkbox" checked onclick='handleClick(this);' name="skymap" value="mainindex">Main Index
</form>
<p id="aurora" style="opacity:1">Aurora</p>
<p id="mainindex" style="opacity:1">Main Index</p>

person jmcgriz    schedule 22.02.2016

Вот пример. Надеюсь, это то, что вы ищете. Просто дай мне знать.

<form action="">
<input type="checkbox" class='imageSelect' name="skymap" value="aurora">Aurora
<input type="checkbox"  class= 'imageSelect' name="skymap" value="mainindex">Main Index
</form>
<div id="aurora" style="background:yellow; width:150px; height:40px; float:left; display:none;">Aurora Image </div>
<div id="mainindex" style="background:blue; width:150px; height:40px;float:left; display:none;">MainIndex Image </div>  

JS:

function CheckBoxClick(){
    $(".imageSelect").click(function(){
        /*if(this.checked){
             $("#"+$(this).val()+" ").fadeIn();
          }else{
             $("#"+$(this).val()+" ").fadeOut();
          }*/
     $("#"+$(this).val()+" ").toggle(this.checked)
    });
};    

Эффект затухания выглядит лучше, но вам решать, используете вы его или нет, оба варианта работают. Вот код для игры: https://jsfiddle.net/dzgppqap/

PD: Не забудьте добавить событие, когда страница будет готова:

$(document).ready(CheckBoxClick());
person epinal    schedule 22.02.2016