Hexo设置外链免责声明

在掘金或者是知乎的文章中打开一个链接时,如果为外部链接(非本站的链接)时,则会先跳转至一个风险提示的页面,告知用户即将打开的新页面出现任何问题概不负责非本站提供,注意账号财产安全。这其实就是一个免责的声明。

添加pug文件

首先我们需要添加外链跳转页面的样式,下面是样式的示例图
e5686804ef940ad3c34051c5bdb23346.png
layout/includes中新建refreshto.pug文件,文件内容如下:

#body-wrap.refreshto
  include ./header/index.pug
  .refreshto-box
    #refreshto-wrap
      .refreshto-content
        .refreshto-info
          h1.refreshto_title= '星の野'
          .refreshto_subtitle= '您即将离开星の野,请注意您的帐号和财产安全。'
          .refreshto_subtitle= '任何透过本网站网页而链接及得到的资讯、产品及服务,本网站概不负责,亦不负任何法律责任。'
          a.button--animated(href=config.root)
            i.anzhiyufont.anzhiyu-icon-rocket
            = _p('回到主页')
          a.button--animated(id='refreshto', href='javascript:;')
            i.anzhiyufont.anzhiyu-icon-rocket
            = _p('继续前往')

    .aside-list
      .aside-list-group
          - let postLimit = theme.aside.card_recent_post.limit === 0 ? site.posts.length : theme.related_post.limit || 6
          - let sort = theme.aside.card_recent_post.sort === 'updated' ? 'updated' : 'date'
          - site.posts.sort(sort, -1).limit(postLimit).each(function(article){
            - let link = article.link || article.path
            - let title = article.title || _p('no_title')
            - let no_cover = article.cover === false || !theme.cover.aside_enable ? 'no-cover' : ''
            - let post_cover = article.cover
            .aside-list-item(class=no_cover)
              if post_cover && theme.cover.aside_enable
                a.thumbnail(href=url_for(link) title=title)
                  img(src=url_for(post_cover) onerror=`this.onerror=null;this.src='${url_for(theme.error_img.post_page)}'` alt=title)
              .content
                a.title(href=url_for(link) title=title)= title
                if theme.aside.card_recent_post.sort === 'updated'
                  time(datetime=date_xml(article.updated) title=_p('post.updated') + ' ' + full_date(article.updated)) #[=date(article.updated, config.date_format)]
                else
                  time(datetime=date_xml(article.date) title=_p('post.created') + ' ' + full_date(article.date)) #[=date(article.date, config.date_format)]
          - })
script(data-pjax).
  const params = new URLSearchParams(window.location.search);
  const target = params.get('target');
  if (target) {
    document.getElementById('refreshto').addEventListener('click', function () {
      window.location.href = decodeURIComponent(target);
    });
  }

设置refreshto界面样式

css/_layout中创建refreshto.styl,内容如下:

#refreshto-wrap
  display: flex
  justify-content: center
  width: 100%
  margin-top: 1rem
  position: relative
  +maxWidth768()
    margin-top: 0

  .refreshto-content
    box-shadow: none !important
    border-radius: 12px
    background: var(--anzhiyu-card-bg) !important
    display: flex
    flex-direction: row
    justify-content: center
    align-items: center
    margin: 0px 1rem
    height: 22rem
    max-width: 800px
    border-radius: 5px
    background: var(--anzhiyu-card-bg)
    box-shadow: var(--card-box-shadow)
    transition: all 0.3s ease 0s
    border: var(--style-border-always)
    position: relative
    width: 100%
    +maxWidth768()
      -webkit-box-orient: vertical;
      flex-direction: column;
      margin: 0px;
      height: 25rem;
      width: 100%;

    .refreshto-img
      flex: 1 1 0%
      height: 90%
      width: 600px
      border-top-left-radius: 8px
      border-bottom-left-radius: 8px
      background-color: rgb(48, 122, 246)
      background-position: center center
      background-size: cover
      height: 100%;
      +maxWidth768()
        -webkit-box-flex: 1;
        flex: 1 1 0%;
        width: 100%;
        border-radius: 12px;


    .refreshto-info
      flex: 1 1 0%
      padding: 0.5rem
      text-align: center
      font-size: 14px
      font-family: "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif
      +maxWidth768()
        -webkit-box-flex: 1.1;
        flex: 1.1 1 0%;
        width: 100%;
        padding-bottom: 2rem;

      .refreshto_title
        font-size: 9em
        line-height: 1
        +maxWidth768()
          font-size: 4rem;

      .refreshto_subtitle
        word-break: break-word
        font-size: 1.6em
        -webkit-line-clamp: 2

      a
        display: inline-block
        margin-top: 0.5rem
        margin-left: 20px
        padding: 0.3rem 1.5rem
        background: var(--btn-bg)
        color: var(--btn-color)
        i
          padding-right: 0.3rem

.button--animated
  border-radius: 8px !important
  transition: 0.3s
  position: relative
  z-index: 1
  transition: color 1s ease 0s

#body-wrap
  .refreshto-box 
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    padding: 1rem;
    padding-top: 0px;
    position: relative;
    .aside-list
      display: flex
      flex-direction: row
      flex-wrap: nowrap
      margin: 1rem
      max-width: 100%
      +maxWidth768()
        margin: 0;

      .aside-list-group
        display: flex
        flex-direction: row
        flex-wrap: wrap
        max-width: 800px
        margin: 0 auto
        justify-content: space-between

      .aside-list-item
        padding: 0.5rem 0
        width: 49%

        .thumbnail
          overflow: hidden
          width: 100%
          height: 200px
          background: var(--anzhiyu-card-bg)
          display: flex
          border-radius: 12px
          +maxWidth768()
            height: 100px;

        img
          width: 100%
          object-fit: cover
          border-radius: 12px
          transition: 0.3s
          transition: filter 300ms ease-in 0.2s, transform 0.6s

        &:hover img
          transform: scale(1.1)
          filter: brightness(0.82)

        .content .title
          -webkit-line-clamp: 2
          overflow: hidden
          display: -webkit-box
          -webkit-box-orient: vertical
          line-height: 1.5
          justify-content: center
          align-items: flex-end
          align-content: center
          padding-top: 0.5rem
          font-size: 16px
          font-weight: bold

        .content time
          display: none

添加全局a标签跳转拦截

打开layout/includes/layout.pug文件,修改如下内容:

    if (theme.mourn.enable && is_home_first_page())
      include ./mourn.pug
    
+   if page.type === 'refreshto'
+     include ./refreshto.pug
-   if page.type !== '404'
+   else if page.type !== '404'
      #body-wrap(class=pageType)
        include ./header/index.pug
        main#blog-container
          if (is_home())
              ·
              ·
              ·
              ·
+   script(data-pjax).
+     document.body.addEventListener('click', function(event) {
+       var el = event.target;
+       while (el && el.nodeName !== 'A') {
+         el = el.parentNode;
+       }
+       if (!el) return;
+       event.preventDefault();
+       choosePush(el);
+     });
+     function choosePush(el) {
+       const target = el.getAttribute("target");
+       const href = new URL(el.href);
+       if (href.hostname !== window.location.hostname) {
+         if (target === "_blank") {
+           if (href.hostname === "localhost" || href.hostname === "byer.top") {
+             window.location.href = href;
+           } else {
+             window.open('/refreshto.html?target=' + encodeURIComponent(href));
+           }
+         } else {
+           window.location.href = href;
+         }
+       }
+     }

以下是直接复制的代码:
if page.type === 'refreshto'
  include ./refreshto.pug
else if page.type !== '404'

script(data-pjax).
  document.body.addEventListener('click', function(event) {
    var el = event.target;
    while (el && el.nodeName !== 'A') {
      el = el.parentNode;
    }
    if (!el) return;
    event.preventDefault();
    choosePush(el);
  });

  function choosePush(el) {
    const target = el.getAttribute("target");
    const href = new URL(el.href);
    if (href.hostname !== window.location.hostname) {
      if (target === "_blank") {
        const mainDomains = ['gov.cn','gov.moe','byer.top', 'foreverblog.cn', 'travellings.cn', 'github.com'];
        if (mainDomains.some(domain => href.hostname.endsWith(domain))) {
          window.open(href, '_blank');
        } else {
          window.open('/refreshto.html?target=' + encodeURIComponent(href));
        }
      } else {
        window.location.href = href;
      }
    }
  }

添加入口

方法1:
使用hexo new page refreshto创建一个新的page

---
title: 链接跳转
date: 2024-01-10 00:00:00
type: "refreshto"
top_img: false
---

方法2:
/scripts/events中创建refreshto.js文件,文件内容如下:
'use strict'

hexo.extend.generator.register('refreshto', function (locals) {
    return {
      path: 'refreshto.html',
      layout: ['page'],
      data: {
        title: '链接跳转',
        type: 'refreshto',
        top_img: false
      }
    }
  })

这样你就可以通过http://localhost:4000/refreshto.html访问你的外链跳转界面了。

可能会导致的问题

假如你的页面你发现你的各种A标签不能跳转了,不用想别的问题,大概率就是这个代码的问题。
有两种解决方案,一种是给你的A标签添加上target="_blank"(我本地可以使用,但是推上去就不好用了,你可以尝试尝试)
另一种是自己定义一个属性给A标签添加上如allowtarget,然后修改如下代码

document.body.addEventListener('click', function(event) {
  var el = event.target;
  while (el && el.nodeName !== 'A') {
    el = el.parentNode;
  }
  //修改这行,使用 hasAttribute 方法来检查是否有allowtarget属性
  if (!el || || el.hasAttribute('allowtarget')) return;
  event.preventDefault();
  choosePush(el);
});

这个可能会导致出现问题的目前我就发现了一个位置,就是网站右下角的直达评论
打开[themes]\layout\includes\rightside.pug,修改第30行添加allowtarget属性,内容如下
a#to_comment(href="#post-comment" title=_p("rightside.scroll_to_comment") allowtarget)