2016-08-08 9 views
1

メニューに追加のタブを動的に作成しています(この新しいタブを呼び出そうとします)、新しいタブが表示されたときに表示されたサブメニューを含め、すべてがうまくいっていました。イベントのバブリングに関する記事を見て、他の例を見ましたが、私の問題の解決策を見つけることができませんでした。JavaScriptサブメニューが維持されない

[ウォッチ]の上に移動すると、サブメニューが表示されますが、ウォッチからそのサブメニューに移動しようとすると、サブメニューが消えます。ユーザーがウォッチまたはサブメニューの上を移動するときにサブメニューを保持する必要があり、サブメニューはユーザーがいったん外に出ると消えてしまいます。注意するだけで、自分のソリューションにCSSを使用することはできません。私はコメントして以下に私の現在のコードを添付しました:

//PREPEND AS FIRST CHILD 
var prependChild = function(parent, newFirstChild) { 
    parent.insertBefore(newFirstChild, parent.firstChild) 
} 

//DECLARING VARS 
var navMenu    = document.getElementsByClassName('navGlobal-list')[0]; 
    categoryExplorer  = document.getElementsByClassName('categoryExplorer')[0]; 

//CREATING NEW TAB 
var exploreTab   = document.createElement('li'); 
    exploreTab.className = 'navGlobal-category'; 

//CREATING NEW SEARCH FORM 
var searchHtml = ['<div class="searchProgram searchProgram--categoryExplorer">', 
         '<div class="searchProgram-container">', 
          '<input type="search" class="form-control form-control--light form-control--searchProgram" placeholder="Search programs" value="">', 
         '</div>', 
        '</div>'].join(''); 

//CREATING NEW WATCH CATEGORY EXPLORER CONTENT  
var watchCategoryExplorerContent = document.createElement('div'); 
    watchCategoryExplorerContent.className = 'categoryExplorer-content target-watch-content'; 
    watchCategoryExplorerContent.innerHTML = searchHtml; 
    prependChild(categoryExplorer, watchCategoryExplorerContent) 

var watchLink = document.createElement('a');  
    watchLink.setAttribute('href','/watch'); 
    watchLink.innerHTML = 'watch'.toUpperCase();  

exploreTab.appendChild(watchLink); 
navMenu.appendChild(exploreTab); //ADDED 'WATCH' TO THE NAVIGATION 

//CHANGE CLASSES ON HOVER 
exploreTab.addEventListener("mouseover", function() { 
    exploreTab.className = 'navGlobal-category navGlobal-category--open'; 
    categoryExplorer.className = 'categoryExplorer categoryExplorer--open'; 
    watchCategoryExplorerContent.className = 'categoryExplorer-content categoryExplorer-content--open target-watch-content'; 
}, false); 

exploreTab.addEventListener("mouseleave", function() { 
    exploreTab.className = 'navGlobal-category'; 
    categoryExplorer.className = 'categoryExplorer'; 
    watchCategoryExplorerContent.className = 'categoryExplorer-content target-watch-content'; 
}, false); 

答えて

2

電位(レイアウト依存)の方法は、そのタブの子にするだろう開いたメニューを保つために - その方法は、スペースがない提供しましたタブとホバーメニューの間で、マウスの移動イベントをタブに作成しなくても、マウスカーソルを移動することができます。

レイアウトに依存しない別の解決策は、最初のmouseleaveイベントとサブメニューの終了の間にいくらかの遅延を追加することです。私はこれまでjQueryを使ってこのようなことを行ってきましたが、同じことはそれがなければ可能でなければなりません。

$('.navGlobal-category').mouseleave(function(){ 
    setTimeout(
    function(){ 
     if(!isHovered($('.navGlobal-category')[0])){ 
     exploreTab.className = 'navGlobal-category'; 
     categoryExplorer.className = 'categoryExplorer'; 
     watchCategoryExplorerContent.className = 'categoryExplorer-content target-watch-content'; 
     } 
    }, 200); 
}); 

function isHovered(e){ 
    return ((e.parentNode.querySelector(":hover") || 
    e.querySelector(":hover")) === e); 
} 

isHoveredソリューションは「ZBするクレジット:https://stackoverflow.com/a/14800287/5403341

2

非レイアウトソリューションの@ B1SeeMoreのためにあなたが実際に遅延を必要としません示唆しています。 https://jsfiddle.net/jw22ddzk/

<div id="one" class="menuitem"></div> 
<div id="two" class="menuitem" style="display: none;"></div> 

var elems = document.getElementsByClassName("menuitem"); 
for (var i = 0; i < elems.length; i += 1) { 
    elems[i].addEventListener("mouseleave", function() { 
    console.log("leave", this.id); 
    document.getElementById("two").style.display = "none"; 
    }); 
    elems[i].addEventListener("mouseenter", function() { 
    console.log("enter", this.id); 
    document.getElementById("two").style.display = ""; 
    }); 
} 

トリックはtwoでもmouseleave場合についてmouseenter火災が要素を隠していることである。ここでは

は、作業のデモです。要素を再度表示することを忘れないでください。同様の説明は、mouseentermouseleaveイベントがペアで生成されるということです。したがって、mouseenterは、mouseleaveの影響に関係なく発生します。

これは、要素がピクセルの精度で互いに隣接している場合にのみ機能することに注意してください。


別のノート:私はあなたがmouseovermouseleaveを使用していることに気づきます。私はそれをすることをお勧めしません。ホバー検出のイベントペアは、mouseenter/leavemouseover/outの2つです。彼らは違う出来事です。彼らは具体的には、mouseover/outが子要素のためにもトリガーする点が異なります。私のお勧めは、あなたがペアを交換しないか、予期しない動作をするかもしれないということです。

+0

表示を変更してもサブメニューが表示されず、メニューが表示されるのは、categoryExplorer-open、navGlobal-category-open、およびcategoryExplorer-content-openが存在する場合のみです。これを回避する方法は表示を調整しないでしょうか? –

+0

それはそれ自体が奇妙です。そこに '重要な'があるのですか?あなたのクラスをどのように使っているのか本当に分かりません。彼らは私に直感的ではなく、私はそれを理解していない定義を見ていない。 – Halcyon

+0

それは大丈夫です、私は1つのアプローチとしてメニューを置き換え、mouseenter mouseleaveせずに別のアプローチに取り組んでいます。レイアウトはReactから構築され、サブメニューはクラスが別のコンポーネントに存在するかどうかに基づいてのみ表示されていました。 –

関連する問題