I have below javascript written, I would like to add tooltip on a button for every desktop device of different sizes. Can anyone advise how can I mention different media screen in my javascript and how could I test it in my laptop for every media screen I included in style.
<style>
.banner-text>div>.banner-link.link-highlight
{
display: none;
}
.booking-widget-home
{
background-image: url('https://www.goxyz.in/content/dam/goxyz/6e-website/banner/target/05/Banner-Blue-checks.jpg') !important;
}
.banner-title
{
color: white;
}
.banner-description
{
color: white;
}
.offers-container.offers-up
{
cursor: pointer;
}
.banner-link.link-highlight
{
border-radius: 10px;
}
.ntooltip
{
position: absolute;
background: #92dff6;
color: #3e3158;
padding: 2px 0;
border-radius: 10px;
bottom: 42px;
left: 100px;
text-align: center;
font-size: 11px;
width: 130px;
box-shadow: 2px 5px 14px 0 rgba(0, 0, 0, .5);
}
.ntooltip:before
/* triangle decoration */
{
width: 0;
height: 0;
border-left: 8px solid transparent;
border-right: 8px solid transparent;
border-bottom: 10px solid #92dff6;
content: '';
position: absolute;
left: 50%;
top: -10px;
margin-left: -10px;
}
</style>
<script>
(function()
{
'use strict';
var cnt = 6000;
function init()
{
if (typeof jQuery != "undefined")
{
// call to change content
content_change();
}
else
{
cnt = cnt - 500;
if (cnt > 500) setTimeout(init, 500);
}
}
// function to change your content
function content_change()
{
if (jQuery(".booking-widget-home").length > 0)
{
jQuery('.offers-container.offers-up > .offers-wrapper > div >h1 ').text('Kerala Alert!');
jQuery('.offers-container.offers-up > .offers-wrapper > div > p.banner-description ').html("Tooltip test is successfull</br><span><a href='https://www.goggle.com' target='_blank' class='banner-link link-highlight'>Add snacks</a></span>");
$('.banner-description > span').append('<div class="ntooltip">Click Here to Know More</div>');
}
else
{
cnt = cnt - 500;
if (cnt > 500) setTimeout(content_change, 500);
}
}
init();
})()
</script>
Related
I am trying to change a menu from a list to a dropdown.
I am using the Mapplic - Custom Interactive Map WordPress Plugin
I found the code for it, but I don't seem to get it to
this.addLevelSwitcher = function() {
if (self.data.levels.length > 1) {
var control = $('<div></div>').addClass('mapplic-level-switcher');
self.data.levels.forEach(function(level, i) {
var button = $('<button></button>').attr('data-level', level.id).text(level.title).prependTo(control).click(function(e) {
e.preventDefault();
self.switchLevel(level.id);
});
if (level.show) button.addClass('mapplic-selected');
});
this.el.append(control);
self.el.on('levelswitched', function(e, target) {
$('button', control).removeClass('mapplic-selected');
$('button[data-level="' + target + '"]', control).addClass('mapplic-selected');
});
}
}
Also here is the css
/* new switcher */
.mapplic-level-switcher {
position: absolute;
right: 0;
top: 0px;
margin: 12px;
}
.mapplic-level-switcher button {
background-color: #f8f8f8;
border-radius: 0;
color: #888;
cursor: pointer;
display: block;
font-size: 11px;
font-weight: 600;
line-height: 20px;
padding: 4px 10px;
text-align: center;
user-select: none;
width: 100%;
border: none;
transition: transform 0.2s;
position: relative;
}
.mapplic-level-switcher button:hover { background-color: #f8f8f8; }
.mapplic-level-switcher button:focus { outline: none; }
.mapplic-level-switcher button.mapplic-selected {
box-shadow: 0 0 12px rgba(0, 0, 0, 0.06);
background-color: #fff;
color: #222;
transform: scale(1.15);
z-index: 100;
}
I am trying to make it more responsive on mobile...
Another thing I was thinking was to hide this menu on mobile and add indiviuals buttons in order to trigger the floor plan.
Any ideas on how could I do any of this?
Thanks
I am coding a (mp3) sample/jingle/sound player button.
The top row has 2 control buttons and a volume slider, pressing the section below will play the sound.
The first control button toggles loop mode on off (this is functioning as expected)
The second control button is supposed to toggle "play/pause" mode.
If play/pause mode is "on" and you press the button a second time (while it is playing) it should pause, the when you press a 3rd time should resume playing but instead currently, it restarts from the begining on second press. Where did I go wrong?
function playsound() {
var audiox = document.getElementById('playerx');
audiox.src = "http://glentertainment.keybit.co.uk/audiop2/22%20Air%20Horn%20Single.mp3";
var playmode = document.getElementById('playpauseorrapidpressonoff').innerText;
if (playmode != "off") {
if (audiox.paused) {
audiox.play()
} else {
audiox.pause()
}
} else {
audiox.play();
}
}
function setvolume() {
document.getElementById('playerx').volume = document.getElementById('ssvolume').value;
}
function playmodebuttonpressed() {
onoffcheck = document.getElementById('playpauseorrapidpressonoff').innerText;
if (onoffcheck != "off") {
document.getElementById('playpauseorrapidpress').style.backgroundColor = "grey";
document.getElementById('playpauseorrapidpressonoff').innerText = "off";
} else {
document.getElementById('playpauseorrapidpress').style.backgroundColor = "black";
document.getElementById('playpauseorrapidpressonoff').innerText = "on";
}
}
function repeatbuttonpressed() {
onoffcheck = document.getElementById('repeatbuttonpressed').innerText;
if (onoffcheck != "off") {
document.getElementById('loop').style.backgroundColor = "grey";
document.getElementById('repeatbuttonpressed').innerText = "off";
document.getElementById('playerx').loop = false;
} else {
document.getElementById('loop').style.backgroundColor = "black";
document.getElementById('repeatbuttonpressed').innerText = "on";
document.getElementById('playerx').loop = true;
}
}
.ssvolume {
transform: scale(0.8);
width: 60px;
position: absolute;
top: 0;
right: 0;
display: inline-block;
margin: 0;
padding: 0;
}
.singlesoundcontainer {
width: 100px;
height: 100px;
box-shadow: inset 0px 1px 0px 0px #a4e271;
background: linear-gradient(to bottom, #89c403 5%, #77a809 100%);
background-color: #89c403;
border: 1px solid #74b807;
border-radius: 5px;
display: block;
position: relative;
}
.singlesamplercontrols {
width: 100px;
height: 20px;
background-color: transparent;
border-radius: 5px 5px 0 0;
border: 0.1px solid black;
}
.ssrepeatbutton {
margin-top: 0px;
margin-bottom: 0px;
margin-left: 0px;
margin-right: -4px;
padding: 0px;
background-color: grey;
display: inline-block;
width: 20px;
cursor: pointer;
}
.ssrepeatbutton:hover {
background-color: black;
}
.singlesamplertrigger {
width: 90px;
height: 69px;
cursor: pointer;
padding: 5px;
color: black;
border-radius: 0 0 5px 5px;
display: inline-block;
overflow: hidden;
background-color: transparent;
font-family: Arial;
font-weight: bold;
text-decoration: none;
text-shadow: 0px 1px 0px #528009;
font-size: 11.5px;
line-height: 10px;
border-bottom: 0.1px solid black;
border-left: 0.1px solid black;
border-right: 0.1px solid black;
-webkit-user-select: none;
/* Safari */
-moz-user-select: none;
/* Firefox */
-ms-user-select: none;
/* IE10+/Edge */
user-select: none;
/* Standard */
}
<div class="singlesoundcontainer">
<div class="singlesamplercontrols">
<img class="ssrepeatbutton" id="loop" onClick="repeatbuttonpressed();" src="https://www.bossdj.net/sampledeck/images/repeat-icon.png">
<span id="repeatbuttonpressed" style="display:none;">off</span>
<img class="ssrepeatbutton" id="playpauseorrapidpress" onClick="playmodebuttonpressed();" src="https://www.bossdj.net/sampledeck/images/playpausemode-icon.png">
<span id="playpauseorrapidpressonoff" style="display:none;">off</span>
<input class="ssvolume" type="range" id="ssvolume" min="0" max="1" value="1" step="0.01" onInput="setvolume();">
</div>
<div class="singlesamplertrigger" onClick="playsound();" id="singlesampler">Air Horn (Single)</div>
</div><br />
<!--Below audio element will be hidden in final code-->
<audio id="playerx" style="display: block; width: 280px" src="#" controls></audio>
You should initialise the src of the audio tag only once, and then just toggle the play/pause.
window.addEventListener('DOMContentLoaded', () => {
var audiox = document.getElementById('playerx');
audiox.src = "http://glentertainment.keybit.co.uk/audiop2/22%20Air%20Horn%20Single.mp3";
})
function playsound() {
var audiox = document.getElementById('playerx');
var playmode = document.getElementById('playpauseorrapidpressonoff').innerText;
if (playmode != "off") {
if (audiox.paused) {
audiox.play()
} else {
audiox.pause()
}
} else {
audiox.play();
}
}
I work with statick creation elements, and for this i need to have slider.
I just create slider, but elements are not fit in to slider container.
Example:
var htmlElements;
var userName = "Jonny Programmer"
var id = "6656"
function createUserCard() {
htmlElements = `<div class="user-card">
<img src="https://source.unsplash.com/user/erondu" class="userImage" />
<div class="info">
<div class="name">${userName}</div>
<div class="handle">
<div class="idPersone">${id}</div>
</div>
</div>
</div>`
$('.cardsCreation').append(htmlElements);
}
$('#plus-button').on('click', function () {
createUserCard();
});
(function () {
var sliderImages = document.querySelectorAll('.image'),
arrowLeft = document.querySelector('#left-arrow'),
arrowRight = document.querySelector('#right-arrow'),
currentImg = 0;
function initSlider() {
resetSlider();
sliderImages[0].style.display = 'block';
}
function resetSlider() {
for (var i = 0; i < sliderImages.length; i++) {
sliderImages[i].style.display = 'none';
}
}
function toLeft() {
resetSlider();
sliderImages[currentImg - 1].style.display = 'block';
currentImg--;
}
function toRight() {
resetSlider();
sliderImages[currentImg + 1].style.display = 'block';
currentImg++;
}
arrowLeft.addEventListener('click', function () {
if (currentImg === 0) {
currentImg = sliderImages.length;
}
toLeft();
});
arrowRight.addEventListener('click', function () {
if (currentImg === sliderImages.length - 1) {
currentImg = -1;
}
toRight();
});
initSlider();
})();
.user-card, userImage {
box-shadow: 0px 2px 5px 0 rgba(0,0,0,0.25);
}
.user-card {
margin: 12px;
padding: 10px 10px 10px 10px;
border-radius: 12px;
width: 160px;
text-align: center;
float: left;
background-color: #fff;
}
.userImage {
border-radius: 50%;
height: 140px;
width: 140px;
border: 5px solid #eee;
}
.name {
font-size: 20px;
margin: 5px;
font-weight: bold;
}
.progress {
color: #25af53;
font-size: 48px;
}
#plus-button {
width: 55px;
height: 55px;
border-radius: 50%;
background: #428bca;
position: absolute;
top: 33%;
margin-left: 20px;
cursor: pointer;
box-shadow: 0px 2px 5px #666;
border: none;
outline: none;
}
.plus {
color: white;
position: absolute;
top: 0;
display: block;
bottom: 0;
left: 0;
right: 0;
text-align: center;
padding: 0;
margin: 0;
line-height: 55px;
font-size: 38px;
font-family: 'Roboto';
font-weight: 300;
}
#plus-button:hover {
box-shadow: 0 6px 14px 0 #666;
transform: scale(1.05);
}
.wrapper {
position: relative;
}
.arrow {
cursor: pointer;
position: absolute;
width: 0;
height: 0;
border-style: solid;
top: 50%;
margin-top: 160px;
}
#left-arrow {
border-width: 50px 40px 50px 0;
border-color: transparent #000 transparent transparent;
left: 0;
margin-left: 25px;
}
#right-arrow {
border-width: 50px 0 50px 40px;
border-color: transparent transparent transparent #000;
right: 0;
margin-right: 25px;
}
.image {
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.vertical-align-wrapper {
display: table;
overflow: hidden;
text-align: center;
}
.vertical-align-wrapper span {
display: table-cell;
vertical-align: middle;
font-size: 5rem;
color: #ffffff;
}
#media only screen and (max-width : 992px) {
.vertical-align-wrapper span {
font-size: 2.5rem;
}
#left-arrow {
border-width: 30px 20px 30px 0;
margin-left: 15px;
}
#right-arrow {
border-width: 30px 0 30px 20px;
margin-right: 15px;
}
.arrow {
margin-top: -30px;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<div id="left-arrow" class="arrow"></div>
<div id="slider">
<div class="image image-one">
<div class="vertical-align-wrapper">
<div class="cardsCreation"></div>
<button id="plus-button">
<p class="plus">+</p>
</button>
</div>
</div>
<div class="image image-two">
<div class="vertical-align-wrapper">
<span>Slide 2</span>
</div>
</div>
<div class="image image-three">
<div class="vertical-align-wrapper">
<span>Slide 3</span>
</div>
</div>
</div>
<div id="right-arrow" class="arrow"></div>
</div>
So as u can see affter tapping "+" i add new ellement in to html.
And from two sides i have arrows which are changing slider.
After tapping arrows go down, and this is not good.
And after i will reach limit of adding element in one slider it's add new element to new slider page.
What i want ex:
If you are using toggle of display CSS property that happened because it remove whole element from the DOM so, I suggest you to use visibility or opacity properties to done your task.
I have problem with my algorithm in simple game.
Game Rules:
Match color NAME (choose one on the bottom) with COLOR of TEXT (on the top).
If none of the two bottom names match than click NEXT.
So the problem is that first correct match gives in console "GOOD" but second , third and any after, even if there is correct match in console I have firstly always "WRONG" and just after that I have "GOOD".
This is a picture with the problem described
It seems like the script remember past random numbers and match current result with them, because after few matches the score pointer raise very quickly (ex. 20 points in one time).
I will be happy to hear from you how can I fix this.
Thank you for any help !
Here you have link to codepen:
http://codepen.io/anon/pen/bWGGga
"use strict"
/*Start Container*/
/* var startContainer = document.getElementById("start_container");
var letsPlay = document.getElementById("start_game"); */
/* letsPlay.addEventListener("click", openTheGame); */
function openTheGame(){
setInterval(startGame, 3000);
};
openTheGame();
var btn1 = document.getElementById("btn1");
var btn2 = document.getElementById("btn2");
var btn3 = document.getElementById("btn3");
var showColor = document.getElementById("show_color");
//SCORE
var score = document.getElementById("score");
var gameContainer = document.getElementById("game_container");
var gameOverContainer = document.getElementById("game_over_container");
/*Array of Colors*/
var arrCol = ["GREEN", "RED", "YELLOW", "BLUE", "ORANGE", "PURPLE"]
//Array from buttons texts to draw Show Color
var arrShowColor = [];
function startGame(){
/*BUTTONS TEXT & COLOR*/
btn1.addEventListener("click", matchColor1);
btn2.addEventListener("click", matchColor2);
btn3.addEventListener("click", matchColor3);
//draw numbers for buttons texts & colors
var randomBtn1Num = Math.floor(Math.random() * 3);
var randomBtn2Num = Math.floor(Math.random() * 3)+3;
var randomBtn3Num = Math.floor(Math.random() * 6);
//Buttons text (next button always "next")
btn1.innerHTML = arrCol[randomBtn1Num];
btn2.innerHTML = arrCol[randomBtn2Num];
//Buttons Color from random_color class
btn1.className = "random_color" + randomBtn2Num;
btn2.className = "random_color" + randomBtn3Num;
btn3.className = "random_color" + randomBtn1Num;
/*SHOW TEXT & COLOR*/
//Array from buttons texts to draw Show Color
arrShowColor[0] = randomBtn1Num;
arrShowColor[1] = randomBtn2Num;
arrShowColor[2] = randomBtn3Num;
console.log(arrShowColor);
//Show color
var randomShowColorNum = Math.floor(Math.random()*3);
var randomShowColor = arrShowColor[randomShowColorNum];
showColor.className = "random_color" + randomShowColor;
console.log(randomShowColor);
//Show text
var randomShowText = Math.floor(Math.random() * 6);
showColor.innerHTML = arrCol[randomShowText];
/*CLICK BUTTON - IF MATCH COLORS*/
function matchColor1(){
if( randomBtn1Num == randomShowColor) {
console.log("GOOD");
score.innerHTML ++;
} else {
console.log("WRONG");
/*gameContainer.style.display = "none";
gameOverContainer.style.display = "inline-block";*/
}
};
function matchColor2(){
if( randomBtn2Num == randomShowColor) {
console.log("GOOD");
score.innerHTML ++;
} else {
console.log("WRONG");
/*gameContainer.style.display = "none";
gameOverContainer.style.display = "inline-block";*/
}
};
function matchColor3(){
if(randomBtn1Num != randomShowColor && randomBtn2Num != randomShowColor){
console.log("GOOD");
score.innerHTML ++;
} else {
console.log("WRONG");
/*gameContainer.style.display = "none";
gameOverContainer.style.display = "inline-block";*/
}
};
/*Finish startGame*/
};
/*Main Styles*/
body {
background-image: url()
}
h4 {
color: #2626e6;
}
/*Main Container Styles*/
#main_container {
width:100%;
text-align:center;
}
/*Start Container Styles*/
#start_container {
position: relative;
display: inline-block;
width: 400px;
height: 400px;
top: 20px;
background-color: rgb(0, 0, 0);
border-radius: 50%;
box-shadow: 0px 0px 10px 10px black;
}
#start_container button {
}
/*Game Container Styles*/
#game_container {
position: relative;
display: inline-block;
width: 400px;
height: 400px;
top: 20px;
background-color: rgb(0, 0, 0);
border-radius: 50%;
box-shadow: 0px 0px 10px 10px black;
}
.second_level{
transform: rotateY(180deg);
}
.third_level{
transform: rotateX(180deg);
}
/*Score Container*/
#score_container {
display: inline-block;
position: relative;
height: 150px;
width: 150px;
background-color: rgb(0, 0, 0);
top: -40px;
margin-left: -5px;
margin-right: 30px;
border-radius: 50%;
box-shadow: 0px 0px 10px 10px black;
}
#score_container #score {
display: inline-block;
height: 30px;
width: 80px;
color: #ffffff;
margin-left: 0;
margin-right: 0;
}
/*Level Container*/
#time_container {
display: inline-block;
position: relative;
height: 150px;
width: 150px;
background-color: rgb(0, 0, 0);
top: -40px;
margin-left: 30px;
border-radius: 50%;
box-shadow: 0px 0px 10px 10px black;
}
#time_container #time {
display: inline-block;
height: 30px;
width: 80px;
color: #ffffff;
margin-left: 0;
margin-right: 0;
}
/*Random Show Color Style*/
#show_color{
margin-top: 50px;
font-size: 40px;
font-family: sans-serif;
font-weight: 800;
}
/*Random Colors Classes*/
.random_color0{
color: green;
}
.random_color1{
color: red;
}
.random_color2{
color: yellow;
}
.random_color3{
color: blue;
}
.random_color4{
color: orange;
}
.random_color5{
color: purple;
}
/*Buttons Container Styles*/
#game_container #buttons_container {
position: relative;
display: inline-block;
margin:0 auto;
margin-top: 120px;
border-top: 1px solid white;
padding-top: 30px;
}
/*Buttons Style*/
#buttons_container button {
height: 40px;
width: 150px;
font-size: 30px;
font-weight: 800;
border: none;
border-radius: 3px;
background-color: rgb(0, 0, 0);
margin: 3px;
}
#buttons_container button:focus{
outline: 0;
}
#buttons_container button:hover{
cursor: pointer;
}
/*Game Over Container*/
#game_over_container {
display: none;
position: relative;
width: 400px;
height: 400px;
top: 20px;
background-color: rgb(0, 0, 0);
border-radius: 50%;
box-shadow: 0px 0px 10px 10px black;
}
<div id="main_container">
<!-- <div id="start_container">
<button id="start_game">PLAY GAME</button>
</div> -->
<div id="score_container">
<h4>SCORE:</h4>
<div id="score">0</div>
</div>
<div id="game_container">
<div id="show_color_container">
<div id="show_color"></div>
</div>
<div id="buttons_container">
<button class="btn_select" id="btn1">ONE</button>
<button class="btn_select" id="btn2">TWO</button>
<button class="btn_select" id="btn3">NEXT</button>
</div>
</div>
<div id="game_over_container">
<h2 id="game_over">GAME OVER</h2>
</div>
</div>
Inside openTheGame() you're using setInterval which calls startGame() every 3 seconds, which in turn creates (adds) new event handlers every 3 seconds, which call your console.logs etc. Replace setInterval with setTimeout:
function openTheGame(){
setTimeout(startGame, 3000);
};
openTheGame();
EDIT: did not thoroughly check your code, but if you need that function called every 3 seconds, then you need to move the setup of click handlers outside that function.
So I have recently been playing around with styling the html range slider.
I came across a pen on CodePen that has some really great designs.
This is the source code from one.
HTML:
<input type="range" data-idx="1">
CSS:
html {
background: #393939;
}
input[type='range'] {
display: block;
margin: 2.5em auto;
border: solid .5em transparent;
padding: 0;
width: 15.5em;
height: 1em;
border-radius: .25em;
background: transparent;
font-size: 1em;
cursor: pointer;
}
input[type='range'], input[type='range']::-webkit-slider-runnable-track, input[type='range']::-webkit-slider-thumb {
-webkit-appearance: none;
}
input[type='range']::-webkit-slider-runnable-track {
width: 15.5em;
height: 0.5em;
border-radius: 0.25em;
background: #fff;
}
.js input[type='range']::-webkit-slider-runnable-track {
background: linear-gradient(#e44e4f, #e44e4f) no-repeat #fff;
}
input[type='range']::-moz-range-track {
width: 15.5em;
height: 0.5em;
border-radius: 0.25em;
background: #fff;
}
.js input[type='range']::-moz-range-track {
background: linear-gradient(#e44e4f, #e44e4f) no-repeat #fff;
}
input[type='range']::-ms-track {
border: none;
width: 15.5em;
height: 0.5em;
border-radius: 0.25em;
background: #fff;
color: transparent;
}
input[type='range']::-ms-fill-lower {
border-radius: 0.25em;
background: #e44e4f;
}
input[type='range']:nth-of-type(1)::-webkit-slider-runnable-track {
background-size: 50% 100%;
}
input[type='range']:nth-of-type(1)::-moz-range-track {
background-size: 50% 100%;
}
input[type='range']:nth-of-type(1)::-webkit-slider-thumb {
margin-top: -0.125em;
border: none;
width: 0.75em;
height: 0.75em;
border-radius: 50%;
box-shadow: 0 0 0.125em #333;
background: #fff;
}
input[type='range']:nth-of-type(1)::-moz-range-thumb {
border: none;
width: 0.75em;
height: 0.75em;
border-radius: 50%;
box-shadow: 0 0 0.125em #333;
background: #fff;
}
input[type='range']:nth-of-type(1)::-ms-thumb {
border: none;
width: 0.75em;
height: 0.75em;
border-radius: 50%;
box-shadow: 0 0 0.125em #333;
background: #fff;
}
input[type='range']:nth-of-type(1)::-ms-tooltip {
display: none;
}
input[type='range']:focus {
outline: none;
box-shadow: 0 0 0.25em #e44e4f;
}
Javascript:
var s = document.createElement('style'),
r = document.querySelectorAll('input[type=range]'),
prefs = ['webkit-slider-runnable', 'moz-range'],
styles = [],
l = prefs.length
n = r.length;
document.body.appendChild(s);
var getTrackStyleStr = function(el) {
var str = '',
j = el.dataset.idx,
min = el.min || 0,
perc = (el.max) ? ~~(100*(el.value - min)/(el.max - min)) : el.value,
val = perc + '% 100%';
for(var i = 0; i < l; i++) {
str += '.js input[type=range]:nth-of-type(' + j + ')::-' + prefs[i] + '-track{background-size:' + val + '}';
}
return str;
};
var getTipStyleStr = function(el) {
var str = '.js input[type=range]:nth-of-type(' + el.dataset.idx + ') /deep/ #thumb:after{content:"' + el.value + '%"}';
return str;
};
for(var i = 0; i < n; i++) {
styles.push('');
r[i].addEventListener('input', function() {
styles[this.dataset.idx] = getTrackStyleStr(this);
if(this.classList.contains('tip')) {
styles[this.dataset.idx] += getTipStyleStr(this);
}
s.textContent = styles.join('');
}, false);
}
This works great for one range element but if I try adding more range elements on the same page, and change the data attribute to data-idx="2" it will not work, the first range will control them all.
How can I adjust the code to make each range work independently?
Here is a JSFiddle of the code I'm using, for some reason the javascript isn't working on there at all, but it's works fine on codepen? Hmm...
Here is the original Codepen
SOLUTION
var r = document.querySelectorAll('input[type=range]'),
prefs = ['webkit-slider-runnable', 'moz-range'],
styles = [],
l = prefs.length,
n = r.length;
var getTrackStyleStr = function(el, j) {
var str = '',
min = el.min || 0,
perc = (el.max) ? ~~(100*(el.value - min)/(el.max - min)) : el.value,
val = perc + '% 100%';
el.previousElementSibling.textContent = el.value;
for(var i = 0; i < l; i++) {
str += "input[type=range][data-rangeId='" + j + "']::-" + prefs[i] + '-track{background-size:' + val + '} ';
}
return str;
};
var setDragStyleStr = function(evt) {
var trackStyle = getTrackStyleStr(evt.target, this);
styles[this].textContent = trackStyle;
};
for(var i = 0; i < n; i++) {
var s = document.createElement('style');
document.body.appendChild(s);
styles.push(s);
r[i].setAttribute('data-rangeId', i);
r[i].addEventListener('input', setDragStyleStr.bind(i));
}
html {
background: #393939;
}
div {
margin: 2.5em auto;
}
input[type='range'] {
display: block;
margin: 0.2em auto;
border: solid .5em transparent;
padding: 0;
width: 15.5em;
height: 1em;
border-radius: .25em;
background: transparent;
font-size: 1em;
cursor: pointer;
}
input[type='range'],
input[type='range']::-webkit-slider-runnable-track,
input[type='range']::-webkit-slider-thumb {
-webkit-appearance: none;
}
input[type='range']::-webkit-slider-runnable-track {
width: 15.5em;
height: 0.5em;
border-radius: 0.25em;
background: #fff;
}
input[type='range']::-webkit-slider-runnable-track {
background: linear-gradient(#e44e4f, #e44e4f) no-repeat #fff;
}
input[type='range']::-moz-range-track {
width: 15.5em;
height: 0.5em;
border-radius: 0.25em;
background: #fff;
}
input[type='range']::-moz-range-track {
background: linear-gradient(#e44e4f, #e44e4f) no-repeat #fff;
}
input[type='range']::-ms-track {
border: none;
width: 15.5em;
height: 0.5em;
border-radius: 0.25em;
background: #fff;
color: transparent;
}
input[type='range']::-ms-fill-lower {
border-radius: 0.25em;
background: #e44e4f;
}
input[type='range']::-webkit-slider-runnable-track {
background-size: 0% 100%;
}
input[type='range']::-moz-range-track {
background-size: 0% 100%;
}
input[type='range']::-webkit-slider-thumb {
margin-top: -0.125em;
border: none;
width: 0.75em;
height: 0.75em;
border-radius: 50%;
box-shadow: 0 0 0.125em #333;
background: #fff;
}
input[type='range']::-moz-range-thumb {
border: none;
width: 0.75em;
height: 0.75em;
border-radius: 50%;
box-shadow: 0 0 0.125em #333;
background: #fff;
}
input[type='range']::-ms-thumb {
border: none;
width: 0.75em;
height: 0.75em;
border-radius: 50%;
box-shadow: 0 0 0.125em #333;
background: #fff;
}
input[type='range']::-ms-tooltip {
display: none;
}
input[type='range']:focus {
outline: none;
box-shadow: 0 0 0.25em #e44e4f;
}
output[for='range'] {
font-family: "Lucida Grande","Lucida Sans Unicode", Tahoma, Sans-Serif;
font-size: 13px;
color: white;
display: block;
text-align: center;
}
<div>
<output for="range">0</output>
<input type="range" value="0">
</div>
<div>
<output for="range">0</output>
<input type="range" value="0">
</div>
<div>
<output for="range">0</output>
<input type="range" value="0">
</div>
Jquery UI offers some functional sliders that can be used in multiple instances on a page. You don't have to write or modify as much code to use them as above. Unless you are trying to avoid jquery, this may be a better option for you.
Here is a link to the multiple sliders demo.
The approach used for multiple sliders relies of course on jquery, but given markup such as:
<div id="eq">
<span>88</span>
<span>77</span>
<span>55</span>
<span>33</span>
<span>40</span>
<span>45</span>
<span>70</span>
</div>
A simple .each statement handles setting them all up.
$( "#eq > span" ).each(function() {
// read initial values from markup and remove that
var value = parseInt( $( this ).text(), 10 );
$( this ).empty().slider({
value: value,
range: "min",
animate: true,
orientation: "vertical"
});
});
Edit: As per comments below, if you want to add tool-tips / hints, you have to roll your own. Here's a brief example from some code I wrote last year. It has some specific behaviors that fit the needs of my users, but this should give you an idea. The id "hintrow" refers to a table row on a grid that contained my slider. Through experimentation, you can probably find the best place relative to your various sliders to append this. It will get positioned so you only want a dom node to append it to.
function drawExtCues(){
z = 200;
$('#hintrow').append('<div id="hintContainer" style="position:relative"></div>');
for(h in rowobjects){
z++;
$('#hintContainer').append('<div title="' + rowobject[h].property1 + '" class="' + rowobject[h].property2+ ' ui-slider-range hint" style="z-index:' + z +';">' + rowobject[h].property1+ '</div>');
}
$('.hint').mouseover(function(){
hintMouseOver();
});
}
function hintMouseOver(){
$('.hint').addClass('hintInspect',500);
$('.hint').unbind('mouseover');
$('.hint').click(function(){
$J('.hint').removeClass('hintInspect',500);
$J('.hint').mouseover(function(){hintMouseOver();})
});
}
Note the z++. This was used to ensure my tool-tips would stack. Since we made them click to dismiss in our case, this worked well. You don't have to do this, but if you don't use a click to dismiss, you might want to bind a timeout to clear the tool tip for you.
The hintMouseOver function does some house cleaning, like unbinding itself to prevent repeat calls. It is rebound after the click event to dismiss the tool tip is fired. This is just the behavior my client wanted. You could do a lot of things here. The class hintInspect is basically the style rules for how your tool-tip will appear. You can make it look any way you like. I think I just used a simple black outline with grey background.