1

我有一个 div 列表,其中包含一组相同的高度/宽度,float:left因此如果父项小于项目的组合,它们彼此相邻并折叠。

很标准。这是为了创建一个 twitter 引导图标列表,它提供如下内容: 在此处输入图像描述

我使用下面的代码添加了下一个/上一个键盘导航,但是您会注意到上/下箭头键被映射为调用左/右功能。我不知道该怎么做是实际进行向上/向下导航?

提琴手

(function ($) {
    $.widget("ui.iconSelect", {

        // default options
        options: {

        },

        $select: null,

        $wrapper: null,

        $list: null,

        $filter: null,

        $active: null,

        icons: {},

        keys: {
            left: 37,
            up: 38,
            right: 39,
            down: 40

        },

        //initialization function
        _create: function () {

            var that = this;
            that.$select = that.element;

            that.$wrapper = $('<div class="select-icon" tabindex="0"></div>');
            that.$filter = $('<input class="span12" tabindex="-1" placeholder="Filter by class name..."/>').appendTo(that.$wrapper);
            that.$list = $('<div class="select-icon-list"></div>').appendTo(that.$wrapper);


            //build the list of icons
            that.element.find('option').each(function () {
                var $option = $(this);
                var icon = $option.val();

                that.icons[icon] = $('<a data-class="' + icon + '"><i class="icon ' + icon + '"></i></a>');

                if ($option.is(':selected')) {
                    that.icons[icon].addClass('selected active');
                }

                that.$list.append(that.icons[icon]);
            });

            that.$wrapper.insertBefore(that.$select);
            that.$select.addClass('hide');



            that._setupArrowKeysHandler();
            that._setupClickHandler();
            that._setupFilter();
            that.focus('selected');
        },

        focus: function (type) {
            var that = this;
            if (that.$active === null || that.$active.length == 0) {
                if (type == 'first') {
                    that.$active = that.$list.find('a:visible:first');
                } else if (type == 'last') {
                    that.$active = that.$list.find('a:visible:last');
                } else if (type == 'selected') {
                    that.$active = that.$list.find('a.selected:visible:first');
                    that.focus('first');
                }
            }
            that.$active.addClass('active');
            var toScroll = ((that.$list.scrollTop() + that.$active.position().top)-that.$list.height()/2)+that.$active.height()/2;
            //that.$list.scrollTop((that.$list.scrollTop() + top)-that.$list.height()/2);
            that.$list.stop(true).animate({
                scrollTop: toScroll,
                queue: false,
                easing: 'linear'
            }, 200);

            if (type === 'selected') {
                return false;
            }

            that.$select.val(that.$active.data('class'));
            that.$select.trigger('change');

        },

        _setupArrowKeysHandler: function () {
            var that = this;

            that.$wrapper.on('keydown', function (e) {
                switch (e.which) {
                    case that.keys.left:
                        that.moveLeft();
                        break;
                    case that.keys.up:
                        that.moveUp();
                        break;
                    case that.keys.right:
                        that.moveRight();
                        break;
                    case that.keys.down:
                        that.moveDown();
                        break;
                    case 16:
                        return true;
                    case 9:
                        return true;
                    break;
                    default:
                        that.$filter.focus();
                        return true;
                }
                return false;
            });
        },

        _setupFilter: function(){
            var that = this;

            that.$filter.on('keydown keyup keypress paste cut change', function(e){
                that.filter(that.$filter.val());
            });
        },

        _setupClickHandler: function () {
            var that = this;
            that.$list.on('click', 'a', function () {
                that.$wrapper.focus();
                that.$active.removeClass('active');
                that.$active = $(this);
                that.focus('first');
            });
        },

        moveUp: function () {
            var that = this;
            return that.moveLeft();
        },

        moveDown: function () {
            var that = this;
            return that.moveRight();
        },

        moveLeft: function () {
            var that = this;
            that.$active.removeClass('active');
            that.$active = that.$active.prevAll(':visible:first');
            that.focus('last');
            return false;
        },

        moveRight: function () {
            var that = this;
            that.$active.removeClass('active');
            that.$active = that.$active.nextAll(':visible:first');
            that.focus('first');
            return false;
        },

        filter: function(word){
            var that = this;
            var regexp = new RegExp(word.toLowerCase());
            var found = false;
            $.each(that.icons, function(i, $v){
                found = regexp.test(i);
                if(found && !$v.is(':visible')){
                    $v.show();
                } else if(!found && $v.is(':visible')){
                    $v.hide();
                }
            });
        }

    });
})(jQuery);
4

2 回答 2

2

也许是这样的:http: //jsfiddle.net/QFzCY/

var blocksPerRow = 4;

$("body").on("keydown", function(e){
    var thisIndex = $(".selected").index();
    var newIndex = null;
    if(e.keyCode === 38) {
        // up
       newIndex = thisIndex - blocksPerRow;
    }
    else if(e.keyCode === 40) {
        // down
        newIndex = thisIndex + blocksPerRow;       
    }
    if(newIndex !== null) { 
        $(".test").eq(newIndex).addClass("selected").siblings().removeClass("selected");   
    }    
 });

基本上,您设置一行中有多少项目,然后找到当前索引并减去或添加该数量以通过新索引选择下一个元素。

如果您需要知道每行有多少块,可以这样做:

var offset = null;
var blocksPerRow = 0;
$(".test").each(function(){
    if(offset === null) {
        offset = $(this).offset().top;
    }
    else if($(this).offset().top !== offset) {
        return false;
    }
    blocksPerRow++;
});

要处理您的“边缘”案例,您可以执行以下操作:

if(newIndex >= $(".test").length) {
    newIndex = $(".test").length - newIndex;
}
于 2013-07-01T12:23:28.057 回答
1
    moveUp: function () {
        var that = this;
        var index = $(this).index();
        var containerWidth = parseInt( $('.select-icon-list').innerWidth(), 10);
        var iconWidth = parseInt( $('.select-icon-list > a').width(), 10);
        var noOfCols = Math.floor( containerWidth / iconWidth );
        var newIndex = ( (index - noOfCols) < 0 ) ? index : (index - noOfCols);
        var elem = $('.select-icon-list > a')[index];
    },

缓存保持静态的内容。

于 2013-07-01T12:25:27.280 回答