select2版本 4.0.5
由于项目需要实现select2效果
在回车后
1.如果有值跳转下一个控件
2.如果无值显示下拉内容
但是鼠标点击也可以显示下拉内容.(用户自由选择)
select2已经实现功能
下拉判断,有值可以取消弹出. 关键 return false
$("#test").select2().on('select2:opening', function (s, e) {
var $target = $(s.target);
var val = $target.val();
if (val) {
//keycode = 13 触发才处理
return false;
}
});
关键在于判断展开是鼠标还是按键,找到SELECT2源码
Select2.prototype._registerEvents = function () {
......
this.on('keypress', function (evt) {
var key = evt.which;
if (self.isOpen()) {
........//打开的
} else {//关闭的
if (key === KEYS.ENTER || key === KEYS.SPACE ||
(key === KEYS.DOWN && evt.altKey)) {
self.open();//修改这里值就可以
evt.preventDefault();
}
}
});
...
}
如何重写这个事件执行,经过研究需要重写
function resetEvent(select2) {
select2.listeners.keypress = [function (evt) {
var KEYS = {
BACKSPACE: 8,
TAB: 9,
ENTER: 13,
SHIFT: 16,
CTRL: 17,
ALT: 18,
ESC: 27,
SPACE: 32,
PAGE_UP: 33,
PAGE_DOWN: 34,
END: 35,
HOME: 36,
LEFT: 37,
UP: 38,
RIGHT: 39,
DOWN: 40,
DELETE: 46
};
var self = select2;
var key = evt.which;
if (self.isOpen()) {
if (key === KEYS.ESC || key === KEYS.TAB ||
(key === KEYS.UP && evt.altKey)) {
self.close();
evt.preventDefault();
} else if (key === KEYS.ENTER) {
self.trigger('results:select', {});
evt.preventDefault();
} else if ((key === KEYS.SPACE && evt.ctrlKey)) {
self.trigger('results:toggle', {});
evt.preventDefault();
} else if (key === KEYS.UP) {
self.trigger('results:previous', {});
evt.preventDefault();
} else if (key === KEYS.DOWN) {
self.trigger('results:next', {});
evt.preventDefault();
}
} else {
if (key === KEYS.ENTER || key === KEYS.SPACE ||
(key === KEYS.DOWN && evt.altKey)) {
alert();
self.open();
evt.preventDefault();
}
}
}];
}
resetEvent($("#test").data().select2);//可以调试时看下 $("#test").data()的值 在关注listeners 属性
过程部分select2源代码,看下初始化时select2事件如何实现的
var Observable = function () {
this.listeners = {};
};
Observable.prototype.on = function (event, callback) {
this.listeners = this.listeners || {};
if (event in this.listeners) {
this.listeners[event].push(callback);
} else {
this.listeners[event] = [callback];
}
};
Observable.prototype.trigger = function (event) {
var slice = Array.prototype.slice;
var params = slice.call(arguments, 1);
this.listeners = this.listeners || {};
// Params should always come in as an array
if (params == null) {
params = [];
}
// If there are no arguments to the event, use a temporary object
if (params.length === 0) {
params.push({});
}
// Set the `_type` of the first object to the event
params[0]._type = event;
if (event in this.listeners) {
this.invoke(this.listeners[event], slice.call(arguments, 1));
}
if ('*' in this.listeners) {
this.invoke(this.listeners['*'], arguments);
}
};
Observable.prototype.invoke = function (listeners, params) {
for (var i = 0, len = listeners.length; i < len; i++) {
listeners[i].apply(this, params);
}
};