mirror of
https://github.com/suk-ws/ph-Bookshelf.git
synced 2024-12-05 09:26:52 +08:00
使切换页面支持了(半个)pjax动态加载
- 现在在支持 javascript 的浏览器环境中,Book 和 Page 的链接将会采用异步局部更新的方式进行更新 - 在进行更新时,内容区域的透明度会降为 20% - 使 index 支持了请求部分页面内容 - 在 raw=true 时,将会只输出内容容器内的内容 - 在 nav=true 时,内容输出的前面会添加一行请求书籍的目录 - 给 page 和 book 链接添加了 'type/id' 格式的 id 和 'type-id' 的自定义属性
This commit is contained in:
parent
e4db1984b9
commit
6e5f71b96b
@ -102,3 +102,11 @@
|
|||||||
#book-search-input {
|
#book-search-input {
|
||||||
background-color: var(--color-nav-background-base);
|
background-color: var(--color-nav-background-base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#page-container {
|
||||||
|
transition-duration: 400ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page-container.loading {
|
||||||
|
opacity: 0.2;
|
||||||
|
}
|
||||||
|
@ -3,9 +3,14 @@ const WITH_SUMMARY_CLASS = "with-summary"
|
|||||||
const DROPDOWN_OPEN_CLASS = "open";
|
const DROPDOWN_OPEN_CLASS = "open";
|
||||||
|
|
||||||
let bookRoot;
|
let bookRoot;
|
||||||
|
let pageContainer;
|
||||||
|
let inBookNavContainer;
|
||||||
|
|
||||||
let fontSettingDiv;
|
let fontSettingDiv;
|
||||||
|
|
||||||
|
let bookCurrentId;
|
||||||
|
let pageCurrentId;
|
||||||
|
|
||||||
function summaryOnOrOff () {
|
function summaryOnOrOff () {
|
||||||
|
|
||||||
if (bookRoot.classList.contains(WITH_SUMMARY_CLASS)) {
|
if (bookRoot.classList.contains(WITH_SUMMARY_CLASS)) {
|
||||||
@ -19,6 +24,8 @@ function summaryOnOrOff () {
|
|||||||
window.onload = function () {
|
window.onload = function () {
|
||||||
|
|
||||||
bookRoot = document.getElementsByClassName("book")[0];
|
bookRoot = document.getElementsByClassName("book")[0];
|
||||||
|
pageContainer = document.getElementById("page-container");
|
||||||
|
inBookNavContainer = document.getElementById("in-book-nav-container");
|
||||||
|
|
||||||
fontSettingDiv = document.getElementsByClassName("font-settings")[0].getElementsByClassName("dropdown-menu")[0];
|
fontSettingDiv = document.getElementsByClassName("font-settings")[0].getElementsByClassName("dropdown-menu")[0];
|
||||||
|
|
||||||
@ -28,16 +35,17 @@ window.onload = function () {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
for (let node of document.getElementsByClassName("fold")) {
|
function bindFolderClickEvent () {
|
||||||
node.childNodes[0].addEventListener("click", function () {
|
for (let node of document.getElementsByClassName("fold")) {
|
||||||
if (node.classList.contains("on")) {
|
node.childNodes[0].addEventListener("click", function () {
|
||||||
node.classList.remove("on");
|
if (node.classList.contains("on")) {
|
||||||
} else node.classList.add("on");
|
node.classList.remove("on");
|
||||||
});
|
} else node.classList.add("on");
|
||||||
}
|
});
|
||||||
|
}
|
||||||
|
} bindFolderClickEvent();
|
||||||
|
|
||||||
for (const node of document.getElementsByClassName("summary-container")) {
|
for (const node of document.getElementsByClassName("summary-container")) {
|
||||||
|
|
||||||
node.nextElementSibling.innerHTML = node.nextElementSibling.innerHTML + "<a class='summary-container-icon'><i class='fa'></i></a>";
|
node.nextElementSibling.innerHTML = node.nextElementSibling.innerHTML + "<a class='summary-container-icon'><i class='fa'></i></a>";
|
||||||
node.nextElementSibling.getElementsByClassName("summary-container-icon")[0].addEventListener("click", function () {
|
node.nextElementSibling.getElementsByClassName("summary-container-icon")[0].addEventListener("click", function () {
|
||||||
if (node.classList.contains("on")) {
|
if (node.classList.contains("on")) {
|
||||||
@ -46,7 +54,6 @@ for (const node of document.getElementsByClassName("summary-container")) {
|
|||||||
node.classList.add("on")
|
node.classList.add("on")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function openOrCloseFontSettings () {
|
function openOrCloseFontSettings () {
|
||||||
@ -114,3 +121,70 @@ function setCookie(name, value) {
|
|||||||
const expires = "expires=" + d.toGMTString()
|
const expires = "expires=" + d.toGMTString()
|
||||||
document.cookie = name + "=" + value + "; " + expires;
|
document.cookie = name + "=" + value + "; " + expires;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updatePage (bookId, pageId = "") {
|
||||||
|
|
||||||
|
const isNavRefresh = bookId !== bookCurrentId;
|
||||||
|
const request = new XMLHttpRequest();
|
||||||
|
const url = (
|
||||||
|
"/" + bookId + "/" + pageId
|
||||||
|
);
|
||||||
|
const urlParam = (
|
||||||
|
"?raw=true" +
|
||||||
|
((isNavRefresh)?("&nav=true"):(""))
|
||||||
|
)
|
||||||
|
request.open("GET", url + urlParam, true);
|
||||||
|
console.log(url + urlParam);
|
||||||
|
request.onreadystatechange = function () {
|
||||||
|
if (request.readyState === 4 && request.status === 200) {
|
||||||
|
|
||||||
|
// data
|
||||||
|
const data = request.responseText.split("\n", 2);
|
||||||
|
const nav = isNavRefresh?data[0]:"";
|
||||||
|
const content = request.responseText.substr(nav.length);
|
||||||
|
console.log(nav);
|
||||||
|
console.log(content);
|
||||||
|
// content
|
||||||
|
pageContainer.innerHTML = content;
|
||||||
|
if (!isNavRefresh) document.getElementById("page/"+pageCurrentId).classList.remove("active");
|
||||||
|
if (!isNavRefresh) pageCurrentId = pageId;
|
||||||
|
if (!isNavRefresh) document.getElementById("page/"+pageId).classList.add("active");
|
||||||
|
// nav
|
||||||
|
if (isNavRefresh) {
|
||||||
|
inBookNavContainer.innerHTML = nav;
|
||||||
|
if (bookCurrentId !== "%root")
|
||||||
|
document.getElementById("book/"+bookCurrentId).classList.remove("active");
|
||||||
|
bookCurrentId = bookId;
|
||||||
|
pageCurrentId = inBookNavContainer.getElementsByClassName("active")[0].getAttribute("page-id");
|
||||||
|
document.getElementById("book/"+bookId).classList.add("active");
|
||||||
|
bindFolderClickEvent();
|
||||||
|
bindPageLinkClickEvent();
|
||||||
|
}
|
||||||
|
// history
|
||||||
|
window.history.pushState(document.documentElement.innerHTML, document.title, url);
|
||||||
|
pageContainer.classList.remove("loading");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
request.send();
|
||||||
|
pageContainer.classList.add("loading");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function bindBookLinkClickEvent () {
|
||||||
|
for (let node of document.getElementsByClassName("link-book")) {
|
||||||
|
node.children[0].removeAttribute("href");
|
||||||
|
node.childNodes[0].addEventListener("click", function () {
|
||||||
|
updatePage(node.getAttribute("book-id"));
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
} bindBookLinkClickEvent();
|
||||||
|
|
||||||
|
function bindPageLinkClickEvent () {
|
||||||
|
for (let node of document.getElementsByClassName("link-page")) {
|
||||||
|
node.children[0].removeAttribute("href");
|
||||||
|
node.childNodes[0].addEventListener("click", function () {
|
||||||
|
updatePage(bookCurrentId, node.getAttribute("page-id"));
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
} bindPageLinkClickEvent();
|
||||||
|
18
index.php
18
index.php
@ -17,6 +17,10 @@ try {
|
|||||||
|
|
||||||
SiteMeta::load();
|
SiteMeta::load();
|
||||||
|
|
||||||
|
// 检查是否为 ajax 请求
|
||||||
|
$rawContent = $_GET['raw']=="true";
|
||||||
|
$rawWithNav = $_GET['nav']=="true";
|
||||||
|
|
||||||
// 格式化所给链接,并将链接转化为路径字符串数组
|
// 格式化所给链接,并将链接转化为路径字符串数组
|
||||||
$req = $_GET['p'];
|
$req = $_GET['p'];
|
||||||
if (strlen($req) > 0 && $req[strlen($req) - 1] === '/')
|
if (strlen($req) > 0 && $req[strlen($req) - 1] === '/')
|
||||||
@ -66,6 +70,12 @@ try {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($rawContent && $rawWithNav) {
|
||||||
|
echo PageMeta::$book->getSummaryHtml() . "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$rawContent) :
|
||||||
|
|
||||||
require "./template/header.php";
|
require "./template/header.php";
|
||||||
|
|
||||||
?>
|
?>
|
||||||
@ -123,11 +133,12 @@ try {
|
|||||||
</div>
|
</div>
|
||||||
<h1>
|
<h1>
|
||||||
<i class="fa fa-circle-o-notch fa-spin"></i>
|
<i class="fa fa-circle-o-notch fa-spin"></i>
|
||||||
<a><?= PageMeta::$book->getName() ?></a>
|
<a id="page-title"><?= PageMeta::$book->getName() ?></a>
|
||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<div class="page-wrapper" tabindex="-1" role="main">
|
<div class="page-wrapper" tabindex="-1" role="main">
|
||||||
<div class="page-inner">
|
<div id="page-container" class="page-inner">
|
||||||
|
<?php endif; ?>
|
||||||
<div id="book-search-results">
|
<div id="book-search-results">
|
||||||
<div class="search-noresults">
|
<div class="search-noresults">
|
||||||
<section class="normal markdown-section">
|
<section class="normal markdown-section">
|
||||||
@ -136,6 +147,7 @@ try {
|
|||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<?php if (!$rawContent) : ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -145,6 +157,8 @@ try {
|
|||||||
|
|
||||||
require "./template/footer.php";
|
require "./template/footer.php";
|
||||||
|
|
||||||
|
endif;
|
||||||
|
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
|
|
||||||
echo "<h1>ERROR</h1><p>" . $e->getMessage() . "</p>";
|
echo "<h1>ERROR</h1><p>" . $e->getMessage() . "</p>";
|
||||||
|
@ -54,7 +54,7 @@ class Book {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function getHtml (): string {
|
public function getHtml (): string {
|
||||||
return "<li class='link" . (PageMeta::$book->getId()==$this->id?" active":"") . "'><a class='link' " . (PageMeta::$book->getId()==$this->id?"":" href='/$this->id'") . ">$this->name</a></li>";
|
return "<li id='book/$this->id' book-id='$this->id' class='link link-book" . (PageMeta::$book->getId()==$this->id?" active":"") . "'><a class='link' " . (PageMeta::$book->getId()==$this->id?"":" href='/$this->id'") . ">$this->name</a></li>";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -64,7 +64,7 @@ class BookContented {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function getSummaryHtml (): string {
|
public function getSummaryHtml (): string {
|
||||||
return $this->childs->getSummaryHtml();
|
return "<div id='in-book-nav-container'>" . $this->childs->getSummaryHtml() . "</div>";
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPage (string $id): ?Page {
|
public function getPage (string $id): ?Page {
|
||||||
|
@ -73,7 +73,7 @@ class Page {
|
|||||||
|
|
||||||
public function getSummaryHtml (): string {
|
public function getSummaryHtml (): string {
|
||||||
$str =
|
$str =
|
||||||
"<li class='page-contented chapter" .
|
"<li id='page/$this->id' page-id='$this->id' class='page-contented chapter link-page " .
|
||||||
(PageMeta::$page->getId()==$this->id?" active":"") .
|
(PageMeta::$page->getId()==$this->id?" active":"") .
|
||||||
"'><a class='page-contented' " .
|
"'><a class='page-contented' " .
|
||||||
(
|
(
|
||||||
|
@ -11,7 +11,11 @@
|
|||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<script><?= SiteMeta::getCustomScriptContent("custom") ?></script>
|
<script><?= SiteMeta::getCustomScriptContent("custom") ?></script>
|
||||||
|
<script>
|
||||||
|
bookCurrentId = "<?= PageMeta::$book->getId() ?>";
|
||||||
|
pageCurrentId = "<?= PageMeta::$page->getId() ?>";
|
||||||
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
Loading…
Reference in New Issue
Block a user