给文章添加自定义文本锚点
发表于更新于
字数总计:1.1k阅读时长:5分钟阅读量:
QX-AI初始化中...
暂无预设简介,请点击下方生成AI简介按钮。
前言
起因是群里有人提出,搜索关键词后只能跳转到对应文章,而不能自动再跳转至关键词处,当然,本文不是实现这个(实际上已经实现了),这给了我一个想法,为啥不弄个文本锚点呢,把选中的文本都保存起来,点击就滚动页面过去,这是一个不错的主意。
功能:选中页面文字保存锚点,点击锚点,页面滚动到对应文本处并背景高亮,当一个锚点对应多处文本时,多次点击锚点,页面能循环地逐个滚动到对应位置。
效果:
实现
首先是右侧悬浮栏的锚点按钮和容器,修改\layout\includes\rightside.pug
,对应着原有缩进添加。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| when 'anchor' if is_post() button#post-anchor i.fas.fa-book #post-anchor-after #post-anchor-rom #post-anchor-box #no-anchor 没有锚点 script. var anchor_back = ''; var anchor_length = 0; var anchor_node = ''; function toAnchor(obj) { var anchor = $(obj).text(); $("anchorbox").parent().each(function(){ $(this).html($(this).html().replace(/(<\/?anchorbox.*?>)/g,'')); }) if(anchor_back == anchor){ i++; if(i>=anchor_length){ i = 0; } }else{ i = 0; anchor_back = anchor; anchor_node = $('#article-container *:contains('+anchor+')').not(".highlight *,.mini-sandbox *,.tag.link *,.folding-tag *"); anchor_length = anchor_node.length; } if(anchor_length>0){ btf.snackbarShow("该锚点对应有 "+anchor_length+" 处文本,当前:"+(i+1)); btf.scrollToDest(anchor_node.eq(i).offset().top-200); }else{ btf.snackbarShow("文章内没有对应文本或出现致命错误,请避免选中跨标签跨行文本。"); } let input = anchor; let textNodes = []; (function getTextNodes(node) { if (node.nodeType === Node.TEXT_NODE) { textNodes.push(node); } else { for (let i = 0; i < node.childNodes.length; i++) { getTextNodes(node.childNodes[i]); } } })(document.getElementById("article-container")); for (let i = 0; i < textNodes.length; i++) { let node = textNodes[i]; let text = node.nodeValue; let index = text.indexOf(input); if (index !== -1) { let newNode = document.createElement("anchorbox"); newNode.appendChild(document.createTextNode(text.substring(index, index + input.length))); node.nodeValue = text.substring(0, index); node.parentNode.insertBefore(newNode, node.nextSibling); node.parentNode.insertBefore(document.createTextNode(text.substring(index + input.length)), newNode.nextSibling); } } } …………
#rightside - const { enable, hide, show } = theme.rightside_item_order - const hideArray = enable ? hide && hide.split(',') : ['refresh','translate','enlargePage','narrowPage','bg','darkmode','hideAside'] - const showArray = enable ? show && show.split(',') : ['toc','anchor','chat','comment', 'share']
|
然后是右键选中文字添加锚点按钮rightside.pug
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| a.rightMenu-item(href="javascript:addAnchor();") script. function addAnchor () { if($("#no-anchor").length > 0){ $("#no-anchor").remove(); } var txt = window.getSelection().toString(); txt = txt.replace(/<[^>]*>/g, ""); $("#post-anchor-box").prepend('<a class="anchor-item" href="javascript:void(0);" onclick="toAnchor(this)" data-pjax-state="">'+txt+'</a>'); btf.snackbarShow("成功添加一个文本锚点"); } i.fa.fa-book span='添加锚点'
|
当然没有右键就把js拿去,监听下选中文字后弹出个按钮触发一下addAnchor()
就行。右键教程可看自定义右键菜单
添加CSS:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
| #post-anchor{ z-index: 10!important; } #post-anchor-rom{ position: fixed; width: auto; overflow: hidden; border-radius: 12px; bottom: 20px; right: -241px; border: var(--anchor-border); transition: all .27s; opacity: 0; max-height: 380px; height: 100%; width: 240px; z-index: 9; } #post-anchor-box{ display:flex; background: #fff; max-height: 380px; height: 100%; flex-wrap: nowrap; flex-direction: column; justify-content: flex-start; border-radius: 12px; overflow: auto; } #post-anchor-after{ display: none; position: fixed; bottom: 20px; right: 0px; background: transparent; max-height: 380px; height: 100%; width: 100px; } #post-anchor-box a{ padding: 5px 10px; width: 100%; border-bottom: 1px solid rgb(8, 148, 235); font-weight: 800; } #post-anchor:hover #post-anchor-rom{ opacity: 1; right: 70px; transition: all .25s; } #post-anchor:hover #post-anchor-after{ display:block; } #article-container anchorbox{ color: black!important; font-weight: 800!important; border-radius: 6px!important; background-color: rgb(253 253 20 / 70%)!important; } a.anchor-item{ font-size: 16px; line-height: 17px; text-align: left; } a.anchor-item:hover{ background-color: #16b2ef; color: #fff; } #no-anchor{ color: rgb(140, 140, 140); font-size: 30px; line-height: 375px; opacity: 0.8; } [data-theme=dark] #post-anchor-box{ background: #000; } [data-theme=dark] #article-container anchor{ color: rgb(255, 255, 255); } @media screen and (max-width:768px){ #rightside #post-anchor{ display: none!important; } }
|
后记
因为是文章页才用到的JS,不是全局的,量也不多,就直接写在pug里了,还能避免pjax的适配问题。
已知BUG:选中锚点跨标签的话,可以跳转,但是没法套标签使背景高亮,这就emm有点烦。当选中的文本只包含半个右半边英文括号时,锚点会无法跳转和高亮,原因未知。