2017-07-29 15 views
2

私はこれが非常に明白であると感じています。解決された場合、私は恥ずかしくなりますが、私はそれを機能させることができません。機能のグループ化

私は、複数のアイテムが表示されたり、ユーザーがクリックしたりする必要があるhtml + javascriptページを持っています。 だから私は次のようにするdivののx量を持っている:

<div id="myDIVA" style="display:none;">blabla 1</div> 
<div id="myDIVB" style="display:none;">blabla 2</div> 
<div id="myDIVC" style="display:none;">blabla 3</div> 

と彼らはDIVのをクリックすると、隠されたおよび/または示されています

<div onClick="myClickFunctionA()">Show only ONE</div> 
<div onClick="myClickFunctionB()">Show only TWO</div> 
<div onClick="myClickFunctionC()">Show only THREE</div> 

シンプルなスクリプトが行く:

<script> 
    var a = document.getElementById('myDIVA'); 
    var b = document.getElementById('myDIVB'); 
    var c = document.getElementById('myDIVC'); 
function myClickFunctionA() { 
     a.style.display = 'block'; 
     b.style.display = 'none'; 
     c.style.display = 'none'; 
} 
function myClickFunctionB() { 
     a.style.display = 'none'; 
     b.style.display = 'block'; 
     c.style.display = 'none'; 
} 
</script> 

私は何だろう好きなようにグループ化することができるように、私は次のような機能を持つことができます:

function myClickFunctionA() { 
     a.style.display = 'block'; 
     b + c.style.display = 'none'; 
} 

私は多くのdivがあります!だから、これはばかげているように見えるかもしれませんが、より簡単に編集できるように、ヴァールを「グループ化」することができれば、私にとっては意味があります。

だから私は、誰かがアレイ用おそらく良いユースケース おかげ

+2

ダーン。だから、しばしば人々は自分自身で満ちているように見えます。謙虚な人を見てうれしいです。 –

答えて

1

:-)簡単な解決のためにアップしている願っています:

var elemsById = ["myDIVA","myDIVB","myDIVC"] 
.map(id=>[id,document.getElementById(id)]); 

だから我々は、これらの要素のうちの1つを表示したい時はいつでも、我々それらのすべてを反復処理し、非表示/それらを表示、自分のIDに応じて:

function showThisAndHideRest(showId){ 
    elemsById.forEach(function([id,el]){ 
    el.style.display=id===showId?"block":"none"; 
    }); 
} 

だから、あなたが行うことができます。

showThisAndHideRest("myDIVA"); 

注:上部には、まだすべてのブラウザでサポートされていないクールなES6機能が使用されています。エルのそのすでに一部(をel.id)、しかし、私はいくつかのパラメータ化代入を使用していた...

Run

+0

どこが間違っているのかわかりませんが、このコードを実行しようとするとショーは表示されません。私は私がするべきだと思う。

Show NEW VERSION
?? ...(((私はこれをFirefox 52.2.1(32ビット版)とChrome 49.0.2623.112でテストしています - 両方とも最新ではありません))) – morganF

+0

@morganF!私はスニペットを追加します... –

+0

@morganFああ、いいえ!実際にはそのために "myDivA"!== "myDIVA" ...私はそれを申し訳ありません:/ –

1

ようとtheresの配列でIDを格納するために、実際に必要はありません、私はあなたを想定しますは、divごとに別々の機能を持たせたいと考えています。そしてあなたはする必要はありません。 :-)クリックを処理し、divの配列で動作する単一の関数を持つことができます。

まずは、これらのdivの配列を取得してみましょう:

var divs = Array.prototype.slice.call(document.querySelectorAll("[id^=myDIV]")); 

(。。私たちは彼らに共通するクラスを与えることができればそれは良いだろうそのIDの開始によってそれらをつかむこと)

それでは、クリック可能なdivのは、彼らがに関連DIVたと言ってみましょう:次に

<div onClick="myClickFunction('myDIVA')">Show only ONE</div> 

、のクリックを処理する単一の機能を持ってみましょう:

function myClickFunction(id) { 
    divs.forEach(function(div) { 
     div.style.display = div.id === id ? "block" : "none"; 
    }); 
} 

(最後の互換性に関する注意を参照してください。)

onxyz -attribute-styleイベントハンドラを使用すると、一般的には悪い考えです。それらは、使用する関数がグローバルであることが必要です。

代わりに、さんが動的にそれらをフックアップし、彼らはに関連するどのターゲット言ってdata-*属性を使用してみましょう:

// Scoping function to avoid globals 
 
(function() { 
 
    var divs = Array.prototype.slice.call(document.querySelectorAll(".showable")); 
 
    Array.prototype.forEach.call(document.querySelectorAll("div[data-show]"), function(dshow) { 
 
     dshow.addEventListener("click", myClickFunction, false); 
 
    }); 
 

 
    function myClickFunction() { 
 
    var idToShow = this.getAttribute("data-show"); 
 
    divs.forEach(function(div) { 
 
     div.style.display = div.id === idToShow ? "block" : "none"; 
 
    }); 
 
    } 
 
})();
<div data-show="myDIVA">Show A</div> 
 
<div data-show="myDIVB">Show B</div> 
 
<div data-show="myDIVC">Show C</div> 
 
<div class="showable" id="myDIVA">A</div> 
 
<div class="showable" id="myDIVB" style="display: none">B</div> 
 
<div class="showable" id="myDIVC" style="display: none">C</div>

今、私たちはグローバルな機能を持っていない、とマークアップを定義します要素間の関係。


互換性ノート:

あなたが(ないIE8   —のようなと悲しげに、多くの)addEventListenerを持っていない古いブラウザをサポートする必要がある場合は、this answerはあなたが使用することをクロスブラウザhookEvent機能を持っています。

IE8をサポートしている場合は、Array.prototype.forEachではなく、forループを使用する必要があります。IE8にはないため、適度にシムできません(IE8もサポートしていないためです)。 JavaScriptオブジェクトに列挙できないプロパティを追加する)。ここで

+0

@Jonasw:ええ、ちょうど適切なイベント処理のライブサンプルを追加したことに気づいたのです。 :-)ありがとう。 –

+0

そして、nodeListをArray cconversionに置き換えられませんでしたか? –

+0

@ジョナス:何か理由は見当たりません。配列のように使うつもりなら、一度配列を作るのは合理的です。それ以外の場合は、 'forEach'を実行するたびに' .call'を使用する必要があります。 –

0

onclick属性の必要性を取り除くaddEventListenerを使用したソリューションです:

// Select the buttons and items 
 
var buttons = Array.prototype.slice.call(document.querySelectorAll('.showhidebutton')) 
 
var items = Array.prototype.slice.call(document.querySelectorAll('.showhideitem')) 
 

 
// Add a click eventListener for each button 
 
buttons.forEach(function(button, i) { 
 
    button.addEventListener('click', function() { 
 
    // When a button is clicked, loop through the items 
 
    items.forEach(function(item, j) { 
 
     // If this is the item that should be shown, show it 
 
     if (i === j) item.style.display = 'block' 
 
     // Otherwise, hide it 
 
     else item.style.display = 'none' 
 
    }) 
 
    }) 
 
}) 
 

 
// This code hides all but item 1 on pageload 
 
// can remove this code if you don't want that 
 
items.forEach(function(item, j) { 
 
    // Arrays are zero-indexed in JS, so the first item is 0 
 
    if (i === 0) return 
 
    // Hide all the other items 
 
    else item.style.display = 'none' 
 
})
<div class="showhideitem">blabla 1</div> 
 
<div class="showhideitem">blabla 2</div> 
 
<div class="showhideitem">blabla 3</div> 
 

 
<div class="showhidebutton">Show only ONE</div> 
 
<div class="showhidebutton">Show only TWO</div> 
 
<div class="showhidebutton">Show only THREE</div>

+0

querySelectorAllは既にforEachメソッドを持っているNodeListを返します。 –

+1

非標準のforEachがありますが、IEではサポートされていません:https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach – RyanZim

+0

@RyanZim実際には、記事の終わりを見ると、標準を挙げています。彼らが標準にそれを加えたのを見てよかった!そして、IE8 +でそれを簡単にシムにすることができます。しかし、ええ、IEの**バージョン**(それが追加される前にリリースされていたもの)は、それを推奨するときに削除してはならない問題です( '@' Jonas)。 –

0

あなたはclickイベントはセレクタで.querySelectorAll()を使用して期待されている要素のそれぞれに共通のクラスを定義することができます".myClickFunction"、ループを使用してforを使用してNodeListを繰り返します。各要素のElement.datasetを現在の反復インデックスに設定します。要素にclickハンドラを添付します。再び.querySelectorAll()をセレクタ"[id^myDIV]"と使用して、id"myDIV"で始まるすべての要素を選択します。それぞれclickイベントセットごとに"myDIV".style"display:none";インデックスElement.dataset.styleから"display:block""myDIV"を設定します。近くだけで最初の行のためにupvoted

for (var i = 0, el = document.querySelectorAll(".myClickFunction") 
 
    ; i < el.length; i++) { 
 
    el[i].dataset.index = i; 
 
    el[i].onclick = function(event) { 
 
    for (var n = 0, el_ = document.querySelectorAll("[id^=myDIV]") 
 
    ; n < el_.length; n++) { 
 
     el_[n].style.display = "none" 
 
    } 
 
    document.querySelectorAll("[id^=myDIV]")[event.target.dataset.index] 
 
     .style.display = "block" 
 
    } 
 
}
<div id="myDIVA" style="display:none;">blabla 1</div> 
 
<div id="myDIVB" style="display:none;">blabla 2</div> 
 
<div id="myDIVC" style="display:none;">blabla 3</div> 
 
and they are hidden and/or shown by clicking div's: 
 

 
<div class="myClickFunction">Show only ONE</div> 
 
<div class="myClickFunction">Show only TWO</div> 
 
<div class="myClickFunction">Show only THREE</div>

関連する問題