这个代码有什么问题,尝试点击菜单?

时间:2014-11-27 11:01:42

标签: javascript jquery html css

所以有一个左侧垂直菜单。它有一个小选项按钮。单击时,它应该打开一个div,它将具有各种过滤器选项。现在,我需要它在单击时显示,并在再次单击选项按钮时消失,或者用户单击div之外的任何位置。

所以我有以下代码。

//options filter menu animation
$('#optionsmenu').hide(); //hides the menu

$('.optionsfilters').click(function(e){
    var $this = $('#optionsmenu');
    $this.show();
    var left = $('#sidebar').css('width'),
        top = $(this).offset().top;
    $this.css('top', top);
    $this.css('left', left);
});
$(':not(.optionsfilters)').click(function(e){
    $('#optionsmenu').hide();
});

HTML

<div id="sidebartitle">
    <h2>Organisation</h2>
    <a id="optionsfilters" class="optionsfilters">Options</a>
</div>
<div id="optionsmenu" class="optionsfilters">
    <h3>Add New</h3>
    <ul>
        <label>Year</label>
        <select>
            <option>2000</option>
            <option>2001</option>
            <option>2002</option>
            <option>2003</option>
            <option>2004</option>
            <option>2005</option>
        </select>
    </ul>
</div>

它没有一起工作,即两个javascript函数,第一个单独工作,当第二个被注释掉时。第二个工作,如果我注释掉隐藏部分,并添加警报消息。但是,他们在一起工作。

冲突是什么?

6 个答案:

答案 0 :(得分:2)

好的,你可以做一些事情:

1)如果您希望原始按钮关闭菜单,您需要使用.toggle()而不是.show()

2)您需要检测文档上的单击,以隐藏选项菜单。如果由于e.stopPropagation();(下面的第4点)点击了选项菜单,则不会调用该文件。

    $(document).click(function() {
        $('#optionsmenu').hide();
    });

3)你还想检查(因为它们都有相同的类)被点击的.optionsfilters不是过滤器本身(否则这将阻止你点击一个选项)。

    if( e.target !== this ) {
       return;
    }

4)使用e.stopPropagation();来阻止事件冒泡到父母(或文档)。

这应该是你要找的东西:

$('#optionsmenu').hide(); //hides the menu

$('.optionsfilters').click(function(e){
    e.stopPropagation();
    if( e.target !== this ) {
       return;
    }
    var $this = $('#optionsmenu');

    $this.toggle();
    var left = $('#sidebar').css('width'),
       top = $(this).offset().top;
    $this.css('top', top);
    $this.css('left', left);
});

$(document).click(function() {
  $('#optionsmenu').hide();
});

这是工作小提琴:http://jsfiddle.net/lee_gladding/pny4vq26/

答案 1 :(得分:1)

你去吧

//options filter menu animation
var filters = $('.optionsfilters');
var options = $('#optionsmenu');

options.hide(); //hides the menu

filters.click(function(e){
    $('#optionsmenu').toggle();
    var left = $('#sidebar').css('width'),
        top = $(this).offset().top;
    _this.css('top', top);
    _this.css('left', left);
});

$(document).click(function(e) {
    if (!filters.is(e.target) && filters.has(e.target).length === 0) {
        options.hide();
    }
});

http://jsfiddle.net/6e86hdwc/

答案 2 :(得分:1)

问题主要在于您的点击处理程序都运行,一个显示菜单,然后另一个隐藏它。

为什么呢?因为那不是一个好的选择器。在您使用 .optionsfilters 类到达元素之前,您的点击会通过 body #sidebartitle 然后到达元素 a < / em>的。由于该元素的父母没有类 .optionsfilters ,它将隐藏菜单。

所以我稍微改了一下代码。首先,不要将该类用作点击处理程序。使用ID

$('#optionsfilters').click(function (e) { // ID of options
    var $this = $('#optionsmenu');
    $this.toggle(); // toggle show/hide when click on it
    var left = $('#sidebar').css('width'),
        top = $(this).offset().top;
    $this.css('top', top);
    $this.css('left', left);
});

您需要检查何时在 #optionsmenu 之外单击。为此,您在文档上附加一个单击处理程序并检查 e.target

$(document).click(function (e) {
    if (!$(e.target).closest('.optionsfilters').length)
         $('#optionsmenu').hide();
});

如果 e.target 本身 .optionsfilters 并且不是该类的父级的子级,则隐藏菜单。

下面的工作示例。

&#13;
&#13;
//options filter menu animation
$('#optionsmenu').hide(); //hides the menu

$('#optionsfilters').click(function (e) {
    var $this = $('#optionsmenu');
    $this.toggle();
    var left = $('#sidebar').css('width'),
        top = $(this).offset().top;
    $this.css('top', top);
    $this.css('left', left);
});
$(document).click(function (e) {
    if (!$(e.target).closest('.optionsfilters').length) $('#optionsmenu').hide();
});
&#13;
#optionsmenu{
  background:lightblue;  
}
&#13;
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<div id="sidebartitle">
     <h2>Organisation</h2>
 <a id="optionsfilters" class="optionsfilters">Options</a>

</div>
<div id="optionsmenu" class="optionsfilters">
     <h3>Add New</h3>

    <ul>
        <label>Year</label>
        <select>
            <option>2000</option>
            <option>2001</option>
            <option>2002</option>
            <option>2003</option>
            <option>2004</option>
            <option>2005</option>
        </select>
    </ul>
</div>
&#13;
&#13;
&#13;

答案 3 :(得分:1)

jQuery(http://api.jquery.com/event.stoppropagation/

中的stopPropagation的经典演示

这是一个简化这个的小提琴:http://jsfiddle.net/ymzrocks/98082xk7/1/

简而言之:

$('.optionsfilters').click(function(e)
{
    e.stopPropagation(); // or elese it will fire the parent event
    var $this = $('#optionsmenu');
    $this.show();
    var left = $('#sidebar').css('width'),
        top = $(this).offset().top;
    $this.css('top', top);
    $this.css('left', left);
});

答案 4 :(得分:0)

小心使用:不要任何其他元素,因为如果 - 例如 - 你点击下拉列表,侧栏会再次隐藏,我怀疑你想要发生这种情况。

最好定义要在单击时隐藏侧边栏的区域,例如主要内容区域。

此外,由于您在侧边栏菜单上使用了课程.optionsfilters,当您点击其中时,侧边栏会再次隐藏。

试试这个 JS Fiddle

答案 5 :(得分:-1)

我无法理解,但是如果您的菜单是隐藏的(您的js中的第一条指令),您如何点击它以显示它?

编辑:没有注意到以前div上的课程。我的错。