2016-07-05 17 views
0

JavaScript/jQueryで時間を把握するためにJavaScript/jQueryを解析して特定の時間後にコンテンツを非表示にしようとしています。それをより明確にするために、私はこれらの例を与えている:HTMLクラス名で指定された時間が経過した後、jQueryでコンテンツを非表示にする

<div id="one" class="some-class some-other-class timeout-3500"> </div> 
<div id="two" class="another-irrelevant-class timeout-2000"> </div> 

スクリプトは、2000ミリ秒後に3500ms後div「1」、およびdiv「2」を非表示にします。次のように

バニラJavaScriptでjQueryライブラリを組み合わせ

これまでの私のコードは、次のとおりです。https://jsfiddle.net/56o57t0j/

$('div[class*="timeout-"]').each(function() 
{ 
    var classList = $(this).attr('class').split(/\s+/); 

    var timeoutDelay; 

    for (var i = 0; i < classList.length; i++) 
    { 
     if (classList[i].includes('timeout-')) 
     { 
      timeoutDelay = parseInt(classList[i].split('-').pop(), 10); 

      setTimeout(function() 
      { 
       $(this).hide(); 
      }, timeoutDelay); 
     } 
    } 
}); 

ここで実証する(非稼働)フィドルです。

setTimeout火災ですが、$(this).hide();は何もしません。これは、jQueryで何も選択されていないようです(すべてのコードがeach()のセレクタブロック内にあるので、もちろん当てはまりません)。

これに関する助力?私は朝から悩んでいます。前もって感謝します。

+1

'setTimiout'の中の' this'は 'window'です。 'setTimiout'呼び出しをクロージャにラップします。 –

+0

参考までに、[この "この"問題(https://developer.mozilla。org/ja-ja/docs/Web/API/WindowTimers/setTimeout#The_this_problem)。 – showdev

+3

データ属性を使用する必要があります。クラス名の解析は必要ありません – epascarello

答えて

1

タイムアウト機能を正しいスコープでバインドする必要があります。スコープとバインディングはJSのかなり高度なトピックですが、最初は混乱する可能性がありますが、「タイムアウト」は非同期で実行されているため、実際には親の「各」ループの範囲外で実行されます。したがって、「this」は実行時には分かりません。あなたは以下のような機能をバインドする場合、それは動作します:私は、実施例とあなたのフィドルをフォークしている

setTimeout(function() { 
    $(this).hide(); 
}.bind(this), timeoutDelay); 

https://jsfiddle.net/jg7m6cyu/1/

MDNが「バインド」はどのように機能するかに大きな記事があります。 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

0

問題は、setTimeoutが関数と異なるコンテキストで呼び出されるという問題です。したがって、setTimeoutの "this"は関数の "this"と同じではありません。その変数を "その"変数にコピーすると、関数のコンテキストが保存されます。 OP this

$('div[class*="timeout-"]').each(function() { 
 
    var classList = $(this).attr('class').split(/\s+/); 
 
    var timeoutDelay; 
 
    //need to lexically bind this because setTimeout is a different calling context 
 
    var that=this; 
 
    for (var i = 0; i < classList.length; i++) { 
 
    if (classList[i].includes('timeout-')) { 
 
     timeoutDelay = parseInt(classList[i].split('-').pop(), 10); 
 

 
     setTimeout(function() { 
 
     $(that).hide(); 
 
     }, timeoutDelay); 
 
    } 
 
    } 
 
});
* { 
 
    font-family: "Tahoma", sans-serif; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> 
 
<div class="some-class some-other-class timeout-3500"> 
 
    First div. 
 
</div> 
 
<div class="yet-another-div with-some-class timeout-2000"> 
 
    Second div. 
 
</div>

+0

ループ内では、 'it'は繰り返しごとに変化します( –

+0

ありがとうございました、タイムアウトを得るためにクラスをループしているという事実 – kingd9

+0

'that'は' $(...)。each'ループ内でまだ変更されています;( –

-1

setTimiout内部windowあります。 setTimioutを閉じてクロージャを呼び出します。 このコードは動作します。

私はあなたがデータ属性を使うべきだと思う
for (var i = 0; i < classList.length; i++) 
{ 
    if (classList[i].includes('timeout-')) 
    { 
     timeoutDelay = parseInt(classList[i].split('-').pop(), 10); 

     (function(elem,timeout){ 
      setTimeout(function() 
      { 
       $(elem).hide(); 
      }, timeout); 
     })(this,timeoutDelay); //this comes from $(...).each 
    }//if 
}//for 
0

、このような何か:

HTML

<div id="one" class="some-class some-other-class delayed" data-timeout="3500"> </div> 
<div id="two" class="another-irrelevant-class delayed" data-timeout="2000"> </div> 

jQueryの

$('div.delayed').each(function() 
{ 
    var timeoutDelay = $(this).data('timeout'), 
     el = $(this); 

    setTimeout(function() 
    { 
     el.hide(); 
    }, timeoutDelay); 
}); 

DEMO

+0

データ属性を使用することをお勧めします。 – BrianR

関連する問題