Чистый JavaScript затухает в функции

Привет, друзья, я хочу исчезать в div, когда я нажимаю на другой div, и для этого я использую следующий код. Code1 работает отлично, но мне нужно использовать Code2.

Я знаю, что есть jQuery, но мне нужно сделать это в JavaScript

Можете ли вы посоветовать мне, какую ошибку я делаю или что мне нужно изменить...

Код1 - работает нормально

function starter() { fin(); }

function fin()
{
    for (i = 0; i <= 1; i += 0.01)
    {
        i=Math.round(i*100)/100;
        setTimeout("seto(" + i + ")", i * 1000);
    }
}

function seto(opa)
{
    var ele = document.getElementById("div1");
    ele.style.opacity = opa;
}

Код2 --- Не работает

function starter()
{
    var ele = document.getElementById("div1");
    fin(ele);
}
function fin(ele)
{
    for (i = 0; i <= 1; i += 0.01)
    {
        i=Math.round(i*100)/100;
        setTimeout("seto(" + ele + "," + i + ")", i * 1000);
    }
}

function seto(ele,opa)
{
    ele.style.opacity = opa;
}

Ответ 1

На основании этого сайта

EDIT-1
Добавлена функциональность, чтобы пользователь мог указать продолжительность анимации (комментарий @Marzian)

Вы можете попробовать это:

function fadeIn(el, time) {
  el.style.opacity = 0;

  var last = +new Date();
  var tick = function() {
    el.style.opacity = +el.style.opacity + (new Date() - last) / time;
    last = +new Date();

    if (+el.style.opacity < 1) {
      (window.requestAnimationFrame && requestAnimationFrame(tick)) || setTimeout(tick, 16);
    }
  };

  tick();
}

var el = document.getElementById("div1");
fadeIn(el, 3000); //first argument is the element and second the animation duration in ms

DEMO

Ответ 2

var div = document.getElementById('div');
div.style.transition="opacity 1s";
div.style.opacity="0";

Ответ 3

Кажется, что вы пытаетесь преобразовать свой элемент в строку. Попробуйте это вместо

function starter()
{
    var ele = document.getElementById("div1");
    fin(ele);
}
function fin(ele)
{
    for (i = 0; i <= 1; i += 0.01)
    {
        i=Math.round(i*100)/100;
        setTimeout(function() { setto(ele,i); }, i * 1000);
    }
}

function seto(ele,opa)
{
    ele.style.opacity = opa;
}

Что происходит, так это то, что я вызываю анонимную функцию, когда таймер попадает, и из этой функции выполняем мой functioncall для установки.

Надеюсь, это поможет. Jonas

Ответ 4

Проблема здесь в том, что вы используете метод pass-a-string для использования setTimeout. Это в основном просто скрытый eval.

Стоит отметить, что это плохая практика, медленный исполнитель и риск для безопасности.

(см. такие вопросы, как: setTimeout() со строкой или (анонимной) ссылкой на функцию? speedwise)

Причина, по которой эта проблема вызывает вашу проблему, состоит в том, что "seto(" + ele + "," + i + ")" будет оцениваться до "seto('[object HTMLDivElement]', 1)". Вы действительно хотите передать ссылку на объект ele, но значение будет передано в строку, когда вы попытаетесь объединить объект в строку. Вы можете обойти это, используя метод pass-a-function для использования setTImeout.

setTimeout(function() { seto(ele, i); }, i * 1000);

Я считаю, что внесение этого изменения сделает ваше поведение Code2 эквивалентным Code1.

Ответ 5

Ниже приведены полные ответы на мой вопрос

ANS1 --- DEMO

function fin() {
    var i = 0;
    var el = document.getElementById("div1");
    fadeIn(el,i);
}

function fadeIn(el,i) {
    i = i + 0.01;
    seto(el,i);
    if (i<1){setTimeout(function(){fadeIn(el,i);}, 10);}
}

function seto(el,i) {
    el.style.opacity = i;
}

ANS2 --- DEMO

function fin(){
    var i = 0;
    var el = document.getElementById("div1");
    fadeIn(el,i);
}

function fadeIn(el,i) {
    var go = function(i) {
        setTimeout( function(){ seto(el,i); } , i * 1000);
    };
    for ( i = 0 ; i<=1 ; i = i + 0.01) go(i);
}

function seto(el,i)
{
    el.style.opacity = i;
}

Ответ 6

Моя версия

 function fadeIn($element){
  $element.style.display="block";
  $element.style.opacity=0;
  recurseWithDelayUp($element,0,1);
}
function fadeOut($element){
  $element.style.display="block";
  $element.style.opacity=1;
  recurseWithDelayDown($element,1,0);
}

function recurseWithDelayDown($element,startFrom,stopAt){
    window.setTimeout(function(){
      if(startFrom > stopAt ){
          startFrom=startFrom - 0.1;
            recurseWithDelayDown($element,startFrom,stopAt)
            $element.style.opacity=startFrom;
      }else{
        $element.style.display="none"
      } 
  },30);
}
function recurseWithDelayUp($element,startFrom,stopAt){
    window.setTimeout(function(){
      if(startFrom < stopAt ){
          startFrom=startFrom + 0.1;
            recurseWithDelayUp($element,startFrom,stopAt)
            $element.style.opacity=startFrom;
      }else{
        $element.style.display="block"
      } 
  },30);
}

Ответ 7

Я просто улучшил ответ laaposto, чтобы включить обратный вызов. Я также добавил функцию fade_out. Посмотрите ответ laaposto для инструкций по реализации. Вы можете вставить JS ниже в его скрипку и посмотреть пример.

Спасибо, Лаапосто! Это действительно помогло для моего проекта, который требует нулевой зависимости.

function fade_out( element, duration, callback ) {
    element.style.opacity = 0;
    var last = +new Date();
    var tick = function() {
        element.style.opacity = +element.style.opacity + ( new Date() - last ) / duration;
        last = +new Date();
        if ( +element.style.opacity < 1 ) {
            ( window.requestAnimationFrame && requestAnimationFrame( tick ) ) || setTimeout( tick, 16 );
        }
        else {
            callback();
        }
    };
    tick();
}

function fade_out( element, duration, callback ) {
    element.style.opacity = 1;
    var last = +new Date();
    var tick = function() {
        element.style.opacity = +element.style.opacity - ( new Date() - last ) / duration;
        last = +new Date();
        if ( +element.style.opacity > 0 ) {
            ( window.requestAnimationFrame && requestAnimationFrame( tick ) ) || setTimeout( tick, 16 );
        }
        else {
            callback();
        }
    };
    tick();
}

var element = document.getElementById("div1");
fade_out(element, 3000, function(){
    console.log("done");
});

Ура!

Ответ 8

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

Посмотрите на ответ laaposto для инструкций по реализации. Вы можете заменить JS в его скрипке на мой и посмотреть пример.

Спасибо, Лаапосто! Это действительно помогло для моего проекта, который требует нулевых зависимостей.

var el = document.getElementById( "div1" );

function fade_in( element, duration, callback = '' ) {
    element.style.opacity = 0;
    var last = +new Date();
    var tick = function() {
        element.style.opacity = +element.style.opacity + ( new Date() - last ) / duration;
        last = +new Date();
        if ( +element.style.opacity < 1 ) {
            ( window.requestAnimationFrame && requestAnimationFrame( tick ) ) || setTimeout( tick, 16 );
        }
        else {
            if( is_function( callback ) ) {
                callback();
            }
        }
    };
    tick();
}

function fade_out( element, duration, callback = '' ) {
    element.style.opacity = 1;
    var last = +new Date();
    var tick = function() {
        element.style.opacity = +element.style.opacity - ( new Date() - last ) / duration;
        last = +new Date();
        if ( +element.style.opacity > 0 ) {
            ( window.requestAnimationFrame && requestAnimationFrame( tick ) ) || setTimeout( tick, 16 );
        }
        else {
            if( is_function( callback ) ) {
                callback();
            }
        }
    };
    tick();
}

function is_function( object_to_check ) {
    return object_to_check && {}.toString.call( object_to_check ) === '[object Function]';
}

fade_out( el, 3000, function(){ fade_in( el, 3000 ) } );

Ура!