说明

该站的所有修改项均在本文列出,实际效果看本站即可。若您也想拥有类似的效果,欢迎借鉴~~
注意:以下代码出现/* */ 、<!-- -->//字符均为注释,即不会有实际效果,仅仅是给人看的一个标记。
在这里不建议删除,因为会影响后期修改时的辨别。悉知~

为了给小白讲明白,这里记录的已经很细了。老博主的话,拿着代码按自己意愿改即可,懂得都懂~

本站环境

Typecho:1.2.1正式版
HandSome:9.2.1 Pro 开心版
其他版本的Typecho和HandSome不确定其可行性,请自行测试~

[!Info] Handsome主题结构目录
component/footer.php       底部版权、音乐播放器之类
component/header.php       页面头,没啥要改的
component/headnav.php      顶部导航
component/say.php          时光机动态
component/sidebar.php      右侧栏目
component/third_party_comments.php    3.3.0新增,第三方评论
css/        博客CSS,一般不要改
fonts/      博客字体,一般不要改
img/        图像,一般不要改
js/         js文件,一般不要改
lang/       语言文件
libs/Content.php    文章内容
libs/...    一般不要改
usr/        另一个语言文件?
404.php     404界面
archive.php    整合
booklist.php   书单
cross.php      时光机
files.php      归档
functions.php  配置界面的东西
guestbook.php  留言板
index.php      首页
links.php      友链
page.php       文章页面整合
post.php       文章输出

color: 选填,不填默认为success(绿色),可选值:
light:白色
info:蓝色
dark:深色
success:绿色
black:黑色
warning:黄色
primary:紫色
danger:红色

美化记录

自定义CSS

注意该修改项位于Handsome主题后台-外观-设置外观-开发者设置-自定义CSS处
部分提到PJAX回调的部分添加到主题后台-外观-外观设置-PJAX-PJAX回调函数内.

  • 右侧列表导航栏图标颜色

    这一项是更改右上方三个图标(大拇指,信息,礼物)的颜色,默认是白色。
    Pasted image 20240330105514

    .sidebar-icon svg.feather.feather-thumbs-up{color: #ff0000;}
    .sidebar-icon svg.feather.feather-message-square{color:#495dc3;}
    .sidebar-icon svg.feather.feather-gift{color:#52DE97;}
    
    #post-content pre code {
      display:block;
      overflow-x:auto;
      position:relative;
      margin:0;
      padding-left:50px;
    }
    pre code {
      position:relative;
      display:block;
      overflow-x:auto;
      margin:4.4px 0.px .4px 1px;
      padding:0;
      max-height:500px;
      padding-left:3.5em
    }
    
    .img-square {
      transition: all 0.3s;
    }
    
    .img-square:hover {
      transform: rotate(360deg);
    }
    
    .glyphicon-fire {
      color: #ff0000;
    }
    
    .nav-tabs-alt .glyphicon-comment {
      color: #495dc3;
    }
    
    .glyphicon-transfer {
      color: #0e5458;
    }

    同样#后面的六位数字代表颜色,可以改~

  • 等距标签云

    #tag_cloud-2 a {
    border-radius: 5px;
    width: 32%;
    }

    自定义JavaScripts

  • 左侧图标颜色和彩色标签云

    let tags = document.querySelectorAll("#tag_cloud-2 a");
    let infos = document.querySelectorAll(".badge");
    let colorArr = ["#428BCA", "#AEDCAE", "#ECA9A7", "#DA99FF", "#FFB380", "#D9B999"];
    tags.forEach(tag => {
      tagsColor = colorArr[Math.floor(Math.random() * colorArr.length)];
      tag.style.backgroundColor = tagsColor;
    });
    infos.forEach(info => {
      infosColor = colorArr[Math.floor(Math.random() * colorArr.length)];
      info.style.backgroundColor = infosColor;
    });
    function addNumber(a) {
      var length = document.getElementById("comment").value.length;
      if(length> 0){
          document.getElementById("comment").focus()
          document.getElementById("comment").value += '\n' + a + new Date
      }else{
          document.getElementById("comment").focus()
          document.getElementById("comment").value += a + new Date
      }
    }
    let leftHeader = document.querySelectorAll("span.nav-icon>svg,span.nav-icon>i");
    let leftHeaderColorArr = ["#FF69B4", "#58c7ea", "#E066FF", "#FF69B4", "#FFA54F", "#90EE90"];
    leftHeader.forEach(tag => {
      tagsColor = leftHeaderColorArr[Math.floor(Math.random() * colorArr.length)];
      tag.style.color = tagsColor;
    });

    如果你博客开启了PJAX,需要在PJAX回调函数里面添加以下代码:

    let tags = document.querySelectorAll("#tag_cloud-2 a");
    let infos = document.querySelectorAll(".badge");
    let colorArr = ["#428BCA", "#AEDCAE", "#ECA9A7", "#DA99FF", "#FFB380", "#D9B999"];
    tags.forEach(tag => {
      tagsColor = colorArr[Math.floor(Math.random() * colorArr.length)];
      tag.style.backgroundColor = tagsColor;
    });
    infos.forEach(info => {
      infosColor = colorArr[Math.floor(Math.random() * colorArr.length)];
      info.style.backgroundColor = infosColor;
    });
    function addNumber(a) {
      var length = document.getElementById("comment").value.length;
      if(length> 0){
          document.getElementById("comment").focus()
          document.getElementById("comment").value += '\n' + a + new Date
      }else{
          document.getElementById("comment").focus()
          document.getElementById("comment").value += a + new Date
      }
    }

  • 打字动画效果(代码实现)

    (function webpackUniversalModuleDefinition(a,b){if(typeof exports==="object"&&typeof module==="object"){module.exports=b()}else{if(typeof define==="function"&&define.amd){define([],b)}else{if(typeof exports==="object"){exports["POWERMODE"]=b()}else{a["POWERMODE"]=b()}}}})(this,function(){return(function(a){var b={};function c(e){if(b[e]){return b[e].exports}var d=b[e]={exports:{},id:e,loaded:false};a[e].call(d.exports,d,d.exports,c);d.loaded=true;return d.exports}c.m=a;c.c=b;c.p="";return c(0)})([function(c,g,b){var d=document.createElement("canvas");d.width=window.innerWidth;d.height=window.innerHeight;d.style.cssText="position:fixed;top:0;left:0;pointer-events:none;z-index:999999";window.addEventListener("resize",function(){d.width=window.innerWidth;d.height=window.innerHeight});document.body.appendChild(d);var a=d.getContext("2d");var n=[];var j=0;var k=120;var f=k;var p=false;o.shake=true;function l(r,q){return Math.random()*(q-r)+r}function m(r){if(o.colorful){var q=l(0,360);return"hsla("+l(q-10,q+10)+", 100%, "+l(50,80)+"%, "+1+")"}else{return window.getComputedStyle(r).color}}function e(){var t=document.activeElement;var v;if(t.tagName==="TEXTAREA"||(t.tagName==="INPUT"&&t.getAttribute("type")==="text")){var u=b(1)(t,t.selectionStart);v=t.getBoundingClientRect();return{x:u.left+v.left,y:u.top+v.top,color:m(t)}}var s=window.getSelection();if(s.rangeCount){var q=s.getRangeAt(0);var r=q.startContainer;if(r.nodeType===document.TEXT_NODE){r=r.parentNode}v=q.getBoundingClientRect();return{x:v.left,y:v.top,color:m(r)}}return{x:0,y:0,color:"transparent"}}function h(q,s,r){return{x:q,y:s,alpha:1,color:r,velocity:{x:-1+Math.random()*2,y:-3.5+Math.random()*2}}}function o(){var t=e();var s=5+Math.round(Math.random()*10);while(s--){n[j]=h(t.x,t.y,t.color);j=(j+1)%500}f=k;if(!p){requestAnimationFrame(i)}if(o.shake){var r=1+2*Math.random();var q=r*(Math.random()>0.5?-1:1);var u=r*(Math.random()>0.5?-1:1);document.body.style.marginLeft=q+"px";document.body.style.marginTop=u+"px";setTimeout(function(){document.body.style.marginLeft="";document.body.style.marginTop=""},75)}}o.colorful=false;function i(){if(f>0){requestAnimationFrame(i);f--;p=true}else{p=false}a.clearRect(0,0,d.width,d.height);for(var q=0;q<n.length;++q){var r=n[q];if(r.alpha<=0.1){continue}r.velocity.y+=0.075;r.x+=r.velocity.x;r.y+=r.velocity.y;r.alpha*=0.96;a.globalAlpha=r.alpha;a.fillStyle=r.color;a.fillRect(Math.round(r.x-1.5),Math.round(r.y-1.5),3,3)}}requestAnimationFrame(i);c.exports=o},function(b,a){(function(){var d=["direction","boxSizing","width","height","overflowX","overflowY","borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth","borderStyle","paddingTop","paddingRight","paddingBottom","paddingLeft","fontStyle","fontVariant","fontWeight","fontStretch","fontSize","fontSizeAdjust","lineHeight","fontFamily","textAlign","textTransform","textIndent","textDecoration","letterSpacing","wordSpacing","tabSize","MozTabSize"];var e=window.mozInnerScreenX!=null;function c(k,l,o){var h=o&&o.debug||false;if(h){var i=document.querySelector("#input-textarea-caret-position-mirror-div");if(i){i.parentNode.removeChild(i)}}var f=document.createElement("div");f.id="input-textarea-caret-position-mirror-div";document.body.appendChild(f);var g=f.style;var j=window.getComputedStyle?getComputedStyle(k):k.currentStyle;g.whiteSpace="pre-wrap";if(k.nodeName!=="INPUT"){g.wordWrap="break-word"}g.position="absolute";if(!h){g.visibility="hidden"}d.forEach(function(p){g[p]=j[p]});if(e){if(k.scrollHeight>parseInt(j.height)){g.overflowY="scroll"}}else{g.overflow="hidden"}f.textContent=k.value.substring(0,l);if(k.nodeName==="INPUT"){f.textContent=f.textContent.replace(/\s/g,"\u00a0")}var n=document.createElement("span");n.textContent=k.value.substring(l)||".";f.appendChild(n);var m={top:n.offsetTop+parseInt(j["borderTopWidth"]),left:n.offsetLeft+parseInt(j["borderLeftWidth"])};if(h){n.style.backgroundColor="#aaa"}else{document.body.removeChild(f)}return m}if(typeof b!="undefined"&&typeof b.exports!="undefined"){b.exports=c}else{window.getCaretCoordinates=c}}())}])});
    POWERMODE.colorful=true;POWERMODE.shake=false;document.body.addEventListener("input",POWERMODE);

    修改文件

    [! Warning] 这部分基本上全是通过修改文件来达到美化的目的,故一定要提前做好备份~

  • 右侧添加人生倒计时(岁月不待人)

    首先找到网站根目录/usr/themes/handsome/component
    打开sidebar.php文件,找到<!--广告位置-->这一行内容。
    在该内容向上两行找到<?php endif; ?>,在该行紧接着下面添加如下代码:

    <section id="blog_info" class="widget widget_categories wrapper-md clear">
      <h5 class="widget-title m-t-none text-md">
          <?php _me("岁月不待人") ?>
      </h5>
      <div class="sidebar sidebar-count">
          <div class="content">
              <div class="item" id="dayProgress">
                  <div class="title">今日已经过去<span></span>小时</div>
                  <div class="progress">
                      <div class="progress-bar">
                          <div class="progress-inner progress-inner-1"></div>
                      </div>
                      <div class="progress-percentage"></div>
                  </div>
              </div>
              <div class="item" id="weekProgress">
                  <div class="title">这周已经过去<span></span>天</div>
                  <div class="progress">
                      <div class="progress-bar">
                          <div class="progress-inner progress-inner-2"></div>
                      </div>
                      <div class="progress-percentage"></div>
                  </div>
              </div>
              <div class="item" id="monthProgress">
                  <div class="title">本月已经过去<span></span>天</div>
                  <div class="progress">
                      <div class="progress-bar">
                          <div class="progress-inner progress-inner-3"></div>
                      </div>
                      <div class="progress-percentage"></div>
                  </div>
              </div>
              <div class="item" id="yearProgress">
                  <div class="title">今年已经过去<span></span>个月</div>
                  <div class="progress">
                      <div class="progress-bar">
                          <div class="progress-inner progress-inner-4"></div>
                      </div>
                      <div class="progress-percentage"></div>
                  </div>
              </div>
          </div>
      </div>
    </section>
    <!-- 时间倒计时代码结束 -->

    加后的样子如下:
    Pasted image 20240330110713
    改好后保存退出,进入网站根目录/usr/themes/handsome/assets/js/的文件夹
    创建一个名为timeinfo.js的文件,并将以下代码放进该文件后,保存并退出

    function getAsideLifeTime() {
      /* 当前时间戳 */
      let nowDate = +new Date();
      /* 今天开始时间戳 */
      let todayStartDate = new Date(new Date().toLocaleDateString()).getTime();
      /* 今天已经过去的时间 */
      let todayPassHours = (nowDate - todayStartDate) / 1000 / 60 / 60;
      /* 今天已经过去的时间比 */
      let todayPassHoursPercent = (todayPassHours / 24) * 100;
      $('#dayProgress .title span').html(parseInt(todayPassHours));
      $('#dayProgress .progress .progress-inner').css('width', parseInt(todayPassHoursPercent) + '%');
      $('#dayProgress .progress .progress-percentage').html(parseInt(todayPassHoursPercent) + '%');
      /* 当前周几 */
      let weeks = {
          0: 7,
          1: 1,
          2: 2,
          3: 3,
          4: 4,
          5: 5,
          6: 6
          };
      let weekDay = weeks[new Date().getDay()];
      let weekDayPassPercent = (weekDay / 7) * 100;
      $('#weekProgress .title span').html(weekDay);
      $('#weekProgress .progress .progress-inner').css('width', parseInt(weekDayPassPercent) + '%');
      $('#weekProgress .progress .progress-percentage').html(parseInt(weekDayPassPercent) + '%');
      let year = new Date().getFullYear();
      let date = new Date().getDate();
      let month = new Date().getMonth() + 1;
      let monthAll = new Date(year, month, 0).getDate();
      let monthPassPercent = (date / monthAll) * 100;
      $('#monthProgress .title span').html(date);
      $('#monthProgress .progress .progress-inner').css('width', parseInt(monthPassPercent) + '%');
      $('#monthProgress .progress .progress-percentage').html(parseInt(monthPassPercent) + '%');
      let yearPass = (month / 12) * 100;
      $('#yearProgress .title span').html(month);
      $('#yearProgress .progress .progress-inner').css('width', parseInt(yearPass) + '%');
      $('#yearProgress .progress .progress-percentage').html(parseInt(yearPass) + '%');
      }
      getAsideLifeTime();
      setInterval(() => {
          getAsideLifeTime();
      }, 1000);
      }
      init_life_time()

    以下代码放在 后台-外观设置-开发者设置-自定义CSS

    .sidebar-count .content {
      padding: 15px
    }
     
    .sidebar-count .content .item {
      margin-bottom: 15px
    }
     
    .sidebar-count .content .item:last-child {
      margin-bottom: 0
    }
     
    .sidebar-count .content .item .title {
      font-size: 12px;
      color: var(--minor);
      margin-bottom: 5px;
      display: flex;
      align-items: center
    }
     
    .sidebar-count .content .item .title span {
      color: var(--theme);
      font-weight: 500;
      font-size: 14px;
      margin: 0 5px
    }
     
    .sidebar-count .content .item .progress {
      display: flex;
      align-items: center
    }
     
    .sidebar-count .content .item .progress .progress-bar {
      height: 10px;
      border-radius: 5px;
      overflow: hidden;
      background: var(--classC);
      width: 0;
      min-width: 0;
      flex: 1;
      margin-right: 5px
    }
    @keyframes progress {
      0% {
          background-position: 0 0
      }
     
      100% {
          background-position: 30px 0
      }
    }
    .sidebar-count .content .item .progress .progress-bar .progress-inner {
      width: 0;
      height: 100%;
      border-radius: 5px;
      transition: width 0.35s;
      -webkit-animation: progress 750ms linear infinite;
      animation: progress 750ms linear infinite
    }
     
    .sidebar-count .content .item .progress .progress-bar .progress-inner-1 {
      background: #bde6ff;
      background-image: linear-gradient(135deg, #50bfff 25%, transparent 25%, transparent 50%, #50bfff 50%, #50bfff 75%, transparent 75%, transparent 100%);
      background-size: 30px 30px
    }
     
    .sidebar-count .content .item .progress .progress-bar .progress-inner-2 {
      background: #ffd980;
      background-image: linear-gradient(135deg, #f7ba2a 25%, transparent 25%, transparent 50%, #f7ba2a 50%, #f7ba2a 75%, transparent 75%, transparent 100%);
      background-size: 30px 30px
    }
     
    .sidebar-count .content .item .progress .progress-bar .progress-inner-3 {
      background: #ffa9a9;
      background-image: linear-gradient(135deg, #ff4949 25%, transparent 25%, transparent 50%, #ff4949 50%, #ff4949 75%, transparent 75%, transparent 100%);
      background-size: 30px 30px
    }
     
    .sidebar-count .content .item .progress .progress-bar .progress-inner-4 {
      background: #67c23a;
      background-image: linear-gradient(135deg, #4f9e28 25%, transparent 25%, transparent 50%, #4f9e28 50%, #4f9e28 75%, transparent 75%, transparent 100%);
      background-size: 30px 30px
    }
     
    .sidebar-count .content .item .progress .progress-percentage {
      color: var(--info)
    }

    最后一步,将以下代码放在后台-外观设置-开发者设置-自定义输出body尾部

    <script src="https://你的域名/usr/themes/handsome/assets/js/timeinfo.js"></script>

    步骤均完成后,即可去查看效果了~

  • 信息统计增加全站字数、在线人数、响应耗时和访客总数

    首先将以下代码加到/usr/themes/handsome/libs/Content.php中,放在class Content的上面

       function theAllViews(){
               $db = Typecho_Db::get();
               $row = $db->fetchAll('SELECT SUM(VIEWS) FROM `typecho_contents`');
                   echo number_format($row[0]['SUM(VIEWS)']);
       }
    
      /*响应时间*/
      function timer_start() {
          global $timestart;
          $mtime = explode( ' ', microtime()  );
          $timestart = $mtime[1] + $mtime[0];
          return true; 
      }
      timer_start();
      function timer_stop( $display = 0, $precision = 3  ) {
          global $timestart, $timeend;
          $mtime = explode( ' ', microtime()  );
          $timeend = $mtime[1] + $mtime[0];
          $timetotal = number_format( $timeend - $timestart, $precision  );
          $r = $timetotal < 1 ? $timetotal * 1000 . " ms" : $timetotal . " s";
          if ( $display  ) {
              echo $r;
          }
          return $r;
      }
          /**
       * 全站字数
       */
      function allOfCharacters() {
          $chars = 0;
          $db = Typecho_Db::get();
          $select = $db ->select('text')->from('table.contents');
          $rows = $db->fetchAll($select);
          foreach ($rows as $row) { $chars += mb_strlen(trim($row['text']), 'UTF-8'); }
          $unit = '';
          if($chars >= 10000)     { $chars /= 10000; $unit = '万'; } 
          else if($chars >= 1000) { $chars /= 1000;  $unit = '千'; }
          $out = sprintf('%.2lf %s',$chars, $unit);
          return $out;
      } 
    /**
       * 在线人数
       */
      function online_users() {
          $filename='online.txt'; //数据文件
          $cookiename='Nanlon_OnLineCount'; //Cookie名称
          $onlinetime=30; //在线有效时间
          $online=file($filename); 
          $nowtime=$_SERVER['REQUEST_TIME']; 
          $nowonline=array(); 
          foreach($online as $line){ 
              $row=explode('|',$line); 
              $sesstime=trim($row[1]); 
              if(($nowtime - $sesstime)<=$onlinetime){
                  $nowonline[$row[0]]=$sesstime;
              } 
          } 
          if(isset($_COOKIE[$cookiename])){
              $uid=$_COOKIE[$cookiename]; 
          }else{
              $vid=0;
              do{
                  $vid++; 
                  $uid='U'.$vid; 
              }while(array_key_exists($uid,$nowonline)); 
              setcookie($cookiename,$uid); 
          } 
          $nowonline[$uid]=$nowtime;
          $total_online=count($nowonline); 
          if($fp=@fopen($filename,'w')){ 
              if(flock($fp,LOCK_EX)){ 
                  rewind($fp); 
                  foreach($nowonline as $fuid=>$ftime){ 
                      $fline=$fuid.'|'.$ftime."\n"; 
                      @fputs($fp,$fline); 
                  } 
                  flock($fp,LOCK_UN); 
                  fclose($fp); 
              } 
          } 
          echo "$total_online"; 
      }

    然后在/usr/themes/handsome/component/sidebar.php文件内,找到合适和位置添加以下代码: 注:<!--博客信息-->处就是添加代码的地方,找到你想加的位置添加代码即可

    <li class="list-group-item"> <i class="glyphicon glyphicon-user text-muted text-muted"></i> <span class="badge pull-right"><?php echo online_users() ?></span><?php _me("在线人数") ?></li>
    <li class="list-group-item text-second"> <span class="blog-info-icons"> <i data-feather="users"></i></span>
       <span class="badge
     pull-right"><?php echo theAllViews(); ?></span><?php _me("访客总数") ?></li>
    <li class="list-group-item text-second"> <span class="blog-info-icons"> <i data-feather="refresh-ccw"></i></span>
       <span class="badge
     pull-right"><?php echo timer_stop(); ?></span><?php _me("响应耗时") ?></li>

    大概位置如图所示:

    ![[Pasted image 20240330111427.png]]

  • 在博客顶部添加心知天气

    首先去心知天气官网注册账号并申请API
    之后在/usr/themes/handsome/component/headnav.php文件中的动态日历中<?php endif;?>下方添加以下代码
    注意将API信息改成自己的

      <div id="tp-weather-widget" class="navbar-form navbar-form-sm navbar-left shift"></div>
    <script>(function(T,h,i,n,k,P,a,g,e){g=function(){P=h.createElement(i);a=h.getElementsByTagName(i)[0];P.src=k;P.charset="utf-8";P.async=1;a.parentNode.insertBefore(P,a)};T["ThinkPageWeatherWidgetObject"]=n;T[n]||(T[n]=function(){(T[n].q=T[n].q||[]).push(arguments)});T[n].l=+new Date();if(T.attachEvent){T.attachEvent("onload",g)}else{T.addEventListener("load",g,false)}}(window,document,"script","tpwidget","//widget.seniverse.com/widget/chameleon.js"))</script>
    <script>tpwidget("init", {
      "flavor": "slim",
      "location": "WX4FBXXFKE4F",
      "geolocation": "enabled",
      "language": "auto",
      "unit": "c",
      "theme": "chameleon",
      "container": "tp-weather-widget",
      "bubble": "enabled",
      "alarmType": "badge",
      "color": "#C6C6C6",
      "uid": "公钥",
      "hash": "密钥"
    });
    tpwidget("show");</script>
    <!-- 知心结束-->

  • 文章页面页脚插入one一言

    Pasted image 20240330112019
    代码放置开发者设置-文章页脚广告位

    <div >
    <br>
    <font style="font-size:20px;font-family:YouYuan;opacity:0.8;">◈</font>
    <br>
    <script type="text/javascript" src="https://api.xygeng.cn/one/get/" >
    </script>
    </div>
    </small>


最后修改:2024 年 03 月 30 日
如果觉得我的文章对你有用,请随意赞赏