博客建立起来也有一段时间了,在使用过程中感觉原有音乐功能还有待完善。一是音乐胶囊在桌面端页面无滚动条和移动端竖屏状态下无法唤出,执行相关操作要返其它页面或横屏使用;二是音乐页面只支持QQ、网易云等音乐平台,不支持本地音乐,因版权问题较多歌曲无法播放。为进一步提升使用体验,本人针对痛点堵点进行了能力范围内的一些细微改动并加以记录,希望对来客有所帮助。以下是第一篇:右键菜单添加音乐控制功能。实际效果欢迎呼出右键菜单体验。
主题魔改风险高,没有备份全报销。劝君三思再保存,莫等黄字泪汪汪。
本教程基于Solitude V3.0.20,作者技术能力有限 ,其他主题或版本请自行研究迁移。
改动简概
实现过程
定义功能逻辑
定位到source/js/main.js,在文件最后一行添加以下内容,引入音乐信息获取与按钮功能相关功能逻辑。
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 89 90 91 92
| function updateRightmenuMusicToggleIcon(forceState) { const playSvg = document.getElementById('rightmenu-music-svg-play'); const pauseSvg = document.getElementById('rightmenu-music-svg-pause'); let isPlaying = forceState; if (typeof isPlaying === 'undefined') { const meting = document.querySelector('meting-js'); isPlaying = !!(meting && meting.aplayer && meting.aplayer.audio && !meting.aplayer.audio.paused); } if (playSvg && pauseSvg) { playSvg.style.display = isPlaying ? 'none' : 'block'; pauseSvg.style.display = isPlaying ? 'block' : 'none'; } } if (typeof sco !== 'undefined') { const oldMusicToggle = sco.musicToggle; sco.musicToggle = function() { if (typeof oldMusicToggle === 'function') oldMusicToggle.apply(this, arguments); updateRightmenuMusicToggleIcon(); }; }
function updateRightmenuMusicTitleAndIcon(retry = 0) { const meting = document.querySelector('meting-js'); const titleEl = document.getElementById('rightmenu-music-title'); const artistEl = document.getElementById('rightmenu-music-artist'); let displayTitle = ''; let displayArtist = '';
if (meting && meting.aplayer && meting.aplayer.list && meting.aplayer.list.audios.length > 0) { const index = meting.aplayer.list.index; let current = meting.aplayer.list.audios[index]; if (!current || !current.name) { current = meting.aplayer.list.audios[0]; } displayTitle = current.name || ''; displayArtist = current.artist || ''; } else if (retry < 3) { setTimeout(() => updateRightmenuMusicTitleAndIcon(retry + 1), 150); return; } else { displayTitle = ''; displayArtist = ''; }
if (displayTitle && titleEl) titleEl.textContent = displayTitle; if (displayArtist && artistEl) artistEl.textContent = displayArtist;
if (meting && meting.aplayer) { updateRightmenuMusicToggleIcon(!meting.aplayer.audio.paused); } }
function bindRightmenuMusicEvents() { function tryBind() { const meting = document.querySelector('meting-js'); if (meting && meting.aplayer) { meting.aplayer.on('listswitch', () => updateRightmenuMusicTitleAndIcon()); meting.aplayer.on('play', () => updateRightmenuMusicToggleIcon(true)); meting.aplayer.on('pause', () => updateRightmenuMusicToggleIcon(false)); updateRightmenuMusicTitleAndIcon(); return true; } return false; }
if (!tryBind()) { const observer = new MutationObserver(() => { if (tryBind()) observer.disconnect(); }); observer.observe(document.body, { childList: true, subtree: true }); } }
document.addEventListener('DOMContentLoaded', bindRightmenuMusicEvents); document.getElementById('rightmenu-music-capsule')?.addEventListener('click', updateRightmenuMusicTitleAndIcon); document.addEventListener('contextmenu', () => updateRightmenuMusicTitleAndIcon());
const rightmenuMenus = document.getElementById('rightmenu-music-capsule'); if (rightmenuMenus) { rightmenuMenus.addEventListener('transitionend', () => { if (window.innerWidth <= 768 && rightmenuMenus.classList.contains('open')) { updateRightmenuMusicTitleAndIcon(); } }); }
|
搭建菜单模组
定位到layout/includes/rightmenu.pug,在div#rightmenu-mask前一行添加以下内容。
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
| div.rightMenu-group.rightMenuMusic div.rightMenu-item span.rightmenu-music-info span#rightmenu-music-title 歌曲名 span#rightmenu-music-artist 歌手名 div.rightMenu-item div.rightmenu-music-btns、 button.menu-child-btn(type="button" onclick="sco.musicSkipBack(); updateRightmenuMusicTitleAndIcon();" title="上一曲") svg(xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24") g(fill="none") path(d="m12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.018-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z") path(fill="currentColor" d="m20.43 5.865l.078.699l.072.767l.036.448l.051.75l.03.55l.038.894l.019.641l.012.675l.004.707l-.004.707l-.012.675l-.019.641l-.024.606l-.028.569l-.05.78l-.035.47l-.09.986l-.079.698a1.332 1.332 0 0 1-1.844 1.065l-.49-.213l-.846-.386l-.62-.298l-.458-.226l-.748-.381l-.538-.283l-.566-.306l-.594-.329l-.619-.353l-.615-.36l-.582-.349l-.809-.5l-.73-.47l-.443-.292l-.406-.274l-.54-.373l-.587-.42l-.43-.319a1.332 1.332 0 0 1 .002-2.13l.325-.242l.422-.306l.517-.363l.607-.414l.694-.458l.51-.327l.546-.342l.581-.355l.617-.366l.32-.186q.312-.18.613-.349l.588-.326l.563-.304l.793-.414l.725-.365l.442-.215l.597-.283l.802-.362l.355-.154a1.332 1.332 0 0 1 1.846 1.065ZM6 5a1 1 0 0 1 .993.883L7 6v12a1 1 0 0 1-.883.993L6 19H5a1 1 0 0 1-.993-.883L4 18V6a1 1 0 0 1 .883-.993L5 5z") button.menu-child-btn(type="button" id="rightmenu-music-toggle" onclick="sco.musicToggle()" title="播放/暂停") svg#rightmenu-music-svg-play(xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" style="display:block") g(fill="none" fill-rule="evenodd") path(d="m12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.018-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z") path(fill="currentColor" d="M5.669 4.76a1.47 1.47 0 0 1 2.04-1.177c1.062.454 3.442 1.533 6.462 3.276c3.021 1.744 5.146 3.267 6.069 3.958c.788.591.79 1.763.001 2.356c-.914.687-3.013 2.19-6.07 3.956c-3.06 1.766-5.412 2.832-6.464 3.28c-.906.387-1.92-.2-2.038-1.177c-.138-1.142-.396-3.735-.396-7.237c0-3.5.257-6.092.396-7.235") svg#rightmenu-music-svg-pause(xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24" style="display:none") g(fill="none") path(d="m12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.018-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z") path(fill="currentColor" d="M7 5a1 1 0 0 1 1 1v12a1 1 0 0 1-2 0V6a1 1 0 0 1 1-1m10 0a1 1 0 0 1 1 1v12a1 1 0 0 1-2 0V6a1 1 0 0 1 1-1") button.menu-child-btn(type="button" onclick="sco.musicSkipForward(); updateRightmenuMusicTitleAndIcon();" title="下一曲") svg(xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 24 24") g(fill="none") path(d="m12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.018-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z") path(fill="currentColor" d="M3.569 5.865A1.332 1.332 0 0 1 5.415 4.8l.646.283l.511.233l.597.283l.676.331l.49.249l.793.414l.564.304l.588.326l.613.349l.633.37l.599.361l.564.349l.778.496l.694.458l.607.414l.517.363l.541.394l.206.154c.71.535.71 1.594.001 2.13l-.43.319l-.273.198l-.664.465l-.595.404l-.443.292l-.73.47l-.81.5l-.581.35l-.615.36l-.62.352l-.593.33l-.566.305l-.538.283l-.748.381l-.673.331l-.773.364l-.744.332l-.224.096a1.332 1.332 0 0 1-1.844-1.065l-.08-.698l-.071-.767l-.053-.689l-.05-.78l-.028-.57l-.024-.605l-.019-.64l-.015-1.026v-.715l.015-1.024l.03-.948l.026-.587l.03-.55l.052-.75l.054-.657l.07-.722zM19 5a1 1 0 0 1 .993.883L20 6v12a1 1 0 0 1-.883.993L19 19h-1a1 1 0 0 1-.993-.883L17 18V6a1 1 0 0 1 .883-.993L18 5z")
|
如果不喜欢Svg图标,也可以换成Font Awesome图标,我只是单纯没用过想试一下。
引入相关样式
定位到blog/source/custom.css或solitude/source/css/_layout/rightmenu.styl,添加以下内容。如无custom.css,新建或者使用自己原有自定义Css文件亦可;如需在styl中引入,请自行修改格式。
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 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
| .rightMenu-group.rightMenuMusic { margin-top: 0.5rem; padding: 0.35rem 0.3rem; border-top: 1px dashed var(--efu-theme-op); }
.rightMenu-group.rightMenuMusic .music-capsule-block { display: flex; flex-direction: column; align-items: center; width: 100%; background: var(--efu-card-bg); border-radius: 8px; border: var(--style-border-always); margin: 0; padding: 8px 0 4px 0; }
.rightMenu-group.rightMenuMusic .music-title-ellipsis { display: block; text-align: center; margin: 0 0 8px 0; font-size: 1em; color: var(--efu-fontcolor); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; width: 100%; padding: 0 8px; box-sizing: border-box; }
.rightMenu-group.rightMenuMusic .music-capsule-btns { display: flex; flex-direction: row; justify-content: center; align-items: center; width: 100%; gap: 20px; margin: 8px 0 4px 0; }
.rightMenu-group.rightMenuMusic .rightmenu-music-info { display: flex; flex-direction: column; align-items: center; gap: 2px; background: none !important; color: inherit !important; pointer-events: auto; }
.rightMenu-group.rightMenuMusic .rightmenu-music-info span#rightmenu-music-title { font-size: 1em; color: var(--efu-fontcolor); font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; width: 100%; text-align: center; }
.rightMenu-group.rightMenuMusic .rightmenu-music-info span#rightmenu-music-artist { font-size: 0.92em; color: var(--efu-gray); margin: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; width: 100%; text-align: center; }
.rightMenu-group.rightMenuMusic .rightmenu-music-btns { display: flex; flex-direction: row; justify-content: center; align-items: center; width: 100%; gap: 16px; background: none; }
.rightMenu-group.rightMenuMusic .rightmenu-music-btns .menu-child-btn { width: 32px; height: 32px; font-size: 1.1em; color: var(--efu-fontcolor); background: none; border: none; border-radius: 8px; margin: 0; cursor: pointer; transition: background 0.2s; }
.rightMenu-group.rightMenuMusic .rightmenu-music-btns .menu-child-btn:hover, .rightMenu-group.rightMenuMusic .rightmenu-music-btns .menu-child-btn:active { background: var(--efu-gray-op); }
.rightMenuMusic .rightMenu-item .rightmenu-music-info, .rightMenuMusic .rightMenu-item .rightmenu-music-info * { color: var(--efu-fontcolor) !important; background: none !important; box-shadow: none !important; display: block !important; height: auto !important; visibility: visible !important; opacity: 1 !important; }
.rightMenuMusic .rightmenu-music-info #rightmenu-music-artist { color: var(--efu-gray) !important; }
.rightMenuMusic .rightmenu-music-info { display: flex; flex-direction: column; align-items: center; gap: 0 !important; margin: 0 !important; padding: 0 !important; } .rightMenuMusic .rightmenu-music-info span#rightmenu-music-title, .rightMenuMusic .rightmenu-music-info span#rightmenu-music-artist { margin: 0 !important; padding: 0 !important; line-height: 1.1 !important; display: block; }
.rightMenuMusic .rightmenu-music-btns { display: flex; flex-direction: row; justify-content: center; align-items: center; width: 100%; gap: 16px; } .rightMenuMusic .menu-child-btn { display: flex; align-items: center; justify-content: center; width: 32px; height: 32px; font-size: 1.1em; color: var(--efu-fontcolor); background: none; border: none; border-radius: 8px; margin: 0; padding: 0; cursor: pointer; transition: background 0.2s; } .rightMenuMusic .menu-child-btn svg { width: 1.5em; height: 1.5em; min-width: 24px; min-height: 24px; display: block; margin: auto; }
.rightMenuMusic .rightMenu-item:hover, .rightMenuMusic .rightMenu-item:active, .rightMenuMusic .rightMenu-item:hover .rightmenu-music-info, .rightMenuMusic .rightMenu-item:active .rightmenu-music-info, .rightMenuMusic .rightMenu-item:hover .rightmenu-music-btns, .rightMenuMusic .rightMenu-item:active .rightmenu-music-btns { background: none !important; box-shadow: none !important; } .rightMenuMusic .menu-child-btn:hover, .rightMenuMusic .menu-child-btn:active { background: var(--efu-main) !important; color: #fff !important; }
|
结语
改动全程在Cursor+Claude-4-Sonnet下进行,如借鉴过程中发现存在问题或有待改进的地方,欢迎在评论区留言,我看到会第一时间回复。