Apparently, IE9 and above supports Array.forEach but not for NodeList, which querySelector returns. I tried Array.from() to no avail as it requires ES6 or use ES6-shim.
Object doesnât support property or method âforEachâ
In that case youâd have to move away from using the querySelector()
method, and use a different (older) technique. At this point though Iâd suggest you not do that and continue on with what Paul has shown you, as itâs a more modern way of achieving what you want - just use another browser instead and forget about IE of any version, especially as youâve said here, that you âdonât really use itâ - itâs virtually dead anywayâŚ
Firefox is my main browser.
Hereâs the pre-ES6 equivalent to Array.from()
:
var playButtonArray = Array.prototype.slice.call(playbuttons)
In the same way, you can call any array method on a node list:
Array.prototype.forEach.call(playButtons, function (el) {
// etc...
})
I think that was a quote from SO that @asasass posted there, not necessarily what heâs tried himself.
I almost got it.
My attempt of replicating:
<style>
.playButton2 {
margin-top: 8px;
width: 266px;
height: 266px;
cursor: pointer;
background-image: linear-gradient( to right, transparent, transparent 83px, #0059dd 83px, #0059dd 86px, #000000 86px, #000000 174px, #0059dd 174px, #0059dd 177px, transparent 177px, transparent 260px), url("http://via.placeholder.com/260x260");
background-repeat: no-repeat;
box-sizing: border-box;
border: 3px solid #0059dd;
}
.playButton2.playing{
border: 3px solid #e77d19;
background-image: linear-gradient( to right, transparent, transparent 83px, #e77d19 83px, #e77d19 86px, transparent 86px, transparent 174px, #e77d19 174px, #e77d19 177px, transparent 177px, transparent 260px), url("http://via.placeholder.com/260x260");
background-color: transparent;
background-repeat: no-repeat;
}
.initial {
stroke: #e77d19;
stroke-width: 3px;
color: black;
}
.pause {
stroke: #e77d19;
stroke-width: 3px;
color: transparent;
}
.play {
stroke: #e77d19;
stroke-width: 3px;
color: transparent;
}
.hide {
display: none;
}
</style>
<div id="playButton2">
<svg class="initial" style="margin:76px 85px;" width="90" height="108" viewbox="0 -10 85 120">
<path fill="currentColor" style="stroke: #e77d19; stroke-width:3px;color:black; " d="M81 44.6c5 3 5 7.8 0 10.8L9 98.7c-5 3-9 .7-9-5V6.3c0-5.7 4-8 9-5l72 43.3z"></path>
</svg>
<svg class="pause" style="display: none;margin:76px 85px;" width="90" height="108" viewbox="-13 -10 85 120">
<path fill="currentColor" style="stroke: #e77d19; stroke-width:3px;color:transparent;" d="M0 8c0-5 3-8 8-8s9 3 9 8v84c0 5-4 8-9 8s-8-3-8-8V8zm43 0c0-5 3-8 8-8s8 3 8 8v84c0 5-3 8-8 8s-8-3-8-8V8z"></path>
</svg>
<svg class="speaker" style="display: none;margin:94px 100px;" width="60" height="72" viewbox="0 0 16 14">
<path d="M12.945.38l-.652.762c1.577 1.462 2.57 3.544 2.57 5.858 0 2.314-.994 4.396-2.57 5.858l.65.763c1.79-1.644 2.92-3.997 2.92-6.62S14.735 2.024 12.945.38zm-2.272 2.66l-.65.762c.826.815 1.34 1.947 1.34 3.198 0 1.25-.515 2.382-1.342 3.2l.652.762c1.04-1 1.69-2.404 1.69-3.96 0-1.558-.65-2.963-1.69-3.963zM0 4v6h2.804L8 13V1L2.804 4H0zm7-1.268v8.536L3.072 9H1V5h2.072L7 2.732z"
fill="#1ed760 " fill-rule="evenodd"></path>
</svg>
<svg class="play" style="display: none;margin:76px 85px;" width="90" height="108" viewbox="0 -10 85 120">
<path fill="currentColor" style="stroke: #e77d19; stroke-width:3px;color:transparent; " d="M81 44.6c5 3 5 7.8 0 10.8L9 98.7c-5 3-9 .7-9-5V6.3c0-5.7 4-8 9-5l72 43.3z"></path>
</svg>
</div>
<audio id="player2" preload="none" style="display:none;">
<source src='' type='audio/mpeg'></source>
</audio>
<script>
(function iife() {
"use strict";
function playButtonClickHandler() {
var button = document.querySelector('playButton2');
var player = document.querySelector('player2');
document.querySelector('#playButton2 .initial').style.display='none';
player.volume=1.0; if (player.paused) {
button.classList.add("playing");
document.querySelector('#playButton2 .pause').style.display='inline-block';
document.querySelector('#playButton2 .play').style.display='none';
player.play();
} else {
document.querySelector('#playButton2 .pause').style.display='none';
document.querySelector('#playButton2 .play').style.display='inline-block';
player.pause();
}" onmouseover="
var player = document.querySelector('player2');
player.isPlaying = function () {
return player.paused === false;
}
if (player.isPlaying()) {
document.querySelector('#playButton2 .speaker').style.display='none';
document.querySelector('#playButton2 .pause').style.display='inline-block';
}" onmouseout="
var player = document.querySelector('player2');
player.isPlaying = function () {
return player.paused === false;
}
if (player.isPlaying()) {
document.querySelector('#playButton2 .pause').style.display='none';
document.querySelector('#playButton2 .speaker').style.display='inline-block';
}
}
var playButton = document.querySelector(".playButton2");
playButton.addEventListener("click", playButtonClickHandler);
}());
</script>
Yes, I was just saying that there are other ways to deal with node lists that work in IE too.
I almost got it:
I wonder if it were to be possible to convert this to javascript. Changing all ids to classes. And readjusting all the styles, like how they were set up before.
<style>
#playButton4 {
display: inline-block;
background-color: #000000;
width: 83px;
border-top: 3px solid #0059dd;
border-bottom: 3px solid #0059dd;
border-left: 3px solid #0059dd;
cursor: pointer;
fill: #aaff00;
}
#playButton5 {
display: inline-block;
background-color: #000000;
width: 88px;
border-left: 3px solid #0059dd;
border-right: 3px solid #0059dd;
border-top: 3px solid #0059dd;
border-bottom: 3px solid #0059dd;
fill: #ffaa00;
cursor: pointer;
}
#playButton6 {
display: inline-block;
background-color: #000000;
width: 83px;
border-right: 3px solid #0059dd;
border-top: 3px solid #0059dd;
border-bottom: 3px solid #0059dd;
cursor: pointer;
fill: #ff00aa;
}
.playButtons {
white-space: nowrap;
font-size: 0;
}
</style>
<div class="playButtons">
<div id="playButton4" onclick="
var button = document.getElementById('playButton4');
var player = document.getElementById('player4');
player.volume=1.0; if (player.paused) {
document.querySelector('#playButton4 .pause').style.display='inline-block';
document.querySelector('#playButton4 .play').style.display='none';
player.play();
} else {
document.querySelector('#playButton4 .pause').style.display='none';
document.querySelector('#playButton4 .play').style.display='inline-block';
player.pause();
}">
<svg class="play" style="margin:15px 36px;" width="12" height="14" viewbox="0 0 85 100">
<path d="M81 44.6c5 3 5 7.8 0 10.8L9 98.7c-5 3-9 .7-9-5V6.3c0-5.7 4-8 9-5l72 43.3z"></path>
</svg>
<svg class="pause" style="display: none;margin:15px 37px;" width="10" height="14" viewbox="0 0 60 100">
<path d="M0 8c0-5 3-8 8-8s9 3 9 8v84c0 5-4 8-9 8s-8-3-8-8V8zm43 0c0-5 3-8 8-8s8 3 8 8v84c0 5-3 8-8 8s-8-3-8-8V8z"></path>
</svg>
</div>
<audio id="player4" preload="none" style="display:none;">
<source src='http://hi5.1980s.fm/;' type='audio/mpeg'>
</audio>
<div id="playButton5" onclick="
var button = document.getElementById('playButton5');
var player = document.getElementById('player5');
player.volume=1.0; if (player.paused) {
document.querySelector('#playButton5 .pause').style.display='inline-block';
document.querySelector('#playButton5 .play').style.display='none';
player.play();
} else {
document.querySelector('#playButton5 .pause').style.display='none';
document.querySelector('#playButton5 .play').style.display='inline-block';
player.pause();
}">
<svg class="play" style="margin:15px 39px;" width="12" height="14" viewbox="0 0 85 100">
<path d="M81 44.6c5 3 5 7.8 0 10.8L9 98.7c-5 3-9 .7-9-5V6.3c0-5.7 4-8 9-5l72 43.3z"></path>
</svg>
<svg class="pause" style="display: none;margin:15px 40px;" width="10" height="14" viewbox="0 0 60 100">
<path d="M0 8c0-5 3-8 8-8s9 3 9 8v84c0 5-4 8-9 8s-8-3-8-8V8zm43 0c0-5 3-8 8-8s8 3 8 8v84c0 5-3 8-8 8s-8-3-8-8V8z"></path>
</svg>
</div>
<audio id="player5" preload="none" style="display:none;">
<source src='http://hi5.1980s.fm/;' type='audio/mpeg'>
</audio>
<div id="playButton6" onclick="
var button = document.getElementById('playButton6');
var player = document.getElementById('player6');
player.volume=1.0; if (player.paused) {
document.querySelector('#playButton6 .pause').style.display='inline-block';
document.querySelector('#playButton6 .play').style.display='none';
player.play();
} else {
document.querySelector('#playButton6 .pause').style.display='none';
document.querySelector('#playButton6 .play').style.display='inline-block';
player.pause();
}">
<svg class="play" style="margin:15px 36px;" width="12" height="14" viewbox="0 0 85 100">
<path d="M81 44.6c5 3 5 7.8 0 10.8L9 98.7c-5 3-9 .7-9-5V6.3c0-5.7 4-8 9-5l72 43.3z"></path>
</svg>
<svg class="pause" style="display: none;margin:15px 37px;" width="10" height="14" viewbox="0 0 60 100">
<path d="M0 8c0-5 3-8 8-8s9 3 9 8v84c0 5-4 8-9 8s-8-3-8-8V8zm43 0c0-5 3-8 8-8s8 3 8 8v84c0 5-3 8-8 8s-8-3-8-8V8z"></path>
</svg>
</div>
<audio id="player6" preload="none" style="display:none;">
<source src='http://hi5.1980s.fm/;' type='audio/mpeg'>
</audio>
My attempt so far. A long, slow process.
<style>
#playButton4 {
display: inline-block;
background-color: #000000;
width: 83px;
border-top: 3px solid #0059dd;
border-bottom: 3px solid #0059dd;
border-left: 3px solid #0059dd;
cursor: pointer;
fill: #aaff00;
}
#playButton5 {
display: inline-block;
background-color: #000000;
width: 88px;
border-left: 3px solid #0059dd;
border-right: 3px solid #0059dd;
border-top: 3px solid #0059dd;
border-bottom: 3px solid #0059dd;
fill: #ffaa00;
cursor: pointer;
}
#playButton6 {
display: inline-block;
background-color: #000000;
width: 83px;
border-right: 3px solid #0059dd;
border-top: 3px solid #0059dd;
border-bottom: 3px solid #0059dd;
cursor: pointer;
fill: #ff00aa;
}
.playButtons {
white-space: nowrap;
font-size: 0;
}
</style>
<div class="playButtons">
<div id="playButton4" onclick="">
<svg class="play" style="margin:15px 36px;" width="12" height="14" viewbox="0 0 85 100">
<path d="M81 44.6c5 3 5 7.8 0 10.8L9 98.7c-5 3-9 .7-9-5V6.3c0-5.7 4-8 9-5l72 43.3z"></path>
</svg>
<svg class="pause" style="display: none;margin:15px 37px;" width="10" height="14" viewbox="0 0 60 100">
<path d="M0 8c0-5 3-8 8-8s9 3 9 8v84c0 5-4 8-9 8s-8-3-8-8V8zm43 0c0-5 3-8 8-8s8 3 8 8v84c0 5-3 8-8 8s-8-3-8-8V8z"></path>
</svg>
</div>
<audio id="player4" preload="none" style="display:none;">
<source src='http://hi5.1980s.fm/' type='audio/mpeg'>
</audio>
<div id="playButton5" onclick="">
<svg class="play" style="margin:15px 39px;" width="12" height="14" viewbox="0 0 85 100">
<path d="M81 44.6c5 3 5 7.8 0 10.8L9 98.7c-5 3-9 .7-9-5V6.3c0-5.7 4-8 9-5l72 43.3z"></path>
</svg>
<svg class="pause" style="display: none;margin:15px 40px;" width="10" height="14" viewbox="0 0 60 100">
<path d="M0 8c0-5 3-8 8-8s9 3 9 8v84c0 5-4 8-9 8s-8-3-8-8V8zm43 0c0-5 3-8 8-8s8 3 8 8v84c0 5-3 8-8 8s-8-3-8-8V8z"></path>
</svg>
</div>
<audio id="player5" preload="none" style="display:none;">
<source src='http://hi5.1980s.fm/' type='audio/mpeg'>
</audio>
<div id="playButton6" onclick="">
<svg class="play" style="margin:15px 36px;" width="12" height="14" viewbox="0 0 85 100">
<path d="M81 44.6c5 3 5 7.8 0 10.8L9 98.7c-5 3-9 .7-9-5V6.3c0-5.7 4-8 9-5l72 43.3z"></path>
</svg>
<svg class="pause" style="display: none;margin:15px 37px;" width="10" height="14" viewbox="0 0 60 100">
<path d="M0 8c0-5 3-8 8-8s9 3 9 8v84c0 5-4 8-9 8s-8-3-8-8V8zm43 0c0-5 3-8 8-8s8 3 8 8v84c0 5-3 8-8 8s-8-3-8-8V8z"></path>
</svg>
</div>
<audio id="player6" preload="none" style="display:none;">
<source src='http://hi5.1980s.fm/' type='audio/mpeg'>
</audio>
<script>
var button = document.getElementById('playButton4');
var player = document.getElementById('player4');
player.volume = 1.0;
if (player.paused) {
document.querySelector('#playButton4 .pause').style.display = 'inline-block';
document.querySelector('#playButton4 .play').style.display = 'none';
player.play();
} else {
document.querySelector('#playButton4 .pause').style.display = 'none';
document.querySelector('#playButton4 .play').style.display = 'inline-block';
player.pause();
}
var button = document.getElementById('playButton5');
var player = document.getElementById('player5');
player.volume = 1.0;
if (player.paused) {
document.querySelector('#playButton5 .pause').style.display = 'inline-block';
document.querySelector('#playButton5 .play').style.display = 'none';
player.play();
} else {
document.querySelector('#playButton5 .pause').style.display = 'none';
document.querySelector('#playButton5 .play').style.display = 'inline-block';
player.pause();
}
var button = document.getElementById('playButton6');
var player = document.getElementById('player6');
player.volume = 1.0;
if (player.paused) {
document.querySelector('#playButton6 .pause').style.display = 'inline-block';
document.querySelector('#playButton6 .play').style.display = 'none';
player.play();
} else {
document.querySelector('#playButton6 .pause').style.display = 'none';
document.querySelector('#playButton6 .play').style.display = 'inline-block';
player.pause();
}
</script>
I cleaned it up a bit here, but it doesnât work for some reason.
This was the last working version, before I moved it to javascript:
<style>
.playButton3 {
display: inline-block;
background-color: #000000;
border-top: 3px solid #0059dd;
border-bottom: 3px solid #0059dd;
cursor: pointer;
height: 44px;
}
.playButton4 {
display: inline-block;
width: 83px;
border-left: 3px solid #0059dd;
fill: #aaff00;
}
.playButton5 {
display: inline-block;
width: 88px;
border-left: 3px solid #0059dd;
border-right: 3px solid #0059dd;
fill: #ffaa00;
}
.playButton6 {
display: inline-block;
width: 83px;
border-right: 3px solid #0059dd;
fill: #ff00aa;
}
.playButtons {
white-space: nowrap;
font-size: 0;
}
</style>
<div class="playButtons">
<div class="playButton3">
<div class="playButton4">
<svg class="play" style="margin:15px 36px;" width="12" height="14" viewbox="0 0 85 100">
<path d="M81 44.6c5 3 5 7.8 0 10.8L9 98.7c-5 3-9 .7-9-5V6.3c0-5.7 4-8 9-5l72 43.3z"></path>
</svg>
<svg class="pause" style="display: none;margin:15px 37px;" width="10" height="14" viewbox="0 0 60 100">
<path d="M0 8c0-5 3-8 8-8s9 3 9 8v84c0 5-4 8-9 8s-8-3-8-8V8zm43 0c0-5 3-8 8-8s8 3 8 8v84c0 5-3 8-8 8s-8-3-8-8V8z"></path>
</svg>
<audio id="player4" preload="none" style="display:none;">
<source src="http://hi5.1980s.fm/" type="audio/mpeg">
</audio>
</div>
<div class="playButton5">
<svg class="play" style="margin:15px 39px;" width="12" height="14" viewbox="0 0 85 100">
<path d="M81 44.6c5 3 5 7.8 0 10.8L9 98.7c-5 3-9 .7-9-5V6.3c0-5.7 4-8 9-5l72 43.3z"></path>
</svg>
<svg class="pause" style="display: none;margin:15px 40px;" width="10" height="14" viewbox="0 0 60 100">
<path d="M0 8c0-5 3-8 8-8s9 3 9 8v84c0 5-4 8-9 8s-8-3-8-8V8zm43 0c0-5 3-8 8-8s8 3 8 8v84c0 5-3 8-8 8s-8-3-8-8V8z"></path>
</svg>
<audio id="player5" preload="none" style="display:none;">
<source src="http://hi5.1980s.fm/" type="audio/mpeg">
</audio>
</div>
<div class="playButton6">
<svg class="play" style="margin:15px 36px;" width="12" height="14" viewbox="0 0 85 100">
<path d="M81 44.6c5 3 5 7.8 0 10.8L9 98.7c-5 3-9 .7-9-5V6.3c0-5.7 4-8 9-5l72 43.3z"></path>
</svg>
<svg class="pause" style="display: none;margin:15px 37px;" width="10" height="14" viewbox="0 0 60 100">
<path d="M0 8c0-5 3-8 8-8s9 3 9 8v84c0 5-4 8-9 8s-8-3-8-8V8zm43 0c0-5 3-8 8-8s8 3 8 8v84c0 5-3 8-8 8s-8-3-8-8V8z"></path>
</svg>
<audio id="player6" preload="none" style="display:none;">
<source src="http://hi5.1980s.fm/;" type="audio/mpeg">
</audio>
</div>
</div>
<script>
(function iife() {
"use strict";
function playButton5ClickHandler() {
var button = document.querySelector("playButton4");
var player = document.querySelector("#player4");
player.volume = 1.0;
if (player.paused) {
document.querySelector(".playButton4 .pause").style.display = "inline-block";
document.querySelector(".playButton4 .play").style.display = "none";
player.play();
} else {
document.querySelector(".playButton4 .pause").style.display = "none";
document.querySelector(".playButton4 .play").style.display = "inline-block";
player.pause();
}
}
var playButton = document.querySelector(".playButton4");
playButton.addEventListener("click", playButtonClickHandler);
}
}
var button = document.querySelector("playButton5");
var player = document.querySelector("#player5");
player.volume = 1.0;
if (player.paused) {
document.querySelector(".playButton5 .pause").style.display = "inline-block";
document.querySelector(".playButton5 .play").style.display = "none";
player.play();
} else {
document.querySelector(".playButton5 .pause").style.display = "none";
document.querySelector(".playButton5 .play").style.display = "inline-block";
player.pause();
}
}
var playButton = document.querySelector(".playButton5");
playButton.addEventListener("click", playButtonClickHandler);
}
}
var button = document.querySelector("playButton6");
var player = document.querySelector("#player6");
player.volume = 1.0;
if (player.paused) {
document.querySelector(".playButton6 .pause").style.display = "inline-block";
document.querySelector(".playButton6 .play").style.display = "none";
player.play();
} else {
document.querySelector(".playButton6 .pause").style.display = "none";
document.querySelector(".playButton6 .play").style.display = "inline-block";
player.pause();
}
}
var playButton = document.querySelector(".playButton6");
playButton.addEventListener("click", playButtonClickHandler);
}());
What does this error mean and how do you fix it?
Class names are not supposed to be individually numbered for a start. Thatâs a strong indicator that things arenât being done right.
Can this be cleaned up and work?
(function iife() {
"use strict";
function playButton5ClickHandler() {
var button = document.querySelector("playButton4");
var player = document.querySelector("#player4");
player.volume = 1.0;
if (player.paused) {
document.querySelector(".playButton4 .pause").style.display = "inline-block";
document.querySelector(".playButton4 .play").style.display = "none";
player.play();
} else {
document.querySelector(".playButton4 .pause").style.display = "none";
document.querySelector(".playButton4 .play").style.display = "inline-block";
player.pause();
}
var playButton = document.querySelector(".playButton4");
playButton.addEventListener("click", playButtonClickHandler);
}
}
function playButton5ClickHandler() {
var button = document.querySelector("playButton5");
var player = document.querySelector("#player5");
player.volume = 1.0;
if (player.paused) {
document.querySelector(".playButton5 .pause").style.display = "inline-block";
document.querySelector(".playButton5 .play").style.display = "none";
player.play();
} else {
document.querySelector(".playButton5 .pause").style.display = "none";
document.querySelector(".playButton5 .play").style.display = "inline-block";
player.pause();
}
var playButton = document.querySelector(".playButton5");
playButton.addEventListener("click", playButtonClickHandler);
}
}
function playButton5ClickHandler() {
var button = document.querySelector("playButton6");
var player = document.querySelector("#player6");
player.volume = 1.0;
if (player.paused) {
document.querySelector(".playButton6 .pause").style.display = "inline-block";
document.querySelector(".playButton6 .play").style.display = "none";
player.play();
} else {
document.querySelector(".playButton6 .pause").style.display = "none";
document.querySelector(".playButton6 .play").style.display = "inline-block";
player.pause();
}
}
var playButton = document.querySelector(".playButton6");
playButton.addEventListener("click", playButtonClickHandler);
}());
<script>
Only by deleting most of it. I donât have time today to guide you through that, as Iâm departing in a few hours.
With IE11 and the nodeList.forEach
issue, you can add in support for it using the following code, sourced from https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach#Polyfill
if (window.NodeList && !NodeList.prototype.forEach) {
NodeList.prototype.forEach = function (callback, thisArg) {
thisArg = thisArg || window;
for (var i = 0; i < this.length; i++) {
callback.call(thisArg, this[i], i, this);
}
};
}
The best place to put that code is at top of your script.
Can it be set up in that format though?
You havenât said what you mean by âthat formatâ yet.
Like this?
The same structure as this?
<script>
(function iife() {
"use strict";
function playButtonClickHandler() {
var button = document.querySelector(".playButton2");
var player = document.querySelector("#player2");
player.volume = 1.0;
if (player.paused) {
button.querySelector(".play").style.display = "none";
button.querySelector(".pause").style.display = "inline-block";
player.play();
} else {
button.querySelector(".play").style.display = "inline-block";
button.querySelector(".pause").style.display = "none";
player.pause();
}
}
var playButton = document.querySelector(".playButton2");
playButton.addEventListener("click", playButtonClickHandler);
}());
</script>
No, it shouldnât be done that way.
Instead, that single function should be adjusted so that the button, the player, and the play/pause buttons are passed in to it as function parameters.
That way, the one playButton function will be able to work on all of the players.