如何通过CSS实现交互性听觉表现?相关技术问询
前端技术分工共识
- HTML负责structure(结构)
- CSS负责presentation(表现)
- JS负责behaviour(行为)
注: 我们可探讨“响应用户交互的表现”是否等同于“行为”,这是一种观点。但网页上大量通过
:hover、:focus、:focus-within等伪类实现的纯CSS交互视觉效果,说明另一种观点被广泛接受:CSS是处理“交互性表现”的合法技术。
技术问询
既然CSS可实现多种交互视觉表现,是否可用于处理交互性听觉表现?
- 是否曾有尝试在CSS中引入aural presentation(听觉表现)?
- 是否有在CSS中引入听觉表现的提案?
是否存在官方方案(即使未被浏览器实现),可通过以下虚构CSS属性实现如下Demo的效果:
audioaudio-durationaudio-play
示例Demo
请忽略下方JavaScript代码,假设如下CSS样式可直接生效:
.square:unhover { audio: url(//cdn.freesound.org/previews/628/628357_1486333-lq.mp3); audio-duration: 1.776s; audio-play: 2; }
实现逻辑(JavaScript)
// BUILD STYLESHEET ARRAY const stylesheet = document.head.querySelector('style'); let stylesheetText = stylesheet.textContent.replace(/\s/g, ''); let stylesheetArray = stylesheetText.split('}'); stylesheetArray.pop(); // BUILD SELECTORS ARRAY let selectorsArray = []; for (let i = 0; i < stylesheetArray.length; i++) { selectorsArray[i] = { selector: stylesheetArray[i].split('{')[0], styles: {} }; let selectorRules = stylesheetArray[i].split('{')[1].split(';') selectorRules.pop(); for (let j = 0; j < selectorRules.length; j++) { selectorsArray[i].styles[selectorRules[j].split(':')[0]] = selectorRules[j].split(':')[1]; } } // BUILD TARGET QUERIES ARRAY let targetQueriesArray = []; for (let i = 0; i < selectorsArray.length; i++) { if ((/:hover|:unhover/).test(selectorsArray[i].selector)) { if (Object.keys(selectorsArray[i].styles).includes('audio')) { let targetQuery = selectorsArray[i]; switch (true) { case (targetQuery.selector.includes(':hover')): targetQuery.event = 'mouseover'; break; case (targetQuery.selector.includes(':unhover')): targetQuery.event = 'mouseout'; break; } targetQueriesArray.push(targetQuery); } } } // DECLARE playAudioViaCSS FUNCTION const playAudioViaCSS = (audioURL, audioDuration, audioPlays) => { let soundEffectViaCSS = new Audio(audioURL); soundEffectViaCSS.loop = true; soundEffectViaCSS.play(); setTimeout(() => soundEffectViaCSS.loop = false, (audioDuration * audioPlays)); } // ATTACH AUDIO EVENTS TO TARGET ELEMENTS for (let i = 0; i < targetQueriesArray.length; i++) { let targetAudio = targetQueriesArray[i].styles.audio.replace('url(', '').replace(')', ''); let targetAudioDuration = (targetQueriesArray[i].styles['audio-duration'].replace('s', '') * 1000) || 1000; let targetAudioPlays = targetQueriesArray[i].styles['audio-play'] || 1; let targetEvent = targetQueriesArray[i].event; let targetQuery = targetQueriesArray[i].selector.replace(/:hover|:unhover/g, ''); let targetElements = [...document.querySelectorAll(targetQuery)]; targetElements.forEach((element) => element.addEventListener(targetEvent, () => playAudioViaCSS(targetAudio, targetAudioDuration, targetAudioPlays), false)); };
样式定义(CSS)
:root { display: flex; justify-content: center; align-items: center; height: 100%; } .square { width: 100px; height: 100px; line-height: 100px; text-align: center; color: rgb(255, 255, 255); background-color: rgb(255, 0, 0); border-radius: 50%; cursor: pointer; transform: scale(1); transition: all 0.9s ease-out; } .square:hover { border-radius: 0; transform: scale(1.5); audio: url(//cdn.freesound.org/previews/354/354062_1490240-lq.mp3); audio-duration: 2.304s; audio-play: 3; } .square:unhover { audio: url(//cdn.freesound.org/previews/628/628357_1486333-lq.mp3); audio-duration: 1.776s; audio-play: 2; }
页面结构(HTML)
<div class="square"> Hover me </div>
内容的提问来源于stack exchange,提问作者Rounin
相关产品推荐
相关产品推荐

