caller类 和 重载超链接标签触发事件/**
* 点击站内链接调用的函数, 另链接不跳转而是成为锚点链接
*/
function linkClick(e,tgt){
var _event=e||event;
var tgt=tgt||this;
var linkTarget=tgt.getAttribute("target");
var tempStr;
if(tgt.host==window.location.host){
// var hostchar=this.pathname.slice(this.pathname.indexOf('/')+1,this.pathname.slice(this.pathname.indexOf('/')+1).indexOf('/')+1);
switch (_event.button){
case 0:
if((!linkTarget||linkTarget=='_self')&&(!e.ctrlKey)){
window.location.href='#/'+tgt.href.substr(tgt.href.indexOf(tgt.host)+(tgt.host.length)+1);
stopPE(e);
// if(tempStr=tgt.getAttribute("title")){
// window.document.title=tempStr;
// }
hashcaller.touchHashListener();
return false;
}
break;
case 1:
// window.open(this.getAttribute('href'));
break;
default:
break;
}
}
}
/**
* 让站内链接失效 链接不跳转而是成为锚点链接
*/
function setupLinkClick(){
document.addEventListener("click",function(e){
var tgt=e.target;
while(tgt.tagName!="HTML"){
if(tgt.tagName=="A"){
linkClick(e,tgt);
break;
}
tgt=tgt.parentElement;
}
});
}
/**
* Hashcaller
*/
class Hashcaller{
constructor(onlyTouchOne=true){
this.listeners=[];
/**如果冲突(有多个能够匹配到的表达式)仅取下标大的监听者触发 */
this.onlyTouchOne=onlyTouchOne;
this.lastListenerIndex=-1;
var that=this;
window.addEventListener("hashchange",function(){that.touchHashListener()});
}
/**
* 添加一个监听者对象 后添加的会比前面的更优先
* @param {HashListener} listener
*/
add(listener){
this.listeners.push(listener);
}
/**
* 添加一个监听者对象数组
* @param {Array<HashListener>} listeners
*/
addList(listeners){
for(var i=listeners.length-1;i>=0;--i){
this.add(listeners[i]);
}
}
/**
* 触发 location.hash
*/
touchHashListener(){
if((typeof window.lowhash!='undefined')&&(window.lowhash!=location.hash)){
var regex;
for(var i=this.listeners.length-1;i>=0;--i)
if(regex=this.listeners[i].exec(location.hash)){
this.listeners[i].listener(regex);
this.lastListenerIndex=i;
if(this.onlyTouchOne)break;
}
}
window.lowhash=location.hash;
}
}
/**
* HashListener obj
*/
class HashListener{
/**
* @param {RegExp} regExp hash的正则表达式
* @param {Function} listener 监听者 调用时会引用 regExp 的 regex
* @param {Boolean} filterFlag 选择是否过滤 hash 中的 /^#\// 默认为过滤
*/
constructor(regExp,listener,filterFlag=true){
this.hashSelector=regExp;
this.listener=listener;
this.filterFlag=filterFlag;
}
/**
* 测试表达式能否匹配字符串
* @param {String} _string 文本
*/
exec(_string){
var string;
if((this.filterFlag)&&(_string.indexOf("#/")==0)){
string=_string.slice(2);
}
else{
string=_string;
}
return this.hashSelector.exec(string);
}
}
var hashcaller=new Hashcaller();
食用方法
hashcaller.add(new HashListener(
/.*/i, //这里放正则表达式匹配url的hash
show404Page //这里放渲染页面的函数
))
|