web-dev-qa-db-ja.com

純粋なJavaScriptフェードイン機能

こんにちは。別のdivをクリックしたときにdivをフェードインしたいので、次のコードを使用しています。 Code1は問題なく動作しますが、Code2を使用する必要があります。

私はjQueryがあることを知っていますが、これをJavaScriptで行う必要があります

どんな間違いをしているのか、何を変える必要があるのか​​教えてくれませんか...

Code1 ---正常に動作します

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;
}

Code2 ---機能しません

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;
}
11
kanudo

this サイトに基づく

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 [〜#〜]

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

ここでの問題は、setTimeoutを使用して文字列を渡す方法を使用していることです。これは基本的には隠されたevalです。

これは悪い習慣であり、パフォーマンスが遅く、セキュリティ上のリスクがあることは注目に値します。

(このような質問を参照してください: setTimeout()with string or(anonymous)function reference?speedwise

これが問題を引き起こしている理由は、"seto(" + ele + "," + i + ")""seto('[object HTMLDivElement]', 1)"に評価されるためです。 eleオブジェクトへの参照を渡したいのですが、オブジェクトを文字列に連結しようとしたときに値が文字列にキャストされています。これを回避するには、setTImeoutを使用するpass-a-functionメソッドを使用します。

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

この変更により、Code2の動作がCode1と同等になると思います。

1
sejordan

以下は私の質問に対する完全な回答です

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;
}
1
kanudo

私のバージョン

 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);
}
1
ShAkKiR

要素を文字列に変換しようとしているようです。代わりにこれを試してください

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;
}

ここで何が起こるかというと、タイマーがヒットしたときに無名関数を呼び出し、その関数から関数呼び出しをsettoに実行します。

それが役に立てば幸い。ジョナス

1
Jonas m

コールバックを含めるように、laapostoの回答を改善しました。 fade_out関数も追加しました。より効率的にすることもできますが、私がやっていることにはうまくいきます。

実装手順については、laapostoの回答をご覧ください。彼のフィドルのJSを私のものに置き換えて、例を見ることができます。

Laaposto、ありがとう!これは、依存関係をまったく必要としない私のプロジェクトに本当に役立ちました。

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 ) } );

乾杯!

0
Justin Waulters
function hide(fn){
        var hideEle = document.getElementById('myElement');
        hideEle.style.opacity = 1;
        var fadeEffect = setInterval(function() {
        if (hideEle.style.opacity < 0.1)
        {
        hideEle.style.display='none';
        fn();
        clearInterval(fadeEffect);
        }
        else
        {
        hideEle.style.opacity -= 0.1;
        }
        }, 20);
}
function show(){
        var showEle = document.getElementById('myElement');
        showEle.style.opacity = 0;
        showEle.style.display='block';
            var i = 0;
            fadeIn(showEle,i);
            function fadeIn(showEle,i) {
                i = i + 0.05;
                seto(showEle,i);
                if (i<1){setTimeout(function(){fadeIn(showEle,i);}, 25);}
            }
            function seto(el,i)
            {
                el.style.opacity = i;
            }
}

hide(show);
0
Tony Duran