工作中写的一个手机字母索引控件,只适用于 Chrome,其它没有测试。sourcecode.zip
//矫正调用者。将 fn 作为 newObj 的方法调用
function repairCaller(newObj, fn){
return function(){
return fn.apply(newObj, arguments);
}
}
function AlphaIndex( config ){
//索引面板
this.indexPanel = (function(){
var alphaList = '',
index = document.createElement('div');
index.id = config.id;
alphaList += '<li style="height:12px;" value="top">♂</li>';
for(var al=65; al<=90; al++){
alphaList += '<li style="height:12px;" value="' + String.fromCharCode(al) + '">' + String.fromCharCode(al) + '</li>';
}
alphaList += '<li style="height:12px;" value="bottom">#</li>';
index.innerHTML = '<ul id="' + config.id + 'Index" style="list-style:none;width:28px;">' + alphaList + '</ul>';
index.style.cssText = '-webkit-padding-before:0;-webkit-padding-after:0;-webkit-margin-before:0;-webkit-margin-after:0;background:none;color:#1E2A38;font-family:\'Helvetica Neue\', HelveticaNeue, Helvetica-Neue, Helvetica, \'BBAlpha Sans\';font-size:11px;font-weight:bold;position:absolute;padding:0px;margin:0px;right:7px;top:0px;z-index:100;border-radius:12px;text-align:center;-webkit-user-select:none;overflow:hidden;';
index.style.right = config.start.right + 'px;';
index.style.top = config.start.top + 'px;';
return index;
})();
//大号字母显示
this.largeLetter = (function(){
var letter = document.createElement('div');
letter.id = config.id + "Letter";
letter.style.cssText = 'font-family:\'Helvetica Neue\', HelveticaNeue, Helvetica-Neue, Helvetica, \'BBAlpha Sans\';color:#1E2A38;background:none;display:block;position:absolute;padding:0px;margin:0px;right:0px;top:0px;z-index:100;text-align:right;';
letter.style.right = (config.start.right + 32) + 'px';
letter.style.top = config.start.top + 'px';
letter.innerHTML = '<span style="font-size:50pt;font-weight:bold;"></span>';
return letter;
})();
//保存mouseup或者鼠标移出索引框时选择的字母
this.selectItem = null;
//初始化时默认隐藏大号字母
this.showLargeLetter = false;
this.bodyScrollHeight = document.body.scrollHeight;
}
AlphaIndex.prototype.start = function(){
//显示大写字母显示
this.showLargeLetter = true;
//绑定事件
T.bind(document,'mousemove',repairCaller(this,this.move));
T.bind(document,'mouseup',repairCaller(this,this.stop));
//取得事件对象
var event = T.event.getEvent(arguments[0]);
var target = T.event.getTarget(event);
if(target.tagName.toUpperCase() ==='LI'){
this.selectItem = target;
this.largeLetter.firstChild.textContent = target.textContent;
this.largeLetter.style.top = (event.clientY + document.body.scrollTop - this.largeLetter.offsetHeight/2) + 'px';
this.largeLetter.style.display = 'block';
}
this.indexPanel.style.background = '#63778F';
};
AlphaIndex.prototype.move = function(){
//取得事件对象
var event = T.event.getEvent(arguments[0]);
var target = T.event.getTarget(event);
if( target.parentNode.id == (this.indexPanel.id + 'Index') && target.tagName.toUpperCase() ==='LI'){
this.selectItem = target;
if(this.showLargeLetter){
this.largeLetter.firstChild.textContent = target.textContent;
this.largeLetter.style.top = (event.clientY + document.body.scrollTop - this.largeLetter.offsetHeight/2) + 'px';
this.largeLetter.style.display = 'block';
}
}
};
AlphaIndex.prototype.stop = function(){
if(this.showLargeLetter && this.selectItem){
var tc = this.selectItem.textContent;
if(tc == '♂'){
tc = 'top';
}
else if(tc == '' || tc == '#'){
tc = 'bottom';
}
if(T.get(tc)){
T.get(tc).scrollIntoView();
}
}
this.showLargeLetter = false;
this.largeLetter.style.display = 'none';
this.indexPanel.style.background = 'none';
//移除事件
T.unbind(document,'mousemove',repairCaller(this,this.move));
T.unbind(document,'mouseup',repairCaller(this,this.stop));
};
AlphaIndex.prototype.scroll = function(){
if( (parseInt(this.indexPanel.style.top) + this.indexPanel.scrollHeight) <= this.bodyScrollHeight || document.body.scrollTop < parseInt(this.indexPanel.style.top)){
this.indexPanel.style.top = ( (window.innerHeight - this.indexPanel.offsetHeight) > 0 ?
( (window.innerHeight - this.indexPanel.offsetHeight)/2 + document.body.scrollTop) : document.body.scrollTop )+ 'px' ;
}
};
AlphaIndex.prototype.resize = function(){
this.indexPanel.style.top = ( (window.innerHeight - this.indexPanel.offsetHeight) > 0 ?
( (window.innerHeight - this.indexPanel.offsetHeight)/2 + document.body.scrollTop) : document.body.scrollTop )+ 'px' ;
};
AlphaIndex.prototype.ready = function(){
document.body.appendChild(this.largeLetter);
document.body.appendChild(this.indexPanel);
this.indexPanel.style.top = ( (window.innerHeight - this.indexPanel.offsetHeight) > 0 ?
( (window.innerHeight - this.indexPanel.offsetHeight)/2 + document.body.scrollTop) : document.body.scrollTop )+ 'px' ;
//绑定事件
T.bind(document, 'scroll', repairCaller(this,this.scroll));
T.bind(window, 'resize', repairCaller(this,this.resize));
T.bind(this.indexPanel,'mousedown',repairCaller(this,this.start));
};