Skip to content

Commit a8aa783

Browse files
authored
fix: use Ref instead of querrySelector follow up #1136 (#1140)
1 parent 6816986 commit a8aa783

File tree

1 file changed

+62
-42
lines changed

1 file changed

+62
-42
lines changed

src/components/audioPlayer/index.js

Lines changed: 62 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,80 @@
11
import "./style.scss";
2+
import Ref from "html-tag-js/ref";
23

34
export default class AudioPlayer {
45
constructor(container) {
56
this.container = container;
67
this.audio = new Audio();
78
this.isPlaying = false;
9+
this.elements = {
10+
playBtn: new Ref(),
11+
playIcon: new Ref(),
12+
timeline: new Ref(),
13+
progress: new Ref(),
14+
progressHandle: new Ref(),
15+
timeDisplay: new Ref(),
16+
duration: new Ref(),
17+
volumeBtn: new Ref(),
18+
};
819
this.initializeUI();
920
this.initializeEvents();
1021
this.cleanup = this.cleanup.bind(this);
1122
}
1223

1324
initializeUI() {
14-
const auidoPlayer = (
25+
const audioPlayer = (
1526
<div className="audio-player">
16-
<button className="play-btn" ariaLabel="Play/Pause">
17-
<span className="icon play_arrow"></span>
27+
<button
28+
ref={this.elements.playBtn}
29+
className="play-btn"
30+
ariaLabel="Play/Pause"
31+
>
32+
<span ref={this.elements.playIcon} className="icon play_arrow"></span>
1833
</button>
1934

20-
<div className="timeline">
21-
<div className="progress"></div>
22-
<div className="progress-handle"></div>
35+
<div ref={this.elements.timeline} className="timeline">
36+
<div ref={this.elements.progress} className="progress"></div>
37+
<div
38+
ref={this.elements.progressHandle}
39+
className="progress-handle"
40+
></div>
2341
</div>
2442

25-
<div className="time">0:00</div>
43+
<div ref={this.elements.timeDisplay} className="time">
44+
0:00
45+
</div>
2646

2747
<div className="volume-control">
28-
<button className="volume-btn" ariaLabel="Volume"></button>
48+
<button
49+
ref={this.elements.volumeBtn}
50+
className="volume-btn"
51+
ariaLabel="Volume"
52+
></button>
2953
</div>
3054
</div>
3155
);
3256

33-
this.container.appendChild(auidoPlayer);
57+
this.container.appendChild(audioPlayer);
3458

35-
this.elements = {
36-
playBtn: this.container.querySelector(".play-btn"),
37-
playIcon: this.container.querySelector(".play-btn .icon"),
38-
timeline: this.container.querySelector(".timeline"),
39-
progress: this.container.querySelector(".progress"),
40-
progressHandle: this.container.querySelector(".progress-handle"),
41-
timeDisplay: this.container.querySelector(".time"),
42-
duration: this.container.querySelector(".duration"),
43-
volumeBtn: this.container.querySelector(".volume-btn"),
44-
};
45-
this.elements.volumeBtn.innerHTML = `<svg viewBox="0 0 24 24">
46-
<path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z"/>
47-
</svg>`;
59+
this.elements.volumeBtn.el.innerHTML = `<svg viewBox="0 0 24 24">
60+
<path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z"/>
61+
</svg>`;
4862
}
4963

5064
initializeEvents() {
5165
// Play/Pause
52-
this.elements.playBtn.addEventListener("click", () => this.togglePlay());
66+
this.elements.playBtn.el.addEventListener("click", () => this.togglePlay());
5367

5468
// Timeline
55-
this.elements.timeline.addEventListener("click", (e) => this.seek(e));
56-
this.elements.timeline.addEventListener("touchstart", (e) => this.seek(e));
69+
this.elements.timeline.el.addEventListener("click", (e) => this.seek(e));
70+
this.elements.timeline.el.addEventListener("touchstart", (e) =>
71+
this.seek(e),
72+
);
5773

5874
// Volume
59-
this.elements.volumeBtn.addEventListener("click", () => this.toggleMute());
75+
this.elements.volumeBtn.el.addEventListener("click", () =>
76+
this.toggleMute(),
77+
);
6078

6179
// Audio events
6280
this.audio.addEventListener("timeupdate", () => this.updateProgress());
@@ -66,18 +84,18 @@ export default class AudioPlayer {
6684
togglePlay() {
6785
if (this.isPlaying) {
6886
this.audio.pause();
69-
this.elements.playIcon.classList.remove("pause");
70-
this.elements.playIcon.classList.add("play_arrow");
87+
this.elements.playIcon.el.classList.remove("pause");
88+
this.elements.playIcon.el.classList.add("play_arrow");
7189
} else {
7290
this.audio.play();
73-
this.elements.playIcon.classList.remove("play_arrow");
74-
this.elements.playIcon.classList.add("pause");
91+
this.elements.playIcon.el.classList.remove("play_arrow");
92+
this.elements.playIcon.el.classList.add("pause");
7593
}
7694
this.isPlaying = !this.isPlaying;
7795
}
7896

7997
seek(e) {
80-
const rect = this.elements.timeline.getBoundingClientRect();
98+
const rect = this.elements.timeline.el.getBoundingClientRect();
8199
const pos =
82100
(e.type.includes("touch") ? e.touches[0].clientX : e.clientX) - rect.left;
83101
const percentage = pos / rect.width;
@@ -86,9 +104,9 @@ export default class AudioPlayer {
86104

87105
updateProgress() {
88106
const percentage = (this.audio.currentTime / this.audio.duration) * 100;
89-
this.elements.progress.style.width = `${percentage}%`;
90-
this.elements.progressHandle.style.left = `${percentage}%`;
91-
this.elements.timeDisplay.textContent = this.formatTime(
107+
this.elements.progress.el.style.width = `${percentage}%`;
108+
this.elements.progressHandle.el.style.left = `${percentage}%`;
109+
this.elements.timeDisplay.el.textContent = this.formatTime(
92110
this.audio.currentTime,
93111
);
94112
}
@@ -102,18 +120,18 @@ export default class AudioPlayer {
102120
toggleMute() {
103121
this.audio.muted = !this.audio.muted;
104122
if (this.audio.muted) {
105-
this.elements.volumeBtn.innerHTML =
123+
this.elements.volumeBtn.el.innerHTML =
106124
'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M11 4.702a.705.705 0 0 0-1.203-.498L6.413 7.587A1.4 1.4 0 0 1 5.416 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.416a1.4 1.4 0 0 1 .997.413l3.383 3.384A.705.705 0 0 0 11 19.298z"/></svg>';
107125
} else {
108-
this.elements.volumeBtn.innerHTML =
126+
this.elements.volumeBtn.el.innerHTML =
109127
'<svg viewBox="0 0 24 24"><path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z"/></svg>';
110128
}
111129
}
112130

113131
audioEnded() {
114132
this.isPlaying = false;
115-
this.elements.playIcon.classList.remove("pause");
116-
this.elements.playIcon.classList.add("play_arrow");
133+
this.elements.playIcon.el.classList.remove("pause");
134+
this.elements.playIcon.el.classList.add("play_arrow");
117135
}
118136

119137
loadTrack(src) {
@@ -126,12 +144,14 @@ export default class AudioPlayer {
126144
this.audio.currentTime = 0;
127145
this.isPlaying = false;
128146

129-
this.elements.playBtn.removeEventListener("click", () => this.togglePlay());
130-
this.elements.timeline.removeEventListener("click", (e) => this.seek(e));
131-
this.elements.timeline.removeEventListener("touchstart", (e) =>
147+
this.elements.playBtn.el.removeEventListener("click", () =>
148+
this.togglePlay(),
149+
);
150+
this.elements.timeline.el.removeEventListener("click", (e) => this.seek(e));
151+
this.elements.timeline.el.removeEventListener("touchstart", (e) =>
132152
this.seek(e),
133153
);
134-
this.elements.volumeBtn.removeEventListener("click", () =>
154+
this.elements.volumeBtn.el.removeEventListener("click", () =>
135155
this.toggleMute(),
136156
);
137157
this.audio.removeEventListener("timeupdate", () => this.updateProgress());

0 commit comments

Comments
 (0)