2017-11-17 2 views
2

HTML、CSS、およびバニラのJavascriptを使用してカスタムドロップダウンメニューを作成しようとしています。カスタムドロップダウンメニューを作成し、データセットの値を入力します。

"from"入力フィールドをクリックしたときにメニューを表示することができましたが、オプションを試してクリックすると、 "code"フィールドに保存されている値を追加することはできません。データセット。

私はsetTimeoutメソッドを使用して動作するようになりましたが、時には少しヒットしてしまい、良い解決策のように見えません。

これを動作させる別の方法はありますか? setTimeoutを使用して

function app() { 
 

 
    var messages = document.querySelector(".messages"); 
 

 
    var inputFrom = document.querySelector(".input-from"); 
 

 
    var inputTo = document.querySelector(".input-to"); 
 

 
    var nearestContainer = document.querySelector(".nearest-container"); 
 

 
    inputFrom.addEventListener("focus", inputToFocusIn, false); 
 

 
    function inputToFocusIn(e) { 
 

 
    messages.innerHTML = "focusin event triggered on input-from"; 
 

 
    // add class 
 
    inputFrom.classList.add("input-from--focusin"); 
 
    nearestContainer.classList.add("nearest-container--active"); 
 

 
    // remove class 
 
    inputFrom.classList.remove("input-from--focusout"); 
 
    nearestContainer.classList.remove("nearest-container--hidden"); 
 

 
    } 
 

 
    inputFrom.addEventListener("focusout", inputToFocusOut, false); 
 

 
    function inputToFocusOut(e) { 
 

 
    messages.innerHTML = "focusout event triggered on input-from"; 
 

 

 
     // add class 
 
     inputFrom.classList.remove("input-from--focusin"); 
 
     nearestContainer.classList.remove("nearest-container--active"); 
 

 
     // remove class 
 
     inputFrom.classList.add("input-from--focusout"); 
 
     nearestContainer.classList.add("nearest-container--hidden"); 
 

 
    } 
 

 
    var nearestStations = document.querySelectorAll(".nearest-station"); 
 

 
    // add event listener to buttons 
 
    for(var nearestStation of nearestStations) { 
 

 
    nearestStation.addEventListener("click", addToInputFrom, false); 
 

 
    } 
 

 
    function addToInputFrom(e) { 
 

 
    inputFrom.classList.add("input-from--focusout"); 
 
    nearestContainer.classList.add("nearest-container--hidden"); 
 

 
    inputFrom.classList.remove("input-from--focusin") 
 
    nearestContainer.classList.remove("nearest-container--active") 
 

 
    var targetDataset = e.currentTarget.dataset.code; 
 

 
    messages.innerHTML = "station added to input from field" 
 

 
    inputFrom.value = ""; 
 
    inputFrom.value = targetDataset; 
 

 
    } 
 

 
    var switchButton = document.querySelector(".button-switch"); 
 

 
    switchButton.addEventListener("click", clickSwitch, false); 
 

 
    function clickSwitch(e) { 
 

 
    var inputFromValue = inputFrom.value; 
 
    var inputToValue = inputTo.value; 
 

 
    inputFrom.value = inputToValue; 
 
    inputTo.value = inputFromValue; 
 

 
    } 
 

 
} 
 

 
window.onload = app();
/* stylesheet */ 
 

 
body { 
 
\t font-family: "GRAPHIK"; 
 
\t font-style: normal; 
 
\t font-weight: 400; 
 
\t font-size: 16px; 
 
\t color: #242424; 
 
} 
 

 
* { 
 
\t box-sizing: border-box; 
 
\t outline: none; 
 
} 
 

 
.container { 
 
\t display: flex; 
 
\t flex-direction: column; 
 
\t justify-content: center; 
 
\t align-items: center; 
 
\t width: 100vw; 
 
\t height: 100vh; 
 
\t background-color: #FF4136; 
 
} 
 

 
.search-container { 
 
\t display: flex; 
 
\t flex-direction: column; 
 
\t flex-shrink: 0; 
 
\t width: 300px; 
 
\t padding: 10px; 
 
\t background-color: #FFF; 
 
\t border-radius: 10px; 
 
} 
 

 
.form-container { 
 
\t display: flex; 
 
\t flex-direction: row; 
 
\t width: 100%; 
 
} 
 

 
.input-container { 
 
\t width: 100%; 
 
} 
 

 
.input { 
 
\t width: 100%; 
 
\t border: none; 
 
\t border-radius: 10px; 
 
\t background-color: #f1f1f1; 
 
\t padding: 10px; 
 
} 
 

 
.input-from { 
 
\t margin-bottom: 5px; 
 
} 
 

 
.input-from--focusout { 
 
\t border-radius: 10px; 
 
} 
 

 
.input-from--focusin { 
 
\t border-radius: 10px 10px 0 0; 
 
} 
 

 
.input-to { 
 
\t margin-bottom: 5px; 
 
} 
 

 
.switch-container { 
 
\t \t margin-bottom: 5px; 
 
} 
 

 
.button { 
 
\t border: none; 
 
\t background-color: transparent; 
 
} 
 

 
.button-switch { 
 
\t height: 100%; 
 
\t width: 38px; 
 
\t margin-left: 5px; 
 
\t background-color: #f1f1f1; 
 
\t border-radius: 10px; 
 
\t background-image: url(../assets/images/switch.svg); 
 
\t background-position: center; 
 
\t background-size: 20px; 
 
\t background-repeat: no-repeat; 
 
} 
 

 
.button-switch:hover { 
 
\t background-image: url(../assets/images/switch-hover.svg); 
 
} 
 

 
.button-search { 
 
\t padding: 10px; 
 
\t background-color: #2ECC40; 
 
\t color: #FFF; 
 
\t border-radius: 10px; 
 
\t width: 100%; 
 
\t transition: background-color 0.5s ease; 
 
} 
 

 
.button-search:hover { 
 
\t background-color: #33e147; 
 
} 
 

 
.input-container-to { 
 
\t \t position: relative; 
 

 
} 
 

 
.nearest-container { 
 
\t position: absolute; 
 
\t top: 38px; 
 
\t background-color: #f1f1f1; 
 
\t padding: 5px; 
 
\t border-radius: 0 0 10px 10px; 
 
\t width: 100%; 
 
\t z-index: 100; 
 
} 
 

 
.messages { 
 
\t width: 300px; 
 
\t background-color: #FFF; 
 
\t padding: 5px; 
 
\t border-radius: 10px; 
 
\t text-align: center; 
 
\t margin-bottom: 5px; 
 
\t font-size: 10px; 
 
} 
 

 
.finding, .show-more { 
 
\t width: 100%; 
 
\t font-size: 10px; 
 
\t font-style: italic; 
 
\t margin: 0; 
 
\t padding: 5px; 
 
} 
 

 
.show-more { 
 
\t text-align: center; 
 
} 
 

 
.nearest-station { 
 
\t font-size: 10px; 
 
\t padding: 5px; 
 
\t border-radius: 10px; 
 
} 
 

 
.nearest-container--hidden { 
 
\t display: none; 
 
} 
 

 
.nearest-station--active { 
 
\t display: flex; 
 
} 
 

 
.nearest-station:hover { 
 
\t background-color: #FFF; 
 
\t cursor: pointer; 
 
} 
 

 
.logo { 
 
\t margin-right: 5px; 
 
} 
 

 
.nr-logo { 
 
\t width: 15px; 
 
} 
 

 
.station-distance { 
 
\t font-style: italic; 
 
\t float: right; 
 
}
<div class="container"> 
 

 
\t \t \t <div class="messages">messages here</div> 
 

 
\t \t \t <div class="search-container"> 
 

 
\t \t \t \t <div class="form-container"> 
 

 
\t \t \t \t \t <div class="input-container"> 
 

 
\t \t \t \t \t <div class="input-container-to"> 
 

 
\t \t \t \t \t \t <input type="text" class="input input-from" placeholder="From"> 
 

 
\t \t \t \t \t \t <div class="nearest-container nearest-container--hidden"> 
 

 

 

 
\t \t \t \t \t \t \t <div class="stations-container"> 
 

 
\t \t \t \t \t \t \t \t <p class="finding">Finding stations closest to you...</p> 
 

 
\t \t \t \t \t \t \t \t <!-- stations here--> 
 

 
\t \t \t \t \t \t \t \t <div class="nearest-station" data-code="Leigh-on-Sea"> 
 

 
\t \t \t \t \t \t \t \t \t <span class="logo"><img class="nr-logo" src="assets/images/nr-logo.svg"></span> 
 
\t \t \t \t \t \t \t \t \t <span class="station-name">Leigh-on-Sea</span> 
 
\t \t \t \t \t \t \t \t \t <span class="station-distance">0.6km</span> 
 

 
\t \t \t \t \t \t \t \t </div> 
 

 
\t \t \t \t \t \t \t \t <div class="nearest-station" data-code="Chalkwell"> 
 

 
\t \t \t \t \t \t \t \t \t <span class="logo"><img class="nr-logo" src="assets/images/nr-logo.svg"></span> 
 
\t \t \t \t \t \t \t \t \t <span class="station-name">Chalkwell</span> 
 
\t \t \t \t \t \t \t \t \t <span class="station-distance">1.5km</span> 
 

 
\t \t \t \t \t \t \t \t </div> 
 

 
\t \t \t \t \t \t \t \t <div class="nearest-station" data-code="Westcliff"> 
 

 
\t \t \t \t \t \t \t \t \t <span class="logo"><img class="nr-logo" src="assets/images/nr-logo.svg"></span> 
 
\t \t \t \t \t \t \t \t \t <span class="station-name">Westcliff</span> 
 
\t \t \t \t \t \t \t \t \t <span class="station-distance">2.7km</span> 
 

 
\t \t \t \t \t \t \t \t </div> 
 

 
\t \t \t \t \t \t \t \t <div class="nearest-station" data-code="Southend Central"> 
 

 
\t \t \t \t \t \t \t \t \t <span class="logo"><img class="nr-logo" src="assets/images/nr-logo.svg"></span> 
 
\t \t \t \t \t \t \t \t \t <span class="station-name">Southend Central</span> 
 
\t \t \t \t \t \t \t \t \t <span class="station-distance">3.6km</span> 
 

 
\t \t \t \t \t \t \t \t </div> 
 

 
\t \t \t \t \t \t \t \t <div class="nearest-station" data-code="Southend Victoria"> 
 

 
\t \t \t \t \t \t \t \t \t <span class="logo"><img class="nr-logo" src="assets/images/nr-logo.svg"></span> 
 
\t \t \t \t \t \t \t \t \t <span class="station-name">Southend Victoria</span> 
 
\t \t \t \t \t \t \t \t \t <span class="station-distance">3.8km</span> 
 

 
\t \t \t \t \t \t \t \t </div> 
 

 
\t \t \t \t \t \t \t </div> 
 

 
\t \t \t \t \t \t \t <div class="stations-show-more"> 
 
<!-- 
 
\t \t \t \t \t \t \t \t <p class="show-more">Show more stations</p> --> 
 

 
\t \t \t \t \t \t \t </div> 
 

 
\t \t \t \t \t \t </div> 
 

 
\t \t \t \t \t </div> 
 

 
\t \t \t \t \t <div class="input-container-to"> 
 

 
\t \t \t \t \t \t <input type="text" class="input input-to" placeholder="To"> 
 

 
\t \t \t \t \t </div> 
 

 
\t \t \t \t </div> 
 

 
\t \t \t \t <div class="switch-container"> 
 

 
\t \t \t \t \t <input type="button" class="button button-switch"> 
 

 
\t \t \t \t </div> 
 

 
\t \t \t </div> 
 

 
\t \t \t <div class="button-search-container"> 
 

 
\t \t \t \t <input type="button" class="button button-search" value="Search"> 
 

 
\t \t \t </div> 
 

 
\t \t </div> 
 

 
\t \t </div>

答えて

1

inputToFocusOut()機能で確かに望まれる効果得るための正しい方法です:メニューの隠しメニュー項目をクリックし、登録するように遅延させなければならないし、そのコールバックを発砲する。何もヒットせず、それについて逃すべきです。ちょうど300msと言う妥当な値で遅延を設定し、addToInputFrom()コールバックからメニューを隠すだけです。実際には、後者の関数のクラストグルコールはすべて重複しており、干渉する可能性があるため、それらをすべて削除することができます。メニューは、inputFromがフォーカスを獲得/失うことによって表示/非表示になります。

ところで、なぜfocusoutで、blurではないのですか?

0

ここ

inputFrom.addEventListener("focusout", inputToFocusOut, false);

focusoutイベントを使用することは適切ではありません。それはclickイベントの前にトリガーされるためです。 機能inputToFocusOutが実行されると.nearest-containerが隠されて次のようになります。

nearestContainer.classList.add("nearest-container--hidden");

clickそれのためのイベントとその子ノードのすべてが(私たちは.nearest-station要素に興味がある)ではありません理由ですトリガーされた。 focusoutの代わりにmousedownイベントを使用してください。 blurイベントでは動作しません。

関連する問題