整个HTML块的jquery .blur

时间:2010-05-28 00:01:05

标签: jquery

我有一个“下拉菜单”的HTML项目,结构如下......

            <li class="ui-dropdown-list" >
                <a href="#">Right Drop Down Menu</a>
                <ul>
                    <li><a href="#">Item</a></li>
                    <li><a href="#">Item</a></li>
                    <li><a href="#">Item</a></li>
                </ul>
            </li>

使用jQuery将其作为下拉列表,使用以下代码。

jQuery.fn.dropdown = function () {

    var defaults = {
        button: null,
        menu: null,
        visible: false
    };
    var options = $.extend(defaults, options);

    return this.each(function () {
        options.button = $(this);
        options.menu = $(this).find("ul");

        // when the parent is clicked, determine whether dropdown needs to occur
        options.button.click(function () {
            options.visible ? lift(options.menu) : drop(options.menu);
            options.visible = !options.visible;
        });

        // drop the menu down so that it can be seen.
        function drop(e) {
            options.button.addClass("open");
            options.menu.show();
        }
        // lift the menu up, hiding it from view.
        function lift(e) {
            options.menu.hide();
            options.button.removeClass('open');
        }

    });
};

我正在尝试连接它,以便如果用户点击菜单外的任何地方,它将折叠它。事实证明这比我预想的要困难得多;甚至尝试使用页面级事件。有什么建议?

菜单本身从未真正“接收”焦点,因此使用.blur似乎不适合此目的。

3 个答案:

答案 0 :(得分:2)

你可以在这里使用事件冒泡,如果click事件一直冒泡到document然后关闭菜单,如果它发生在菜单中,停止泡泡以便处理程序开启document不会受到影响,如下所示:

jQuery.fn.dropdown = function () {
    var defaults = {
        button: null,
        menu: null,
        visible: false
    };
    var options = $.extend(defaults, options);

    return this.each(function () {
        options.button = $(this);
        options.menu = $(this).find("ul");
        $(document).click(lift); //close on bubble!

        options.button.click(function (e) {
            options.menu.is(':visible') ? lift() : drop();
            e.stopPropagation(); //prevent bubble!
        });

        function drop(e) {
            options.button.addClass("open");
            options.menu.show();
        }
        function lift(e) {
            options.menu.hide();
            options.button.removeClass('open');
        }
    });
};

You can see a working demo here:)

答案 1 :(得分:1)

编辑:请参阅Nick Craver的答案,了解利用事件冒泡的完整示例。


也许另一种方法是将文本input的不透明度设置为零,以便在展开菜单时获得焦点,并触发模糊处理程序以折叠菜单。

当然,如果你点击一个菜单项也会激活它。

或许更多的是hackish,但同时也是一个更专注的事件处理程序。


修改

虽然搞乱了Nick的jsFiddle示例,但我尝试创建两个菜单。它无法正常运行,因为两个实例共享同一组options

如果您计划使用多个菜单,我认为您需要将options存储在each()函数中的变量放置,以便每个菜单都有自己的设置。 / p>

jQuery.fn.dropdown = function () {

    var defaults = {
        button: null,
        menu: null,
        visible: false
    };

    return this.each(function () {
           // each menu gets its own options
        var options = $.extend({}, defaults, options);

        options.button = $(this);
        options.menu = $(this).find("ul");

 ...and so on

答案 2 :(得分:0)

如果用户点击它之外你想要关闭菜单,因为我在1月份遇到了类似的问题,并提出了这个问题:

document.onclick=check;
function check(e){
    var target = (e && e.target) || (event && event.srcElement);
    var obj = document.getElementById('opts_select01');
    var obj2 = document.getElementById('select01_input');
    checkParent(target)?obj.style.display='none':null;
    target==obj2?obj.style.display='block':null;
}
function checkParent(t){
    while(t.parentNode){
        if(t==document.getElementById('opts_select01')){
            return false;
        }
        t=t.parentNode;
    }
    return true;
}

它的作用是检测鼠标点击,如果鼠标点击两个指定元素之外,它会将菜单显示设置为“无”,因此隐藏它!

我已经使用此代码在用户点击输入时显示div(创建自定义选择框,这变得非常受欢迎):) 无论哪种方式,如果它打开并且用户点击div或输入,它会保持打开状态,但如果点击进入页面上的其他位置,它会关闭div! 另外,如果用户在隐藏div时单击输入(始终可见),则会触发div(显示)

对于您来说,将“select01_input”替换为始终可见的菜单元素的ID(用于触发菜单),并将“opts_select01”替换为菜单树的ID。

  

完全关闭它,简单方法   是通过CSS隐藏整个菜单   显示属性......

希望它有助于你!