使ul列表像选择输入一样工作

Men*_*wen 18 html javascript jquery

出于样式原因,我希望能够使用ul列表作为选择表单元素.

我能用我的代码填充一个隐藏的输入(不包含在这个jsfiddle中),到目前为止一直很好.但是现在我试图让我的ul表现得像键盘按下时的选择输入,或鼠标用来.

在我之前的问题中,我遇到了键盘控件的一些问题.他们现在已经修好了.请参阅:向上/向下键盘上的自动滚动

剩下的问题是按下键盘按钮时不会忽略鼠标.这导致"悬停效果"首先听取键盘输入,但是立即转到鼠标并选择此项目作为选择.

这可以在我的jsfiddle示例中看到:http://jsfiddle.net/JVDXT/3/

我的javascript代码:

// scrollTo plugin 
  $.fn.scrollTo = function( target, options, callback ){
  if(typeof options == 'function' && arguments.length == 2){ callback = options; options = target; }
  var settings = $.extend({
    scrollTarget  : target,
    offsetTop     : 100,
    duration      : 0,
    easing        : 'linear'
  }, options);
  return this.each(function(){
    var scrollPane = $(this);
    var scrollTarget = (typeof settings.scrollTarget == "number") ? settings.scrollTarget : $(settings.scrollTarget);
    var scrollY = (typeof scrollTarget == "number") ? scrollTarget : scrollTarget.offset().top + scrollPane.scrollTop() - parseInt(settings.offsetTop);
    scrollPane.animate({scrollTop : scrollY }, parseInt(settings.duration), settings.easing, function(){
      if (typeof callback == 'function') { callback.call(this); }
    });
  });
}


//My code
//The function that is listing the the mouse
jQuery(".btn-group .dropdown-menu li").mouseover(function() {
        console.log('mousie')
        jQuery(".btn-group .dropdown-menu li").removeClass('selected');
        jQuery(this).addClass('selected');
})  

//What to do when the keyboard is pressed
jQuery(".btn-group").keydown(function(e) {
    if (e.keyCode == 38) { // up
        console.log('keyup pressed');
        var selected = jQuery('.selected');
        jQuery(".btn-group .dropdown-menu li").removeClass('selected');
        if (selected.prev().length == 0) {
            selected.siblings().last().addClass('selected');
        } else {
            selected.prev().addClass('selected');
            jQuery('.btn-group .dropdown-menu').scrollTo('.selected');
        }
    }
    if (e.keyCode == 40) { // down
        console.log('keydown');
        var selected = jQuery('.selected');
        jQuery(".btn-group .dropdown-menu li").removeClass('selected');
        if (selected.next().length == 0) {
            selected.siblings().first().addClass('selected');
        } else {
            selected.next().addClass('selected');
            jQuery('.btn-group .dropdown-menu').scrollTo('.selected');
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

因此,任何人都可以教我如何在按下键盘按钮时igonore鼠标,但是当用户再次触摸它时会列出鼠标.与默认选择输入表单字段一样.

更新

这是一个新的jsfiddle.

com*_*oma 13

看一下这个:

http://jsfiddle.net/coma/9KvhL/25/

(function($, undefined) {

    $.fn.dropdown = function() {

        var widget = $(this);
        var label = widget.find('span.valueOfButton');
        var list = widget.children('ul');
        var selected;
        var highlighted;

        var select = function(i) {

            selected = $(i);
            label.text(selected.text());

        };

        var highlight = function(i) {

            highlighted = $(i);

            highlighted
            .addClass('selected')
            .siblings('.selected')
            .removeClass('selected');
        };

        var scroll = function(event) {

            list.scrollTo('.selected');

        };

        var hover = function(event) {

            highlight(this);

        };

        var rebind = function(event) {

            bind();

        };

        var bind = function() {

            list.on('mouseover', 'li', hover);
            widget.off('mousemove', rebind);

        };

        var unbind = function() {

            list.off('mouseover', 'li', hover);
            widget.on('mousemove', rebind);

        };

        list.on('click', 'li', function(event) {

            select(this);

        });

        widget.keydown(function(event) {

            unbind();

            switch(event.keyCode) {

                case 38:
                    highlight((highlighted && highlighted.prev().length > 0) ? highlighted.prev() : list.children().last());

                    scroll();
                    break;

                case 40:
                    highlight((highlighted && highlighted.next().length > 0) ? highlighted.next() : list.children().first());

                    scroll();
                    break;

                case 13:
                    if(highlighted) {

                        select(highlighted);

                    }
                    break;

            }

        });

        bind();

    };

    $.fn.scrollTo = function(target, options, callback) {

        if(typeof options === 'function' && arguments.length === 2) {

            callback = options;
            options = target;
        }

        var settings = $.extend({
            scrollTarget  : target,
            offsetTop     : 185,
            duration      : 0,
            easing        : 'linear'
        }, options);

        return this.each(function(i) {

            var scrollPane = $(this);
            var scrollTarget = (typeof settings.scrollTarget === 'number') ? settings.scrollTarget : $(settings.scrollTarget);
            var scrollY = (typeof scrollTarget === 'number') ? scrollTarget : scrollTarget.offset().top + scrollPane.scrollTop() - parseInt(settings.offsetTop, 10);

            scrollPane.animate({scrollTop: scrollY}, parseInt(settings.duration, 10), settings.easing, function() {

                if (typeof callback === 'function') {

                    callback.call(this);
                }

            });

        });

    };

})(jQuery);

$('div.btn-group').dropdown();
Run Code Online (Sandbox Code Playgroud)

关键是解除鼠标悬停并在鼠标移动时重新绑定.

我通过使用闭包函数重构了一点,将逻辑添加到一个名为dropdown的jQuery方法中,这样你就可以重用它,使用switch代替一堆if等等.

好吧,有很多插件可以将select转换为列表:

http://ivaynberg.github.io/select2/

http://harvesthq.github.io/chosen/

http://meetselva.github.io/combobox/

我也有我的!(使用与http://uniformjs.com相同的技巧为触摸设备做好准备)

https://github.com/coma/jquery.select

但是这个问题是关于采用HTML并使其表现得像选择避免悬停问题吧?


650*_*502 0

mouseover如果最近在小部件上按下了按键,您可以使用全局来忽略该事件。例如:

var last_key_event = 0;

jQuery(".btn-group .dropdown-menu li").mouseover(function() {
    if ((new Date).getTime() > last_key_event + 1000) {
        console.log('mousie')
        jQuery(".btn-group .dropdown-menu li").removeClass('selected');
        jQuery(this).addClass('selected');
    }
});
Run Code Online (Sandbox Code Playgroud)

然后keydown处理程序可以设置何时处理以避免与鼠标交互:

//What to do when the keyboard is pressed
jQuery(".btn-group").keydown(function(e) {
    last_key_event = (new Date).getTime();
    ...
});
Run Code Online (Sandbox Code Playgroud)

也许让last_key_event每个小部件的变量分开而不是全局变量可能是有意义的。