2016-12-17 5 views
1

このIDを使用して特定の場所をアニメーション化するこのjavascriptを作成しました。 問題は、サイトに多くのものがあり、getElementById( "x")のxを置き換えるだけで、この関数を何度も複製する必要があることを意味します。だからここidの代わりにクラスベースのJSを作成する

は、私は完全に自分自身で行うコードです:

var popcount = 0; 
var opanumber = 1; 
var poptimeout; 
function pop() { 
    if (popcount < 10) { 
     popcount++; 
     if (opanumber == 1) { 
     document.getElementById("nav1").style.opacity = 0; 
     opanumber = 0; 
     poptimeout = setTimeout("pop()", 50); 
     } 
     else { 
     document.getElementById("nav1").style.opacity = 1; 
     opanumber = 1; 
     poptimeout = setTimeout("pop()", 50); 
     } 
    } 
    else { 
    popcount = 0; 
    document.getElementById("nav1").style.opacity = 1; 
    } 
} 

function stoppop() { 
    clearTimeout(poptimeout); 
    popcount = 0; 
    document.getElementById("nav1").style.opacity = 1; 
} 

私は喜んで、私はこのような状況を解決し、またクラスと、「これを」使用についてのチュートリアルができる方法上の任意の情報をいただければ幸いです。

+0

でも、あなたは既に問題を認識しました。これは、あなたが 'nav1'パラメータをハードコーディングしたという事実です。ここでは、関数にパラメータを追加する方法を知っていると仮定しています。これらのパラメータを関数内で再利用できます。あなたが考えなければならない別のことは、文字列のアプローチでsetTimeoutは、非常に日付の付いたaproachに慣れています。匿名関数を定義し、その無名関数内からpop関数を呼び出してください。もう一つの小さな点は、これは作業コードですので、[codereview](http://codereview.stackexchange.com)はあなたの質問のためのより良い場所になるかもしれません – Icepickle

+0

私の関数にパラメータを追加すると動作するようになりました(試しました)。私はパラメータのgetElementByIdすることができないようです。 "+ 'p1 +'" 'を試してみてください。 setTimeoutはうまくいくかもしれませんが、onmouseoverの機能IDが必要でしょうか? – MrMeDo

答えて

2

このようなものです。値を関数にハードコードするのではなく、複数の関数で関数を再利用できるように、値を渡す方がよいでしょう。この場合、CSSクラスの名前でstartPopとstopPopを呼び出すことができます。

var popTimeout; 

function setOpacity(className, value) { 
    Array.prototype.forEach.call(
     document.getElementsByClassName(className), 
     function(el) { 
      el.style.opacity = value; 
     } 
    ); 
} 

function pop(className, popCount, opaNumber) { 
    if (popCount < 10) { //Must be even number so you end on opacity = 1 
     setOpacity(className, opaNumber); 
     popTimeout = setTimeout(function() { 
      pop(className, popCount++, 1-opaNumber); 
     }, 50); 
    } 
} 

function startPop(className) { 
    pop(className, 0, 0); 
} 

function stopPop(className) { 
    clearTimeout(popTimeout); 
    setOpacity(className, 1); 
} 

この= 0 1-1及び1-0 = 1のように1と0の間の値を切り替える簡単な方法である1 - opaNumber;について不思議に思っている場合。

+0

ありがとうございますが、私は "Uncaught TypeError:document.getElementsByClassName(...)。forEachは関数ではありません"クラスを設定し、コードをフィッティングした後に取得します;/ – MrMeDo

+0

このようなものが必要です:https:// jsfiddle.net/2b9304ur/ https://toddmotto.com/ditch-the-array-foreach-call-nodelist-hack/ – sinisake

+0

各ノードをサポートしていないダムノードのリストです。やってみよう。 –

1

さて、あなたは、あなたが問題を持っており、それはすでに良いことだところ認識:)

もう少しコンパクトなコードを作成し、ローカルスコープの外に、できるだけ多くのものを得るためにと始めました次の実装をチェックできます。

私は可能な限り多くのコメントを追加しようとしたのは、ちょっとしたデモです。

IDの代わりにクラス名を使用したいと思った後にもう少し編集しました:)その結果、私はちょっとだけ自由を与えるdocument.querySelectorAllを使用しています。

有効なセレクタでstartPop関数を呼び出すことができます。あなたはクラス

startPop('.className'); 

自体も追加たとえば行きたい場合は、別の関数、NLトリガが、それはどのようにあなたを示しています

startPop('#elementId'); 

のか:あなたは純粋にIDにポップアップ表示したい場合は、使用することができます機能を開始/停止することができます。

また、setTimeoutメソッドの代わりにsetIntervalメソッドを使用することを選択しました。どちらの関数も一定のミリ秒後に関数をコールバックしますが、setIntervalは一度だけ呼び出す必要があります。

さらに、stopPopは関数と同じ自由度を持つように、document.querySelectorAllを使用するようになりました。

startPop関数に2つのオプションのパラメータ、つまりtotalcallbackを追加しました。

合計は、要素を「点滅」させたい時間を示し、コールバックはポップが終了したときに通知を受け取る方法を提供します(ポップを開始した可能性のある要素を更新するなど)

私はあなたがjavascriptの

'use strict'; 
 

 
function getElements(className) { 
 
    // if it is a string, assume it's a selector like #id or .className 
 
    // if not, assume it's an element 
 
    return typeof className === "string" ? document.querySelectorAll(className) : [className]; 
 
} 
 

 
function startPop(className, total, callback) { 
 
    // get the element once, and asign a value 
 
    var elements = getElements(className), 
 
    current = 0; 
 
    var interval = setInterval(function() { 
 
    var opacity = ++current % 2; 
 
    // (increase current and set style to the left over part after dividing by 2) 
 
    elements.forEach(function(elem) { elem.style.opacity = opacity }); 
 
    // check if the current value is larger than the total or 10 as a fallback 
 
    if (current > (total || 10)) { 
 
     // stops the current interval 
 
     stopPop(interval, className); 
 
     // notifies that the popping is finished (if you add a callback function) 
 
     callback && callback(); 
 
    } 
 
    }, 50); 
 
    // return the interval so it can be saved and removed at a later time 
 
    return interval; 
 
} 
 

 
function stopPop(interval, className) { 
 
    // clear the interval 
 
    clearInterval(interval); 
 
    // set the opacity to 1 just to be sure ;) 
 
    getElements(className).forEach(function(elem) { 
 
    elem.style.opacity = 1; 
 
    }); 
 
} 
 

 
function trigger(eventSource, className, maximum) { 
 
    // get the source of the click event (the clicked button) 
 
    var source = eventSource.target; 
 
    // in case the attribute is there 
 
    if (!source.getAttribute('current-interval')) { 
 
    // start it & save the current interval 
 
    source.setAttribute('current-interval', startPop(className, maximum, function() { 
 
     // completed popping (set the text correct and remove the interval) 
 
     source.removeAttribute('current-interval'); 
 
     source.innerText = 'Start ' + source.innerText.split(' ')[1]; 
 
    })); 
 
    // change the text of the button 
 
    source.innerText = 'Stop ' + source.innerText.split(' ')[1]; 
 
    } else { 
 
    // stop it 
 
    stopPop(source.getAttribute('current-interval'), className); 
 
    // remove the current interval 
 
    source.removeAttribute('current-interval'); 
 
    // reset the text of the button 
 
    source.innerText = 'Start ' + source.innerText.split(' ')[1]; 
 
    } 
 
}
<div class="nav1"> 
 
    test navigation 
 
</div> 
 
<div class="nav2"> 
 
    Second nav 
 
</div> 
 
<div class="nav1"> 
 
    second test navigation 
 
</div> 
 
<div class="nav2"> 
 
    Second second nav 
 
</div> 
 
<a id="navigation-element-1" 
 
    onmouseover="this.interval = startPop(this)" 
 
    onmouseout="stopPop(this.interval, this)">Hover me to blink</a> 
 

 
<button type="button" onclick="trigger(event, '.nav1', 100)"> 
 
    Start nav1 
 
</button> 
 
<button type="button" onclick="trigger(event, '.nav2', 100)"> 
 
    Start nav2 
 
</button>

+0

私はまだdownvoteについて興味があります(私は間違いなく最初に疑問を理解しましたが、十分に追加/修正したと思います) – Icepickle

+0

基本的に私はonmouseover私の状況)、ちょうど1つ。だから、イドもうまくいくかもしれない。実際にonmouseover = "pop( 'nav1')"のようにしてIDの変数を実際に得ることができることを知った後、私は実際にこの方法を思いついた。私がしなければならなかったことは、それらを使用することだけでした。 今のところ、関数のタイムアウトで値が "undefined"に変わるということは、関数が2回目に役に立たないことを意味します。だから私はタイムアウトの権利と別の方法を行う必要がありますね? – MrMeDo

+0

@MrMeDoええ、匿名関数を使用するかどうかは、setIntervalで使用したようにいくつかの方法でチェックしてください。すでにpop関数で定義されているパラメータがあるので、setTimeoutメソッドを呼び出すときにその値を再利用できます。バージョンもあなたの計画(そして両方ともクラスとしてのIDを持っている)で動作します) – Icepickle

0

インライン用this構文を使用して要素の上にマウスのためにそれを使用できるようにするために、もう少しそれを変更IDを使用することに戻したい場合は、一度に複数の要素でこれを実行する場合は、popTimeoutについて考える必要があります。

function setOpacity(id, value) { 
    document.getElementById(id).style.opacity = value; 
} 

function runPop(id) { 
    function pop(id, popCount, opaNumber) { 
     if (popCount < 10) { //Must be even number so you end on opacity = 1 
      setOpacity(id, opaNumber); 
      popTimeout = setTimeout(function() { 
       pop(id, popCount++, 1-opaNumber); 
      }, 50); 
     } 
    } 

    var popTimeout; 

    pop(id, 0, 0); 

    return function() { 
     clearTimeout(popTimeout); 
     setOpacity(id, 1); 
    } 
} 

var killPop = []; 

function startPop(id) { 
    killPop[id] = runPop(id); 
} 

function stopPop(id) { 
    killPop[id](); 
} 
関連する問題