2016-05-25 8 views
2

でコンボボックスドロップダウンを隠す:表示/私は次のようなマークアップを出力asp.netでユーザーコントロールを持っている純粋なJavascriptを

<div id="combobox1"> 
    <div id="combobox1_text"><span>combobox 1</span></div> 
    <div id="combobox1_ddl"> 
    <input type="checkbox" id="combobox1_$1" /> 
    <label for="combobox1_$1">Item 1</label> 
    <br /> 
    <input type="checkbox" id="combobox1_$2" /> 
    <label for="combobox1_$2">Item 2</label> 
    <br /> 
    <input type="checkbox" id="combobox1_$3" /> 
    <label for="combobox1_$3">Item 3</label> 
    <br /> 
    <input type="checkbox" id="combobox1_$4" /> 
    <label for="combobox1_$4">Item 4</label> 
    <br /> 
    <input type="checkbox" id="combobox1_$5" /> 
    <label for="combobox1_$5">Item 5</label> 
    <br /> 
    </div> 
</div> 

この制御を伴うジャバスクリプトファイルには、再現するために以下のクラス(最小限のコードを持っています問題のみ):

ComboBox = function(cb) { 
    var pnlContainer = document.getElementById(cb); 
    var pnlComboBox = document.getElementById(cb + '_text'); 
    var pnlDropdownList = document.getElementById(cb + '_ddl'); 
    var isCollapsed = true; 

    var collapseDropdown = function() { 
    if (!isCollapsed) { 
     isCollapsed = true; 
     pnlDropdownList.style.display = 'none'; 
     //-- some more custom handling code follows here -- 
    } 
    }; 
    pnlComboBox.onclick = function() { 
    isCollapsed = !isCollapsed; 
    pnlDropdownList.style.display = (isCollapsed) ? 'none' : 'block'; 
    }; 
    pnlContainer.onclick = function(event) { 
    event.stopPropagation(); 
    }; 
    document.addEventListener('click', function() { 
    collapseDropdown(); 
    }, false); 
} 

そして最後には、私のページに私はこのようなクラスのインスタンスを作成します。

cb1 = new ComboBox('combobox1'); 

このコントロールのインスタンスが1つしかない限り、これはすべて正常に機能します。コントロールの外側の何かがクリックされると、まるで期待通りに正しく折りたたまれます。

問題:

ページ上のこのコントロールの複数のインスタンスが存在する場合に問題が起こります。コンボボックスの1つが開いていて、ユーザーがコンボボックスの別のインスタンスをクリックした場合、前のコンボボックスは折り畳まれません。問題を再現する最小限のコードため

JsFiddleは、ここで見つけることができます:

https://jsfiddle.net/x8qjo79f/

私はそれが理由のevent.stopPropagation()コールが起こっている知っているが、これのために何をすべきかわかりません。

答えて

2

編集イベントをキャプチャ(それはバブリング段階の前に実行される)、そのターゲットがあなたの外にあるときに崩壊する文書のonclickイベントリスナコンボボックス。

ComboBox = function(cb) { 
 
    var pnlContainer = document.getElementById(cb); 
 
    var pnlComboBox = document.getElementById(cb + '_text'); 
 
    var pnlDropdownList = document.getElementById(cb + '_ddl'); 
 
    var isCollapsed = true; 
 

 
    var collapseDropdown = function() { 
 
    if (!isCollapsed) { 
 
     isCollapsed = true; 
 
     pnlDropdownList.style.display = 'none'; 
 
     //-- some more custom handling code follows here -- 
 
    } 
 
    }; 
 
    pnlComboBox.onclick = function() { 
 
    isCollapsed = !isCollapsed; 
 
    pnlDropdownList.style.display = (isCollapsed) ? 'none' : 'block'; 
 
    }; 
 
    pnlContainer.onclick = function(event) { 
 
    event.stopPropagation(); 
 
    }; 
 

 
    // Edit: Capture click event 
 
    document.addEventListener('click', function(event) { 
 
    if (!pnlContainer.contains(event.target)) collapseDropdown(); 
 
    }, true); 
 
} 
 

 
cb1 = new ComboBox('combobox1'); 
 
cb2 = new ComboBox('combobox2');
#combobox1, 
 
#combobox2 { 
 
    border: 1px solid black; 
 
    cursor: default; 
 
    width: 200px; 
 
    font-family: verdana; 
 
    font-size: 10pt; 
 
} 
 

 
#combobox1_text, 
 
#combobox2_text { 
 
    padding: 2px; 
 
} 
 

 
#combobox1_ddl, 
 
#combobox2_ddl { 
 
    border-top: 1px solid black; 
 
    display: none; 
 
}
<div id="combobox1"> 
 
    <div id="combobox1_text"><span>combobox 1</span></div> 
 
    <div id="combobox1_ddl"> 
 
    <input type="checkbox" id="combobox1_$1" /> 
 
    <label for="combobox1_$1">Item 1</label> 
 
    <br /> 
 
    <input type="checkbox" id="combobox1_$2" /> 
 
    <label for="combobox1_$2">Item 2</label> 
 
    <br /> 
 
    <input type="checkbox" id="combobox1_$3" /> 
 
    <label for="combobox1_$3">Item 3</label> 
 
    <br /> 
 
    <input type="checkbox" id="combobox1_$4" /> 
 
    <label for="combobox1_$4">Item 4</label> 
 
    <br /> 
 
    <input type="checkbox" id="combobox1_$5" /> 
 
    <label for="combobox1_$5">Item 5</label> 
 
    <br /> 
 
    </div> 
 
</div> 
 
<br /> 
 
<input type="text" /> 
 
<br /> 
 
<input type="button" /> 
 
<br /> 
 
<input type="checkbox" /> 
 
<br /> 
 
<span>some random text in the document.. <br />blah. blah.. blah..</span> 
 
<br /> 
 
<br /> 
 
<br /> 
 
<div id="combobox2"> 
 
    <div id="combobox2_text"><span>combobox 2</span></div> 
 
    <div id="combobox2_ddl"> 
 
    <input type="checkbox" id="combobox2_$1" /> 
 
    <label for="combobox2_$1">Item 1</label> 
 
    <br /> 
 
    <input type="checkbox" id="combobox2_$2" /> 
 
    <label for="combobox2_$2">Item 2</label> 
 
    <br /> 
 
    <input type="checkbox" id="combobox2_$3" /> 
 
    <label for="combobox2_$3">Item 3</label> 
 
    <br /> 
 
    <input type="checkbox" id="combobox2_$4" /> 
 
    <label for="combobox2_$4">Item 4</label> 
 
    <br /> 
 
    <input type="checkbox" id="combobox2_$5" /> 
 
    <label for="combobox2_$5">Item 5</label> 
 
    <br /> 
 
    </div> 
 
</div>

+0

私はもともと 'onblur'イベントでドロップダウンの崩壊がありました。問題はクロムブラウザで、ドロップダウンエリアのチェックボックスをクリックするとすぐにドロップダウンを折りたたむことです。ユーザーがコンボボックスの外側をクリックするか、コンボボックスのテキスト領域をクリックして折り畳むまで、開いておきたいです。 –

+0

私の答えは –

+0

です。非常に良いです。私はこの後に 'event.stopPropagation()'コールがもう必要なくなり、 'pnlContainer.onclick'イベント処理を完全に取り除くことができることを知りました。 –

2

pnlContainer.onclickでイベントの伝達を許可することができますが、ComboBoxがクリックされたことを忘れないでください。ドキュメントクリックイベントハンドラの内部では、ComboBoxがクリックされたかどうかをテストし、ComboBoxがクリックされていない場合にのみ折りたたむことができます。

Javascriptのコードの変更次のようになります。

ComboBox = function(cb) { 
    var isClicked = false; 
    ... 
    pnlContainer.onclick = function(event) { 
    isClicked = true; 
    }; 
    document.addEventListener('click', function() { 
    if (isClicked) { 
     isClicked = false; 
    } 
    else { 
     collapseDropdown(); 
    } 
    }, false); 
} 
+1

'するevent.stopPropagation()'の呼び出しを取り除くためニースのトリック。私はおそらく一方向だけを見ていただろう。 –

関連する問題