我正在设计一个本机浏览器元素,
<audio>
,为此,有必要使用本机浏览器伪元素,例如:
.audio-message audio::-webkit-media-controls-current-time-display {
display: none;
}
隐藏此元素会使总音频持续时间元素显示在前面,并带有“/”。
我希望隐藏这个斜杠,因为它在隐藏剩余时间的上下文中没有任何意义,但我不能将
:first-letter
与本机元素选择器一起使用。
我的问题是,我们如何应用类似的东西:
.audio-message audio::-webkit-media-controls-current-time-display::first-letter {
display: none;
}
该示例不起作用,我尝试了
:is()
,使用 :first-letter
而不是 ::
,并且还更改为悬停并添加 important 来测试问题是否是选择器。
我宁愿使用仅 CSS 的解决方案,我知道它可以以某种方式在 JS 中完成,但是有几个音频元素,这会损害性能。
audio::-webkit-media-controls-current-time-display {
display: none;
}
audio::-webkit-media-controls-current-time-display::first-letter {
/* Doesn't work */
display: none;
}
<audio controls="" src="https://www.w3schools.com/tags/horse.ogg"></audio>
请使用基于 Chrome 的浏览器测试代码片段。
音频播放器在每个浏览器中的显示方式都不同。我们只能通过繁琐的编码来解决每个问题,因此这是创建自定义音频播放器的更好方法,例如:
// scripts.js
document.addEventListener('DOMContentLoaded', function() {
var audio = document.getElementById('audio');
var playPauseButton = document.getElementById('play-pause');
var playIcon = document.getElementById('play-icon');
var pauseIcon = document.getElementById('pause-icon');
var volumeControl = document.getElementById('volume');
var muteButton = document.getElementById('mute');
var speakerIcon = document.getElementById('speaker-icon');
var muteIcon = document.getElementById('mute-icon');
var speedOptions = document.querySelectorAll('.speed-option');
var timeline = document.getElementById('timeline');
var currentTimeDisplay = document.getElementById('current-time');
// Play/Pause functionality
playPauseButton.addEventListener('click', function() {
if (audio.paused) {
audio.play();
playIcon.style.display = 'none';
pauseIcon.style.display = 'block';
} else {
audio.pause();
playIcon.style.display = 'block';
pauseIcon.style.display = 'none';
}
});
// Revert to play icon when audio ends
audio.addEventListener('ended', function() {
playIcon.style.display = 'block';
pauseIcon.style.display = 'none';
});
// Volume control functionality
volumeControl.addEventListener('input', function() {
audio.volume = volumeControl.value;
if (audio.volume === 0) {
speakerIcon.style.display = 'none';
muteIcon.style.display = 'block';
} else {
speakerIcon.style.display = 'block';
muteIcon.style.display = 'none';
}
});
// Mute functionality
muteButton.addEventListener('click', function() {
if (audio.muted) {
audio.muted = false;
speakerIcon.style.display = 'block';
muteIcon.style.display = 'none';
} else {
audio.muted = true;
speakerIcon.style.display = 'none';
muteIcon.style.display = 'block';
}
});
// Playback speed control functionality
speedOptions.forEach(function(option) {
option.addEventListener('click', function() {
audio.playbackRate = this.dataset.speed;
});
});
// Update current time display and timeline
audio.addEventListener('timeupdate', function() {
var currentMinutes = Math.floor(audio.currentTime / 60);
var currentSeconds = Math.floor(audio.currentTime % 60);
if (currentSeconds < 10) {
currentSeconds = '0' + currentSeconds;
}
currentTimeDisplay.textContent = currentMinutes + ':' + currentSeconds;
// Update timeline
var value = (audio.currentTime / audio.duration) * 100;
timeline.value = value;
});
// Seek functionality for timeline
timeline.addEventListener('input', function() {
var time = (timeline.value / 100) * audio.duration;
audio.currentTime = time;
});
});
/* styles.css */
.audio-player {
display: flex;
align-items: center;
background: #f3f3f3;
border-radius: 100px;
padding: 5px;
gap: 10px;
width: 100%;
max-width: 290px;
margin: 0 auto;
}
button {
padding: 10px 10px;
background-color: transparent;
border: none;
border-bottom-right-radius: 20px;
border-top-right-radius: 20px;
font-size: 20px;
line-height: 10px;
z-index: 37;
position: relative;
}
#play-pause {
border-radius: 50px;
}
input[type="range"] {
width: 100px;
}
#timeline {
width: 80px;
}
.volume-control {
display: flex;
align-items: center;
position: relative;
}
.volume-control input[type="range"] {
position: relative;
top: 1px;
right: 50px;
width: 47px;
}
.wrap {
width: 0;
overflow: hidden;
position: absolute;
float: right;
}
.volume-control:hover .wrap {
overflow: visible;
}
#play-icon,
#pause-icon,
#speaker-icon,
#mute-icon {
width: 24px;
height: 24px;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 50px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
}
.dropdown-content button {
color: black;
padding: 8px 12px;
text-decoration: none;
display: block;
background: none;
border: none;
width: 100%;
text-align: left;
font-size: 14px;
}
.dropdown-content button:hover {
background-color: #f1f1f1;
}
.dropdown:hover .dropdown-content {
display: block;
}
.wrap::before {
background-color: #e0e0e0;
content: "";
margin: 0 auto;
position: absolute;
right: -45px;
width: 100px;
height: 43px;
border-radius: 50px;
top: -15px;
border: 5px solid #f3f3f3;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Custom Audio Player</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="audio-player">
<audio id="audio" src="https://www.w3schools.com/tags/horse.ogg"></audio>
<button id="play-pause">
<svg id="play-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8 5v14l11-7L8 5z" fill="currentColor"/>
</svg>
<svg id="pause-icon" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" style="display: none;">
<path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z" fill="currentColor"/>
</svg>
</button>
<span id="current-time">0:00</span>
<input type="range" id="timeline" value="0" max="100">
<div class="volume-control">
<button id="mute">
<svg id="speaker-icon" width="24px" height="24px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16 9C16.5 9.5 17 10.5 17 12C17 13.5 16.5 14.5 16 15M19 6C20.5 7.5 21 10 21 12C21 14 20.5 16.5 19 18M13 3L7 8H5C3.89543 8 3 8.89543 3 10V14C3 15.1046 3.89543 16 5 16H7L13 21V3Z" stroke="#000000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<svg id="mute-icon" width="24px" height="24px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" style="display: none;">
<path d="M10.6 5L13 3V8M3 3L21 21M13 18V21L7 16H5C3.89543 16 3 15.1046 3 14V10C3 9.63571 3.09739 9.29417 3.26756 9" stroke="#000000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</button>
<span class="wrap"><input type="range" id="volume" min="0" max="1" step="0.01" value="1"></span>
</div>
<div class="dropdown">
<button id="speed-menu">⋮</button>
<div class="dropdown-content">
<button class="speed-option" data-speed="0.5">0.5x</button>
<button class="speed-option" data-speed="1">1x</button>
<button class="speed-option" data-speed="1.5">1.5x</button>
<button class="speed-option" data-speed="2">2x</button>
</div>
</div>
</div>
<script src="scripts.js"></script>
</body>
</html>