正如您所说,您不需要编辑列表项,因此没有理由使用contenteditable
.
您需要的是一个与列表的当前活动项相对应的索引,以及在按下箭头时增加和减少该索引的函数。这是一个构造函数,它实现了您需要的功能:
var NavigableList = function (ul, selectedClass, activeClass) {
var list = null,
index = 0,
walk = function (step) {
var walked = true;
index += step;
if (index < 0 || index === list.length) {
index -= step;
walked = false;
}
return walked;
},
active = false;
this.active = function (state) {
if (state !== active) {
active = state;
if (active) {
ul.addClass(activeClass);
} else {
ul.removeClass(activeClass);
}
}
};
this.isActive = function () {
return active;
};
this.down = function () {
var previous = index,
changed = false;
if (walk(1)) {
$(list[previous]).removeClass(selectedClass);
$(list[index]).addClass(selectedClass);
changed = true;
}
return changed;
};
this.up = function () {
var previous = index,
changed = false;
if (walk(-1)) {
$(list[previous]).removeClass(selectedClass);
$(list[index]).addClass(selectedClass);
changed = true;
}
return changed;
};
this.currentIndex = function () {
return index;
};
this.currentElementx = function () {
return $(list[index]);
};
ul = $(ul);
list = ul.find('>li');
selectedClass = selectedClass || 'current';
activeClass = activeClass || 'active';
$(ul).click(function (e) {
this.active(true);
NavigableList.activeList = this;
}.bind(this));
$(document).keydown(function(e) {
var event = $.Event('change');
if (this.isActive() && e.keyCode === 40) {
if (this.down()) {
event.selected = $(list[index]);
event.index = index;
ul.trigger(event);
}
} else if (this.isActive() && e.keyCode === 38) {
if (this.up()) {
event.selected = $(list[index]);
event.index = index;
ul.trigger(event);
}
}
}.bind(this));
$(list[index]).addClass(selectedClass);
};
使用它非常简单:
var list = new NavigableList($('#list'), 'current', 'active'),
list2 = new NavigableList($('#list2'));
$(document).click(function (e) {
if (NavigableList.activeList) {
switch (NavigableList.activeList) {
case list:
list2.active(false);
break;
case list2:
list.active(false);
break;
}
} else {
list.active(false);
list2.active(false);
}
NavigableList.activeList = null;
});
此外,我change
在列表中实现了一个事件,您可以通过这种方式使用:
$('#list').change(function (e) {
console.log('List. Selected: ' + e.index);
});
$('#list2').change(function (e) {
console.log('List 2. Selected: ' + e.index);
});
为了跨浏览器的兼容性,您需要在所有 Javascript 代码之前使用它:
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== "function") {
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function () {},
fBound = function () {
return fToBind.apply(this instanceof fNOP && oThis
? this
: oThis,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}
这是一个工作演示。