• tauri学习(2)a链接伪类visited失效问题


    上节继续,在前端开发中,a链接常用a:visited伪类,用于区分链接点击过后的呈现效果。

    在tauri项目模板中,把App组件中添加3个链接:

     然后在App.css中添加几个样式:

     程序跑起来后,却意外发现:其它几个伪类都起作用,唯独:visited这个伪类,在tairu桌面应用中一点反应都没有,参见下面,上面为tauri桌面应用,下面为浏览器窗口。

    从动图效果看出,在浏览器中:visited是能正常生效的,点击后的链接显示为orange橙色,但是在上面的tauri应用中却没反应。其实不光是tauri有这个问题,electron同样也有类似问题。

    StackOverFlow上有外国网友给出了解决思路:将访问过的链接,写入localStorage中,然后在组件生命周期的DidUnmount中,给这些链接,强行附加一个额外样式。

    先定义2个常量,分别用于localStorage存放访问过的a链接记录,另1个则是强行附加的样式类名

    const LOCAL_STORAGE_HISTORY_KEY = "visitedHistory";
    const VISITED_CLASS_NAME = "visited";
    

    核心代码1:setVisited

    从localStorage中取出点击过的a链接记录(先不管如何存入localStorage的,后面会讲到,假如已经有了),然后判断记录是否过期,如果过期了则删除(重要!否则一直不停点,一直不停向localStorage中存,列表越来越大,早晚崩溃),然后将每个a链接的href跟访问记录匹配,对上了,则追加1个visited的样式(当然:这个样式要额外写)

    /**
     * 根据localStorage里的历史记录,将a附加上visited样式
     * by 菩提树下的杨过http://yjmyzz.cnblogs.com/
     */
    function setVisited() {
      let localstorageSimuHistory = localStorage.getItem(LOCAL_STORAGE_HISTORY_KEY);
      let simuHistory = localstorageSimuHistory ? JSON.parse(localstorageSimuHistory) : [];
    
      //过期访问记录清理
      const now = new Date();
      let hasExpired = false;
      for (let i = simuHistory.length - 1; i >= 0; i--) {
        let item = simuHistory[i];
        //过期的访问记录删除
        if (now.getTime() > item.expire) {
          simuHistory.splice(i, 1)
          hasExpired = true
        }
      }
      if (hasExpired) {
        if (simuHistory.length <= 0) {
          localStorage.removeItem(LOCAL_STORAGE_HISTORY_KEY);
        }
        else {
          localStorage.setItem(LOCAL_STORAGE_HISTORY_KEY, JSON.stringify(simuHistory));
        }
      }
    
      //遍历所有a,访问过的,则强制附加visited样式
      let elements = document.getElementsByTagName('a');
      for (let i = 0; i < elements.length; i++) {
        for (let h = 0; h < simuHistory.length; h++) {
          if (elements[i].href === simuHistory[h].url && elements[i].className.indexOf(VISITED_CLASS_NAME) === -1) {
            elements[i].className += ` ${VISITED_CLASS_NAME}`;
          }
        }
      }
    }
    

    localStorage中的数据,大致长这样:

    核心代码2:addHref

    每个链接点击后,将自身的href存入localStorage

    /**
     * a链接点击后将url加入localStorage
     * @param url 
     */
    function addHref(url: String) {
      let localstorageSimuHistory = localStorage.getItem(LOCAL_STORAGE_HISTORY_KEY);
      let simuHistory = localstorageSimuHistory ? JSON.parse(localstorageSimuHistory) : [];
      let found = false;
      const now = new Date();
      //访问记录过期时间设置(此处仅为示例:30秒)
      const ttl: number = 1000 * 30;
    
      for (let i = simuHistory.length - 1; i >= 0; i--) {
        let item = simuHistory[i];
        if (item.url === url) {
          found = true;
          //过期时间续租
          simuHistory[i] = { "url": url, "expire": new Date().getTime() + ttl };
          break;
        }
      }
      //如果本链接不在访问列表里,则添加
      if (!found) {
        simuHistory[simuHistory.length] = { "url": url, "expire": new Date().getTime() + ttl };
        localStorage.setItem(LOCAL_STORAGE_HISTORY_KEY, JSON.stringify(simuHistory));
      }
    
      //此处只是为了方便,把所有点过的a全刷了一把,还可以再优化下(略)
      setVisited();
    }
    

      

    核心代码3:bindAddHref

    给每个a链接的click绑定事件

    function bindAddHref() {
      let elements = document.getElementsByTagName('a');
      for (let i = 0; i < elements.length; i++) {
        elements[i].onclick = () => {
          addHref(elements[i].href);
        }
      }
      setVisited();
    }
    

    有了上面3个核心方法,就可以在App的生命周期"DidMount"挂载阶段,调用bindAddHref,为每个a链接自动绑定click事件

    当然App.css里得手动添加.visited样式

    .visited {
      color: orange !important
    }
    

    最后运行的效果如下:

    从运行效果上看,"大致"跟浏览器上的表现相同,但值得说明的是,这毕竟只是一种变相的解决方法,二者还是有差别的,如果用开发者工具,把localStorage清了,而浏览器并不清除缓存(反过来也一样),二者的表现还是有差异,不过大多数情况下,上述解决方案,应该能满足业务要求了。

    文中示例代码:https://github.com/yjmyzz/tauri-visited-solution

  • 相关阅读:
    POJ 1611 : The Suspects (普通并查集)
    深入解析 Dubbo 3.0 服务端暴露全流程
    智能搜索推荐一体化营收增长解决方案
    云上应用系统数据存储架构演进
    EMR on ACK 全新发布,助力企业高效构建大数据平台
    介绍一下闭包和闭包常用场景?
    BFC
    高斯消元学习笔记
    云虚拟主机如何设置域名解析
    Centos7.3安装openJDK
  • 原文地址:https://www.cnblogs.com/yjmyzz/p/how_to_fix_pseudo_classes_visited_do_not_work_with_tauri.html
Copyright © 2020-2023  润新知