鱼C论坛

 找回密码
 立即注册
查看: 5205|回复: 3

[技术交流] hash监听者,类似前端路由的东西

[复制链接]
发表于 2021-4-28 17:06:15 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
如题。
HashCaller当触发超链接或者url的hash变动时查找是否有对应的监听者,然后将触发监听者的执行函数。
将重渲染界面的代码放到监听者的执行函数即可实现类似前端路由的东西。(话说以前我和朋友都叫这种操作叫无刷新跳转而不是叫路由)
非常简单的东西,楼下放代码,有爱自取。
或者查看我的js库,里面还有其他有用的东西: https://gitee.com/darth_ef/def-web/blob/master/js/Basics.js
使用例: https://gitee.com/darth_ef/def-web/blob/master/page/index.js
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-4-28 18:22:02 | 显示全部楼层
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 //这里放渲染页面的函数
    ))
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-4-29 07:01:32 From FishC Mobile | 显示全部楼层
Darth_EF 发表于 2021-4-28 18:22
caller类 和 重载超链接标签触发事件



还是不会用,我后台在跳转路由时,都是带参数渲染,这些参数都咋弄,能给个实例吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-4-29 14:21:07 | 显示全部楼层
本帖最后由 Darth_EF 于 2021-4-29 14:37 编辑
wp231957 发表于 2021-4-29 07:01
还是不会用,我后台在跳转路由时,都是带参数渲染,这些参数都咋弄,能给个实例吗


示例的话可以看看我一楼放的第二个链接。

闭包写一个渲染某页面的函数作为HashListener的构造函数的参数就好了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-23 07:33

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表