2017-09-09 11 views
0

javscriptでスライダを作成しようとしています。私は2つの関数、最初にparseDom()、DOMから要素を取得する責任がある必要があります。 2番目のものconfigureRange()は、minmaxの値のような範囲属性を設定する必要があります。両方の関数は、window.onload変数に割り当てられた匿名関数の内部で呼び出されます。これらの関数内の変数が異なるスコープにあるためJavaScript関数は別の関数スコープの変数にアクセスできません

function parseDom() { 
    var main = document.getElementById('main'); 
    main.classList.add('red'); 
    // red class added - main selector is ok 
    var rangeContainer = main.querySelector('.range-container'); 
    rangeContainer.classList.add('green'); 
    // green class added - rangeContainer selector is ok 
    var rangeInput = rangeContainer.querySelector('.range-input'); 
    rangeInput.classList.add('crosshair'); 
    // crosshair class added - rangeInput selector is ok 

} 

function configureRange(){ 
    rangeInput.classList.add('pointer'); 
    rangeInput.setAttribute('min', '0'); 
} 

window.onload = function(){ 
    parseDom(); 
    configureRange(); 
} 

はしかし、parseDom()からの変数は、configureRange()からaccesedすることはできません。だからconfigureRange()のコードが動作しません。私は2つではなく1つの機能ですべてを行うことができますが、これはコードを乱雑にするでしょう。優れたモジュールソリューションを作成するにはどうすればよいですか?

コードはここにある: https://codepen.io/t411tocreate/pen/oeKwbW?editors=1111

+1

関数にパラメータを渡します。 – Script47

答えて

2

最も簡単なものはparseDomはそれを呼び出すことによって、それが必要configureRange情報を渡すために、おそらくです:

...またはコントローラ機能を有することにより、( parseAndConfigure、どんなものでも)入力をルックアップし、両方の関数に渡します。


サイドノート:小さな機能を維持し、名前を確保するという点では、それが何をするかの指標である(あなたの目標のようだとして)、parseDomは何かを解析しませんし、それだけで特定するだけではありません関連するDOM要素(クラスも追加します)。おそらく3つの機能:getDom,addClasses、およびconfigureRangeまたはそれに類するもの。次に:

window.onload = function() { 
    var dom = getDom(); 
    addClasses(dom); 
    configureRange(dom); 
} 

...などです。

+0

理想的なソリューションは、コード内で何が起こっているのかを明確に定義し、変数との衝突の可能性を排除する2番目のソリューションです。 – Script47

+0

@ Script47:そうですね、私の意見もあります。それは本当にその行の上にあってはいないはずですが、私は今のところ他の答えがあることを知っているからです([adeneo's](https://stackoverflow.com/a/46133778/157247 ))どこにそれが属しているのですか。 (getDom関数がなくても、[A Macdonald's](https://stackoverflow.com/a/46133795/157247)) –

0

あなたが好きなように多くの関数に引数として渡す、その後、.onloadの内側にあなたの変数を宣言することができます:

function parseDom(main, rangeContainer, rangeInput) { // <= arguments 
    main.classList.add('red'); 
    rangeContainer.classList.add('green'); 
    rangeInput.classList.add('crosshair'); 
} 

function configureRange(rangeInput){ // <= argument 
    rangeInput.classList.add('pointer'); 
    rangeInput.setAttribute('min', '0'); 
} 

window.onload = function(){ 
    var main = document.getElementById('main'), 
    rangeContainer = main.querySelector('.range-container'), 
    rangeInput = rangeContainer.querySelector('.range-input'), 
    // other elements 
    parseDom(main, rangeContainer, rangeInput); // <= pass as arguments 
    configureRange(rangeInput); // <= pass as argument 
} 
+1

まったく良いアイデアはありません。これはまさに['code smell'](https://stackoverflow.com/questions/5063878/how-to-cleanly-deal-with-global-variables)です。より良いオプションはパラメータを渡すことです。 – Script47

+0

@ Script47同じ要素を操作する数十の関数がある場合は、モジュール性に優れています。 –

+0

@ T.J.Crowderの2番目の解決策を見てください。それは、あなたが提起したシナリオを扱うでしょう。 – Script47

1

は、あなたがオブジェクトに要素を維持し、その後であるためには、そのオブジェクトを返すことができますどこか他の再利用

function parseDom() { 
    var els = (function(d) { 
    var main   = d.getElementById('main'), 
     rangeContainer = main.querySelector('.range-container'), 
     rangeInput  = rangeContainer.querySelector('.range-input'); 

    return {main, rangeContainer, rangeInput}; 
    })(document); 

    els.main.classList.add('red'); 
    els.rangeContainer.classList.add('green'); 
    els.rangeInput.classList.add('crosshair'); 

    return els; 
} 

function configureRange(els) { 
    els.rangeInput.classList.add('pointer'); 
    els.rangeInput.setAttribute('min', '0'); 

    return els; 
} 

window.onload = function() { 
    var elems = parseDom(); 
    configureRange(elems); 
} 
1

最も簡単な方法は、多分、代わりにそのupdateDomを呼び出して、トップレベル関数などでセレクターを解析し、離れparseDom機能からセレクタ抽象的になります

function updateDom(main, rangeContainer, rangeInput) { 
    main.classList.add('red'); 
    // red class added - main selector is ok 

    rangeContainer.classList.add('green'); 
    // green class added - rangeContainer selector is ok 

    rangeInput.classList.add('crosshair'); 
    // crosshair class added - rangeInput selector is ok 

} 

function configureRange(rangeInput){ 
    rangeInput.classList.add('pointer'); 
    rangeInput.setAttribute('min', '0'); 
} 

window.onload = function(){ 
    var main = document.getElementById('main'), 
    rangeContainer = main.querySelector('.range-container'), 
    rangeInput = rangeContainer.querySelector('.range-input'); 

    updateDom(main, rangeContainer, rangeInput); 
    configureRange(rangeInput); 
} 
関連する問題