Javascript 检查鼠标位于哪个元素上以控制另一个div的可见性

Javascript 检查鼠标位于哪个元素上以控制另一个div的可见性,javascript,prototype,Javascript,Prototype,我试图建立一个菜单,检测悬停状态和隐藏/显示相关的div取决于鼠标的位置。我需要用Prototype.js来实现这一点 菜单如下所示: ========ONE========TWO======THREE=======FOUR======FIVE====== ============================================================ ------------------- BIG MIDDLE DIV ------------------------

我试图建立一个菜单,检测悬停状态和隐藏/显示相关的div取决于鼠标的位置。我需要用Prototype.js来实现这一点

菜单如下所示:

========ONE========TWO======THREE=======FOUR======FIVE======

============================================================
------------------- BIG MIDDLE DIV -------------------------
============================================================

============================================================
-------------------- TARGET HIDDEN DIV ---------------------
============================================================
当您将鼠标悬停在链接1、2、3上时。。它将显示相关的目标div。诀窍是当你鼠标移出时,如果你在中间div或活动状态div上,它需要保持该div可见。如果你鼠标移出身体的任何其他地方,它需要隐藏。下面是根据到目前为止的答案更新的代码

<ul><li #id="one">one</li><li>two</li><li>three</li><li>four</li></ul>
<div id="middleBar"></div>

<div id="container-one">1</div>

<div id="container-two">2</div>

<div id="container-three">3</div>

<div id="container-four">4</div>

<script>
   MouseOff = true;
function getTarget(event) {
    var el = event.target || event.srcElement;
    return el.nodeType == 1? el : el.parentNode;
}

var ShowDiv = function(activeDiv){
    $(activeDiv).addClassName('isActive');
    var activeSibs = $(activeDiv).siblings();
    activeSibs.invoke('removeClassName', 'isActive');
};

var HideDiv = function(){
    if(MouseOff){
      $$('div').invoke('removeClassName','isActive');
    }
};

$$('li').invoke('observe','mouseenter',function(){
    console.log(getTarget(event));
    MouseOff = false;
    var linkName = this.innerHTML;
    var activeDiv = 'container-' + linkName;
    ShowDiv(activeDiv);    
});


$$('li').invoke('observe','mouseleave',function(){
    MouseOff = true;
    HideDiv();
});

 $$('#middleBar').invoke('observe','mouseenter',function(){
       console.log(getTarget(event));
        MouseOff = false;
    });
</script>
    一个两个三个四个
      1. 2. 3. 4. MouseOff=true; 函数getTarget(事件){ var el=event.target | | event.src元素; 返回el.nodeType==1?el:el.parentNode; } var ShowDiv=函数(activeDiv){ $(activeDiv).addClassName('isActive'); var activeSibs=$(activeDiv.sibles(); invoke('removeClassName','isActive'); }; var HideDiv=函数(){ if(MouseOff){ $$('div').invoke('removeClassName','isActive'); } }; $$('li')。调用('observe','mouseenter',函数(){ log(getTarget(event)); MouseOff=false; var linkName=this.innerHTML; var-activeDiv='container-'+linkName; ShowDiv(activeDiv); }); $$('li')。调用('observe','mouseleave',函数(){ MouseOff=true; HideDiv(); }); $$('#middleBar')。调用('observe','mouseenter',function(){ log(getTarget(event)); MouseOff=false; });
这里有一把小提琴:

为了进一步阐明我试图实现的目标,一旦div被激活,它需要在导航触发器、中间栏或激活的div本身上保持可见。我想的另一个方法是使用getTarget函数始终检查鼠标上面的元素,但我觉得这是错误的,而且似乎效率不高。对此有何看法

更新:仍在努力解决此问题。。现在我稍微靠近了一点,当超过中间div时,标志设置正确,但是当它超过活动div时,它重置标志,div消失。我试着加回一个超时。。以下是最新的尝试:

更新:好的,我想我可能有这个,在这一点上,我只想听到任何关于这个解决方案的反馈。我发现,因为活动类是动态添加的,所以创建它的函数中必须包含observer方法:ShowDiv。以下是我得到的:


更新:周二晚上。我相信这会更简洁。也许这只是我的浏览器,但我注意到我只能将鼠标移到Panel1上,并显示它不会消失,其他面板(由于它们的位置)会留下一个空间,即“主体”,我将其关闭。希望这会好一点


经过多次修补,我终于找到了解决这个问题的有效方法。多亏了詹姆斯的想法,我根据鼠标在哪个元素上的位置来设置一个标志。加上超时,我可以继续检查鼠标位置。我的问题的一部分是在调用从
ShowDiv()
动态添加的类上的observe事件时,当我将它移动到该函数中时,我能够使它工作。这是我最后得到的js

MouseLocator = 'off';
var ShowDiv = function(activeDiv){
    $(activeDiv).addClassName('isActive');
    var activeSibs = $(activeDiv).siblings();
    activeSibs.invoke('removeClassName', 'isActive');
    $$('.isActive').invoke('observe','mouseenter',function(){
    MouseLocator = 'on';
    });

    $$('.isActive').invoke('observe','mouseleave',function(){
      MouseLocator = 'off';
      setTimeout(function(){HideDiv()},500);
    });
};

var HideDiv = function(){
    if(MouseLocator == 'off'){
      $$('div').invoke('removeClassName','isActive');
    }
};

$$('li').invoke('observe','mouseenter',function(){
    MouseLocator = 'on';
    var linkName = this.innerHTML;
    var activeDiv = 'container-' + linkName;
    ShowDiv(activeDiv);    
});
$$('li').invoke('observe','mouseleave',function(){
    MouseLocator = 'off';
    setTimeout(function(){HideDiv()},500);
});
 $$('#middleBar').invoke('observe','mouseenter',function(){
     MouseLocator = 'on';
    });

 $$('#middleBar').invoke('observe','mouseleave',function(){
        MouseLocator = 'off';
        setTimeout(function(){HideDiv()},500);
 });
还有小提琴:


我想这已经解决了,但我总是乐于接受关于如何改进代码的建议:)

很酷,谢谢,我会试试这个。如果用户离开了中间条,它需要隐藏,但首先检查它是否超出初始触发器或.isActive类。我想我理解了如何使用这个标志变量来完成所有这些。实际上,因为你有一个.500的计时器,你可以设置这个值,然后在你的setTimeOut回调中检查,而不是把它放在hide func中。-只是大声思考。是的,超时造成了其他bug,混淆了主题,所以我把它删除了。我尝试了一些关于你添加旗帜的解决方案,但不认为这解决了我的问题。我可能没有很好地描述它,但一旦div被激活,它需要在导航触发器、中间栏或活动div本身上保持可见。一旦离开导航触发器,该标志即设置为false(这是所需的,除非鼠标离开并移到中间)。这是最新的小提琴演奏。。嘿,看看我原来的帖子。我更新了一把小提琴。我希望我接近你所需要的。我知道有时候很难得到用户想要的东西。我希望我没有太离谱。基本上,如果您将鼠标放在选项卡上,它会打开。。将鼠标移到中间的div,显示选项卡仍然打开,直到您将鼠标移到另一个选项卡上。感谢您尝试+1,但这不是我需要的。如果它在dom中除了这3个元素之外的任何地方,我需要它消失。我想我终于找到了答案,最后一把小提琴贴在了我的帖子上。我现在真的不知道该怎么处理这个问题,只是我担心我的代码有点臭,希望得到“更好的方式”的反馈。
MouseLocator = 'off';
var ShowDiv = function(activeDiv){
    $(activeDiv).addClassName('isActive');
    var activeSibs = $(activeDiv).siblings();
    activeSibs.invoke('removeClassName', 'isActive');
    $$('.isActive').invoke('observe','mouseenter',function(){
    MouseLocator = 'on';
    });

    $$('.isActive').invoke('observe','mouseleave',function(){
      MouseLocator = 'off';
      setTimeout(function(){HideDiv()},500);
    });
};

var HideDiv = function(){
    if(MouseLocator == 'off'){
      $$('div').invoke('removeClassName','isActive');
    }
};

$$('li').invoke('observe','mouseenter',function(){
    MouseLocator = 'on';
    var linkName = this.innerHTML;
    var activeDiv = 'container-' + linkName;
    ShowDiv(activeDiv);    
});
$$('li').invoke('observe','mouseleave',function(){
    MouseLocator = 'off';
    setTimeout(function(){HideDiv()},500);
});
 $$('#middleBar').invoke('observe','mouseenter',function(){
     MouseLocator = 'on';
    });

 $$('#middleBar').invoke('observe','mouseleave',function(){
        MouseLocator = 'off';
        setTimeout(function(){HideDiv()},500);
 });