English Title
简体标题
type
Post
status
Published
date
Apr 22, 2022
slug
youtube-for-notion-nextjs
summary
讓 YouTube Chapters 章節功能可以在我的 Blog 中,自由的跳轉播放,這樣使用者不用點擊每個時間點都跳到新的頁面,跳到 YouTube 產生體驗上的割裂感。
tags
useEffect
react.js
React Hook
YouTube
player
hashtag
Javascript
category
程式開發
blog
link
Property
Bilibili
TikTok
抖音
icon
⌚ 時光戳記
在本站中,我常常會嵌入我拍好的 YouTube 影片,而為了讓觀看者有更好的觀看體驗,我會使用 YouTube Chapters 章節功能來標定影片不同時間點的位置。
問題說明
然而,這些時間點通常是在 YouTube 說明欄打上後,再複製到文章後台的,導致每個時間的標示都有連結本身,而連結本身都是連結到 YouTube 頁面的特定時間點,以
t=0s
這樣的形式表示。令人討厭的是我們的內文明明就嵌有一個 YouTube 播放器,為什麼不能讓使用者在 Blog 中直接看我的影片呢?
目標:不刷新切換影片時間點!
今天,我的目標便是讓 YouTube Chapters 章節功能可以在我的 Blog 中,自由的跳轉播放,這樣使用者不用點擊每個時間點都跳到新的頁面,跳到 YouTube 產生體驗上的割裂感。
首先,我們要改裝我們的
react-notion-x
內的連結,當連結跟我的文章的 youtube
屬性有吻合的時候,抓取 t=0s
樣式的秒數,並用 query 改動網頁連結。當
query
連結有改動的時候,YouTube 播放器自動地時間到目標時間。這個過程,我希望頁面不要有刷新。刷新雖然可以帶來閱讀數的增加,不過會使頻繁使用我的 Blog 用戶體驗不佳,產生割裂!技術問題
問題一、 react-notion-x
的跳出 <a>
連結標籤
NotionNext 目前使用的
react-notion-x
版本比較舊一些,目前沒有新一點的版本有的 Next/link
的連結功能,使用的還會是一般 HTML
所使用的 <a>
標籤,不管 href
塞入什麼,都會造成頁面跳出與刷新。問題二、 Next.js Shallow Routing
由於不想改動
react-notion-x
這個套件,我無法從底層將元件從 <a>
變成 <Link>
。當我們點擊連結時,<a>
在處理連結與觸發的時候,會整頁的刷新,而這是我們不想看到的!我要點擊時間只是想要跳到影片的段落位置,而非整頁刷新。其中 Next.js
提供一個功能叫做 “Shallow Routing ”,能夠在不刷新頁面的狀況下,改動 query
。我嘗試將 Shallow Routing 各種寫法接寫過一遍,發現只要連結還是
<a>
頁面便會刷新。既然,
query
不行,那......想法一轉,我們不是有側欄的 Table of Content 可以點擊到不同段落而不會有刷新!
我們塞
hashtag
吧!實作
畫一個 YouTube 播放器
react-youtube
這個插件我使用
react-youtube
這個 npm
套件,建了一個 16:9 的 div
,並在內放入我的播放器! playerVars
用來調控播放器的參數,目前內含 autoplay
與 start
,YTTime
是一個 state
,會隨著 hashtag
來更新秒數。import YouTube from 'react-youtube'
<div className="video-player w-full" style={{ aspectRatio: '16/9' }}>
<YouTube
videoId={youtubeId}
opts={{
width: '100%',
height: '100%',
playerVars: {
start: YTTime,
autoplay: 1
}
}}
/>
</div>
取得 youtubeId
開啟播放器與否,我是由
post
是否有含 youtube
這個 property
來決定的!那來看看我怎麼從 post.youtube
來取得他的 youtubeId
吧!當然,我可以從
post.youtube
用切字串的方式取得 v=
這個 youtube
連結的參數,不過既然是 URL
的 params
我們就用 javascript
的方式解決!const YouTubeURL = new URL(post.youtube)
const params = new URLSearchParams(YouTubeURL.search)
youtubeId = params.get('v')
處理 <a>
連結
useEffect
我們先建一個只跑一次的
useEffect
useEffect(() => {
}, [])
getElements...
在
React
中,我們應該將所有的元件都切成一個一個獨立運作的 Component
,然而,我們今天要改動的元件卻是在 react-notion-x
中的元件,因不改動套件,我們使用基礎的 JavaScript
語法,抓取元件並對連結做改動。const container = document?.getElementById('container')
const a = container?.getElementsByClassName('notion-link')
//---
item.href.includes('youtube')
item.href.includes('t=')
我一步一步抓取元件、取得連結並篩選只有與 YouTube 相關的連結。我們要對於 YouTube 連結的時間點抓取秒數。
更換連結位置
避免
<a>
連結將頁面跳到新頁,我將 target
與 rel
的參數設定為空值,href
則為 youtube-time 的時間點!// 把連結換成 hash 並取消點擊連結開新頁
a[i].href = `#youtube-time=${urlTime}`
a[i].target = ''
a[i].rel = ''
這樣使用 hashtag 就可以自由切換 url ,但頁面不會跳轉!這是
html
一直以來都有的功能!抓取 #HashTag 時間,改變播放器時間!
當 hash 改變,則...
我們運用
react component
的useEffect
hook
來 mount
元件,使用 hash
的 event listener
來確保 hash
改變的時候,會執行 state change
const onHashChanged = () => {
// run when hash change!
}
window.addEventListener('hashchange', onHashChanged)
return () => {
window.removeEventListener('hashchange', onHashChanged)
}
改變播放器時間
先抓取
hash
,因為有些標題使用到 hash
,我們確保他有 youtube-time
才去抓取時間,並設定 setYTTime 讓 YouTube 播放器跳轉到 hash
上的時間!const linkHash = window.location.hash
if (linkHash.includes('youtube')) {
setYTTime(parseInt(linkHash.replace(/\D/g, '')))
}
這邊,我們大致將不刷新切到時間點的功能做好了!不過,我們在點擊連結的時候,可能連結與播放器的位置有一段頁面上的距離。我們來讓它點擊後,會跑到播放器的位置!
賦予新 #HashTag 錨定位置
創立錨定點
創建一個
div
,它與 notion-header-anchor
標題的錨定點有同樣的 class
,繼承一些原有的設計。我為他加上 yt-anchor
來讓它有著一些獨特的性質。我們將錨定點 id
設為 youtube-time=5s
的形式來讓點擊 hashtag
後可以跳到這邊!const newYTAnchor = document.createElement('div')
newYTAnchor.id = `youtube-time=${urlTime}`
newYTAnchor.classList.add('yt-anchor')
newYTAnchor.classList.add('notion-header-anchor')
塞到播放器前面
const videoPlayer =
document.getElementsByClassName('video-player')
if (videoPlayer) {
videoPlayer[0].prepend(newYTAnchor)
}
我們將錨定點塞到 videoPlayer 前面,確保點擊不同的時光戳記,都會滑動到播放器的位置!
Future work
當我剛寫完我的 YouTube 插件後,發現
react
還有除了 react-youtube
外的另外一個插件,而且還更強大!它就是 react-player
! 看來要找時間再改寫並加入更多功能!插件 Code 在這邊!如果大家喜歡這篇文章歡迎分享或是留言跟我交流喔!
- Author:Andy
- URL:https://tw.andys.pro/article/youtube-for-notion-nextjs
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!
Relate Posts
2022-11-17
Error message "error:0308010C:digital envelope routines::unsupported” React 錯誤如何解決
2022-10-09
開箱 Apple Watch Ultra 綠色高山回環錶帶! S 號大小剛好!跟 Mystery Ranch 綠色狩獵包搭配合嗎?
2022-05-23
美化 Prism.js 擁有漂亮的 Mac 風格視窗與 One Dark 主題,讓程式部落格更好看!
2022-04-11
如何喚起 Facebook comment plugin?
2022-04-05
NotionNext Facebook Customer Chat Bubble
2022-04-04
NotionNext Facebook Open Graph url, image 優化, Vercel 衝突解決!
留言區
如果你想使用 Facebook, Google, Twitter 帳號留言,或是匿名分享,可以使用 Disqus 留言。
擁有 Facebook 帳號的朋友可以使用 Facbook 原生社群插件留言。
若是有 Github 帳號可以使用 Giscus 留言!