日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

Typecho插件實現添加文章目錄的方法詳解

瀏覽:328日期:2022-06-06 16:20:51
目錄
  • 添加文章標題錨點
  • 顯示文章目錄
  • 添加文章目錄樣式
  • 定位到文章
  • 定位到目錄

我的長博文不少,比較影響閱讀體驗,有必要添加一個文章目錄功能。相比 Wordpress, Typecho 的插件就比較少了。我想找一個像掘金那樣為文章添加目錄的插件,沒一個合適的。此類教程也不是很多,而且差不多都是前臺 JavaScript 來實現的,感覺這樣不如后臺實現來的好。

注意:我使用的是Joe主題7.3,其他主題文件路徑可能不一樣。

添加文章標題錨點

1.聲明 createAnchor 函數

core/functions.php 中添加如下代碼:

// 添加文章標題錨點
function createAnchor($obj) {
  global $catalog;
  global $catalog_count;
  $catalog = array();
  $catalog_count = 0;
  $obj = preg_replace_callback("/<h([1-4])(.*?)>(.*?)<\/h\1>/i", function($obj) {
    global $catalog;
    global $catalog_count;
    $catalog_count ++;
    $catalog[] = array("text" => trim(strip_tags($obj[3])), "depth" => $obj[1], "count" => $catalog_count);
    return "<h".$obj[1].$obj[2]." id="cl-".$catalog_count."">".$obj[3]."</h".$obj[1].">";
  }, $obj);
  return $obj;
}

也可以在標題元素內添加 <a> 標簽,然后該標簽新增 id 屬性。

createAnchor 函數主要是通過正則表達式替換文章標題H1~H4來添加錨點,接下來我們需要調用它。

2.調用函數

同樣在 core/core.php 中的 themeInit 方法最后一行之前添加如下代碼:

if ($self->is("single")) {
  $self->content = createAnchor($self->content);
}

現在可以查看一下文章詳情頁面的源代碼。文章的 H1~H4 元素應該添加了諸如 cl-1cl-2 之類的 id 屬性值。具體啥名不是關鍵,好記就行。

顯示文章目錄

1.聲明 getCatalog 函數

core/functions.php 中添加如下代碼:

// 顯示文章目錄
function getCatalog() {  
  global $catalog;
  $str = "";
  if ($catalog) {
    $str = "<ul>"."\n";
    $prev_depth = "";
    $to_depth = 0;
    foreach($catalog as $catalog_item) {
      $catalog_depth = $catalog_item["depth"];
      if ($prev_depth) {
if ($catalog_depth == $prev_depth) {
  $str .= "</li>"."\n";
} elseif ($catalog_depth > $prev_depth) {
  $to_depth++;
  $str .= "<ul>"."\n";
} else {
  $to_depth2 = ($to_depth > ($prev_depth - $catalog_depth)) ? ($prev_depth - $catalog_depth) : $to_depth;
  if ($to_depth2) {
    for ($i=0; $i<$to_depth2; $i++) {
      $str .= "</li>"."\n"."</ul>"."\n";
      $to_depth--;
    }
  }
  $str .= "</li>";
}
      }
      $str .= "<li><a href="#cl-".$catalog_item["count"]."" rel="external nofollow"  title="".$catalog_item["text"]."">".$catalog_item["text"]."</a>";
      $prev_depth = $catalog_item["depth"];
    }
    for ($i=0; $i<=$to_depth; $i++) {
      $str .= "</li>"."\n"."</ul>"."\n"; 
    }
    $str = "<section>"."\n"."<div>文章目錄</div>"."\n".$str."</section>"."\n";
  }
  echo $str;
}

getCatalog 方法通過遞歸 $catalog 數組生成文章目錄,接下來我們需要調用它。

2.函數

最好將放在右側邊欄中。為此在 public/aside.php 中添加如下代碼:

<?php if ($this->is("post")) getCatalog(); ?>

注意:只有文章才使用目錄,獨立頁面那些不需要,所以加了判斷。Typecho 有一些神奇的 is 語法可以方便二次開發,可以訪問它的官網文檔了解更多。

現在點擊右側的文章目錄,可以滾動到相應的文章小標題位置了。

添加文章目錄樣式

可以看到,當前的文章目錄還比較丑陋,我們來美化一下。在 assets/css/joe.post.min.scss 中添加如下 SCSS 代碼:

.joe_aside {
  .toc {
    position: sticky;
    top: 20px;
    width: 250px;
    background: var(--background);
    border-radius: var(--radius-wrap);
    box-shadow: var(--box-shadow);
    overflow: hidden;

    .title {
      display: block;
      border-bottom: 1px solid var(--classA);
      font-size: 16px;
      font-weight: 500;
      height: 45px;
      line-height: 45px;
      text-align: center;
      color: var(--theme);
    }

    .list {
      padding-top: 10px;
      padding-bottom: 10px;
      max-height: calc(100vh - 80px);
      overflow: auto;

      .link {
display: block;
padding: 8px 16px;
border-left: 4px solid transparent;
color: var(--main);
text-decoration: none;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;

&:hover {
  background-color: var(--classC);
}

&.active {
  border-left-color: var(--theme);
}
      }
    }
  }
}

為了方便操作,將 .toc 設置成 position: sticky; 實現了吸頂定位。考慮到文章目錄可能很多,為 .toc 列表添加了 overflow: auto;,如代碼第 3 ~ 4 行。

由于 .joe_header(主題標頭)也使用了吸頂定位,導致和文章目錄有遮擋,所有加了 has_toc .joe_header 來取消頁面主題標頭的吸頂功能,如下代碼:

.has_toc {
  .joe_header {
    position: relative;
  }
}

定位到文章

要顯示文章目錄當前選中項的狀態,需要用到 JavaScript 給選中項添加一個 active 樣式。在 assets/js/joe.post_page.js 中添加如下代碼:

var headings = $(".joe_detail__article").find("h1, h2, h3, h4");
var links = $(".toc .link");
var tocList = document.querySelector(".tocr > .list");
var itemHeight = $(".toc .item").height();
var distance = tocList.scrollHeight - tocList.clientHeight;
var timer = 0;
// 是否自動滾動
var autoScrolling = true;

function setItemActive(id) {
  links.removeClass("active");
  var link = links.filter("[href="#" + id + ""]")
  link.addClass("active");
}

function onChange() {
  autoScrolling = true;
  if (location.hash) {
    id = location.hash.substr(1);
    var heading = headings.filter("[id="" + id + ""]");
    var top = heading.offset().top - 15;
    window.scrollTo({ top: top })
    setItemActive(id)
  }
}
window.addEventListener("hashchange", onChange);
// hash沒有改變時手動調用一次
onChange();

由于布局和滾動動畫的影響,導致錨點定位有點偏差。我們再 setItemActive 函數中用 scrollToscrollIntoView 來糾正。另外,我們希望有錨點的鏈接可以直接定位,因此監聽了 hashchange 事件。點擊文章目錄測試一下定位,再手動鍵入錨點測試一下,應該都沒啥問題。

定位到目錄

目前可以從文章目錄定位到文章標題了,是單向定位,雙向定位還需要實現滾動文章內容時定位到文章目錄的當前項。正如我們馬上能想到的,需要監聽 windowscroll 事件,如下代碼:

function onScroll() {
  if (timer) {
    clearTimeout(timer);
  }
  timer = setTimeout(function () {
    var top = $(window).scrollTop();
    var count = headings.length;
    for (var i = 0; i < count; i++) {
      var j = i;
      // 滾動和點擊時 index 相差 1,需要 autoScrolling 來區分
      if (i > 0 && !autoScrolling) {
j = i - 1;
      }
      var headingTop = $(headings[i]).offset().top;
      var listTop = distance * i / count
      // 判斷滾動條滾動距離是否大于當前滾動項可滾動距離
      if (headingTop > top) {
var id = $(headings[j]).attr("id");
setItemActive(id);
// 如果目錄列表有滑條,使被選中的下一元素可見
if (listTop > 0) {
  // 向上滾動
  if (listTop < itemHeight) {
    listTop -= itemHeight;
  } else {
    listTop += itemHeight;
  }
  $(tocList).scrollTop(listTop)
}
break;
      } else if (i === count - 1) {
// 特殊處理最后一個元素
var id = $(headings[i]).attr("id");
setItemActive(id);
if (listTop > 0) {
  $(tocList).scrollTop(distance)
}
      }
    }
    autoScrolling = false;
  }, 100);
}

$(window).on("scroll", onScroll);

首先,在 onScroll 事件處理函數中遍歷標題數組 headings, 如果滾動條滾動距離 top 大于當前標題項 item 可滾動距離 headingTop,再調用 setItemActive 函數,傳入當前的標題項的 id 來判斷文章目錄激活狀態。

如果目錄列表有滑條,調用 jQuery 的 scrollTop 方法滾動目錄列表滑條,使被選中目錄項的上下元素可見,

現在文章目錄基本上可用了,也還美觀,后續可以考慮優化再封裝成一個插件。

吐槽一下:Joe 主題太依賴jQuery了,修改起來費勁 ::(汗)。

到此這篇關于Typecho插件實現添加文章目錄的方法詳解的文章就介紹到這了,更多相關Typecho添加文章目錄內容請搜索以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持!

標簽: PHP
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
日本欧美不卡| 欧美国产日韩电影| 久久精品毛片| 国产精品久久777777毛茸茸| 激情综合在线| 亚洲精品一区二区妖精| 日韩中文字幕区一区有砖一区| 国产亚洲福利| 欧美一区免费| 成人在线免费观看91| 亚洲特色特黄| 99成人在线视频| 精品国模一区二区三区| 国产精品亚洲综合在线观看| 国产一区二区三区91| 精品久久久中文字幕| 高清一区二区| 欧美成人国产| 国产福利资源一区| 亚洲专区视频| 精品免费av一区二区三区| 国产精品亚洲四区在线观看| 欧美黑人巨大videos精品| 成人台湾亚洲精品一区二区| 美女av在线免费看| 亚洲精品123区| 午夜国产欧美理论在线播放| 亚洲一区二区三区高清| 日韩精品国产欧美| 久久精品亚洲一区二区| 国产成人精品一区二区免费看京| 桃色一区二区| av不卡在线看| 日韩美女精品| 美女久久久精品| 少妇久久久久| 亚洲欧美专区| 亚洲黄页一区| 亚洲日产av中文字幕| 亚洲尤物av| 国产精品亚洲人成在99www| 国产a久久精品一区二区三区| 久久精品av| 日韩精品免费视频人成| 在线亚洲人成| 国产精区一区二区| 福利一区视频| 亚洲欧美日韩国产综合精品二区| 欧美好骚综合网| 亚洲爱爱视频| 快she精品国产999| 国产精品日韩精品中文字幕| 国产中文在线播放| 免费在线观看成人| 精品三级久久久| 合欧美一区二区三区| 欧美极品一区二区三区| 99久久夜色精品国产亚洲1000部| 亚洲综合色婷婷在线观看| 免费一级欧美在线观看视频 | 国产乱码精品一区二区三区四区| 欧美日韩国产欧| 91福利精品在线观看| 91精品一区二区三区综合在线爱| 久久国产精品99国产| 老色鬼精品视频在线观看播放| 久久国产电影| 国产精品免费99久久久| 黄色精品网站| 亚洲天堂av影院| 热久久久久久| 中文欧美日韩| 日韩中文在线电影| 国产精品v一区二区三区| 婷婷综合社区| 麻豆一区二区三区| 亚洲精品视频一二三区| 成人片免费看| 欧美在线看片| 久久免费国产| 日本久久二区| 日韩午夜一区| а√天堂8资源在线| 视频一区日韩精品| 女人天堂亚洲aⅴ在线观看| 精品国产亚洲日本| 日本亚洲不卡| 丝瓜av网站精品一区二区| 久久婷婷国产| 国产日韩一区二区三区在线| 日韩精品一级中文字幕精品视频免费观看| 人人草在线视频| 欧美一级二级视频| 日韩精品一二三四| 欧美日韩日本国产亚洲在线| 日韩理论片av| 久久中文字幕一区二区| 日本欧美韩国一区三区| 亚洲自啪免费| 久久人人97超碰国产公开结果| 国产精品s色| 日韩黄色在线观看| 免费在线欧美视频| 国产亚洲一级| 香蕉精品视频在线观看| 国产+成+人+亚洲欧洲在线| 欧美三级第一页| 蜜桃视频在线观看一区| 欧美日韩精品免费观看视频完整| 成人在线网站| 欧美三级网址| 中文字幕高清在线播放| 成人精品视频| 成人精品高清在线视频| 日本国产一区| 日本在线不卡视频| 美美哒免费高清在线观看视频一区二区| 日韩伦理一区| 久久美女性网| 亚洲高清二区| 欧美不卡高清| 日韩一级欧洲| 狠狠爱成人网| 美女少妇全过程你懂的久久| 韩国精品主播一区二区在线观看| av在线资源| 色婷婷狠狠五月综合天色拍| 久久久精品午夜少妇| 欧美日韩尤物久久| 久久精品青草| 尤物精品在线| 亚洲精品无播放器在线播放| 日韩极品在线观看| 你懂的国产精品永久在线| 国产精品久久久网站| 黄色精品视频| 91精品精品| 国产一区二区精品| 一区二区三区四区日韩| 中文字幕日本一区二区| 日本中文字幕一区二区视频| 国产午夜久久av| 久久一区精品| 高潮一区二区| 久久久久99| 在线亚洲观看| 日韩成人午夜精品| 国产欧美啪啪| 中文字幕在线免费观看视频| 亚洲天堂成人| 六月丁香综合| 国产日韩中文在线中文字幕| 精品一区二区三区免费看| 国产一区丝袜| 国产一区日韩一区| 欧美精品中文| 精品一区电影| 欧美日韩一区二区综合| 亚洲日本免费电影| 国产精品多人| 精品久久视频| 婷婷综合激情| 欧美天堂一区| 日韩欧美精品| 亚洲精品动态| 开心激情综合| 精品一区在线| 日韩一区二区三免费高清在线观看 | 国产精品av一区二区| 欧美专区18| 国产精品网站在线看| 亚洲电影有码| 日韩精品三区四区| 亚洲深夜视频| 亚洲精品韩国| 国产欧美高清| 欧美日韩一二| 国产日产精品_国产精品毛片| 老牛国内精品亚洲成av人片| 亚洲一级二级| 国产精品日韩精品中文字幕| 久久免费高清| 国产精品亚洲四区在线观看 | 午夜在线观看免费一区| 国产精品美女在线观看直播| 久久久精品网| 欧美精品福利| 亚洲在线一区| 国产欧美91| 亚洲免费播放| 国产精品久久久久久久久久妞妞 | 只有精品亚洲| 日韩综合在线| 色综合视频一区二区三区日韩 | 99国产精品自拍| 国产精品magnet| 老牛影视一区二区三区| 中文在线资源| 国产欧美一区二区三区精品观看| 香蕉国产精品|