I am Completely new to JavaScript so this may be really obvious but I am trying to build an Andon system using traffic lights where if the number is above or below a certain number the light will change colour (i.e. > 5 = green). There are nine sets of lights in total, I have successfully made one light change based on the variable by using query select all and then change the opacity.
When i try and do this with the second light nothing happens. I have tried to make it work by naming my div elements in html and CSS differently e.g. "Zcircle", "A1circle"
Link to code pen.
Any help will be greatly appreciated!
Thanks
Code
HTML:
div class="Zcontainer">
<div class="Zcircle red" color="red">
</div>
<div class="Zcircle yellow" color="yellow"></div>
<div class="Zcircle green" color="green"></div>
</div>
<div class="A1container">
<div class="A1Circle red" color="red">
</div>
<div class="A1Circle yellow" color="yellow"></div>
<div class="A1Circle green" color="green"></div>
</div>
CSS
.Zcontainer {
background-color: #2c3e50;
border-radius: 60px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
position: relative;
left: 250px;
bottom: 75px;
padding: 15px 0;
height: 200px;
width: 70px;
}
.Zcircle {
background-color: rgba(0, 0, 0, 0.3);
border-radius: 100%;
position: relative;
height: 40px;
width: 40px;
}
.Zcircle::after {
border-right: 4px solid rgba(255, 255, 255, 0.6);
border-radius: 100%;
content: " ";
position: absolute;
top: 5px;
left: 0px;
width: 30px;
height: 30px;
}
.Zcircle.red {
background-color: #c0392b;
box-shadow: 0 0 20px 5px #c0392b;
}
.Zcircle.yellow {
background-color: #f1c40f;
box-shadow: 0 0 20px 5px #f1c40f;
}
.Zcircle.green {
background-color: #2ecc71;
box-shadow: 0 0 20px 5px #2ecc71;
}
.A1container {
background-color: #2c3e50;
border-radius: 60px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
position: relative;
left: 350px;
bottom: 275px;
padding: 15px 0;
height: 200px;
width: 70px;
}
.A1circle {
background-color: rgba(0, 0, 0, 0.3);
border-radius: 100%;
position: relative;
height: 40px;
width: 40px;
}
.A1circle::after {
border-right: 4px solid rgba(255, 255, 255, 0.6);
border-radius: 100%;
content: " ";
position: absolute;
top: 5px;
left: 0px;
width: 30px;
height: 30px;
}
.A1circle.red {
background-color: #c0392b;
box-shadow: 0 0 20px 5px #c0392b;
}
.A1circle.yellow {
background-color: #f1c40f;
box-shadow: 0 0 20px 5px #f1c40f;
}
.A1circle.green {
background-color: #2ecc71;
box-shadow: 0 0 20px 5px #2ecc71;
}
Javascript
//first traffic light - this one works
var myElements = document.querySelectorAll(".Zcircle");
for (var i = 0; i < myElements.length; i++) {
myElements[i].style.opacity = 0;
}
var $15a = 2 //value which will make the light change color
if ($15a > 4) {
var myElements = document.querySelectorAll(".Zcircle");
for (var x = 2; x < myElements.length; i++) {
myElements[x].style.opacity = 1;
}
} else if ($15a < 3) {
var myElements = document.querySelectorAll(".Zcircle");
for (var x = 0; x < myElements.length; i++) {
myElements[x].style.opacity = 1;
}
} else {
var myElements = document.querySelectorAll(".Zcircle");
for (var x = 1; x < myElements.length; i++) {
myElements[x].style.opacity = 1;
}
}
//second traffic light - this one doesnt work
var myElements = document.querySelectorAll(".A1circle");
for (var a = 0; a < myElements.length; a++) {
myElements[a].style.opacity = 0;
}
var $15b = 1; //value which will make the light change color
if ($15b > 4) {
var myElements = document.querySelectorAll(".A1circle");
for (var b = 2; x < myElements.length; b++) {
myElements[b].style.opacity = 1;
}
} else if ($15b < 3) {
var myElements = document.querySelectorAll(".A1circle");
for (var b = 0; b < myElements.length; b++) {
myElements[b].style.opacity = 1;
}
} else {
var myElements = document.querySelectorAll(".A1circle");
for (var b = 1; b < myElements.length; b++) {
myElements[b].style.opacity = 1;
}
}
Here is the final code you wanted.
let allZCircles = select(".Zcircle"),
allA1Circles = select(".A1Circle"),
items = 2;
//hides all the lights
setOpacity(allZCircles, 0);
setOpacity(allA1Circles, 0);
//as per op's requirnments
if(items >= 5) {
setOpacity(select(".Zcircle.green"), 1); // makes green light visible
setOpacity(select(".A1Circle.green"), 1); // makes green light visible
} else if (items < 3) {
setOpacity(select(".Zcircle.red"), 1); // makes red light visible
setOpacity(select(".A1Circle.red"), 1); // makes red light visible
} else {
setOpacity(select(".Zcircle.yellow"), 1); // makes yellow light visible
setOpacity(select(".A1Circle.yellow"), 1); // makes yellow light visible
}
function select(selector) {return document.querySelectorAll(selector); }
function setOpacity(selectors, opacity) {selectors.forEach((selector) => selector.style.opacity = opacity);}
I want to make a circle which have border, and border get smaller. Then when it have 0 border, want to change the color and finally circle's border grows up. To do that , I used this code but the circle doesn't get smaller and then grows up , it only change color.
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function yesno() {
navigator.vibrate(500);
for (var i = 0; i < 40; i++) {
var px = 39 - i;
document.getElementById("yesno").style.border = px + "px solid";
}
if (Math.random() < 0.5) {
for (var i = 0; i < 40; i++) {
var px = 1 + i;
document.getElementById("yesno").style.border = px + "px solid rgba(0,1000,0,1)";
}
} else {
for (var i = 0; i < 40; i++) {
var px = 1 + i;
document.getElementById("yesno").style.border = px + "px solid rgba(1000,0,0,1)";
}
}
}
</script>
<style type="text/css">
#yesno {
position: absolute;
border-radius: 50%;
transition: all 1000ms linear;
margin-left: 400px;
margin-top: 60px;
width: 120px;
height: 120px;
border: 40px solid rgba(1000,0,0,1);
}
#ynbtn {
position: absolute;
border: 40px solid rgba(0,0,0,1);
margin-left: 440px;
margin-top: 100px;
width: 40px;
height: 40px;
border-radius: 50%;
}
</style>
</head>
<body>
<div id="ploufisme">
<div class="yesno" onclick="yesno()">
<div id="yesno"></div>
<div id="ynbtn"></div>
</div>
</div>
</body>
</html>
Well, there as many ways to do this. This is a simple way. Note that I separated the border properties in order to transition only affect the border-width property. I think this is what you are trying to do.
var circle = document.querySelector('.circle');
function decreaseBorder() {
circle.classList.add('thin');
setTimeout(function() {
circle.classList.remove('thin');
circle.classList.add('bold');
}, 1000);
}
window.onload = function() { decreaseBorder(); }
.circle {
border-radius: 50%;
transition: border-width 1s linear;
width: 120px;
height: 120px;
border-width: 40px;
border-style: solid;
border-color: rgba(1000,0,0,1);
}
.thin {
border-width: 0;
}
.bold {
border-width: 40px;
border-color: rgba(0,0,0,1);
}
<div class="circle"></div>
I am playing around and practice my JS (beginner). I have created stacking panels and i hit a wall. I just can not target and add class of shadow to the moving element (only when one panel is above other, class should add).
For now i have this:
const boxes = Array.from(document.querySelectorAll(".box"));
const wrapper = document.querySelector(".wrapper");
const leftMargin = 60; //px
function scrollWrap(e) {
let scrollCoord = wrapper.scrollLeft; // horizontal scroll value
boxes.forEach((box, index) => {
let leftMarginStop = index * leftMargin;
const boxCoord = box.getBoundingClientRect();
let leftCoordPanel = boxCoord.left;
let flag = false;
//console.log({scrollCoord, leftMarginStop, leftCoordPanel, box});
if (boxCoord.left <= leftMarginStop) { // if left side of pannel is less than margin 60, 120, 180,...
//console.log("STAHP!!");
box.style.position = "sticky";
box.style.left = `${leftMarginStop}px`; // sets the left to 60, 120, 180,...
flag = true;
if (flag) {
box.classList.add("shadow");
console.log(this) //how to target each panel rather than wrapper?
} else {
box.classList.remove("shadow");
}
} else {
box.style.position = "static";
box.style.left = 0;
flag = false;
}
});
}
wrapper.addEventListener("scroll", scrollWrap);
body {
margin: 0;
padding: 0;
}
.wrapper, .box1, .box2, .box3, .box4, .box5, .box6, .box7, .box8 {
position: sticky;
height: 750px;
z-index: 1;
}
.wrapper {
width: 1442px;
border-right: 1px solid #f2f2f2;
border-bottom: 1px solid #f2f2f2;
display: flex;
overflow: scroll;
}
.wrapper .box1 {
min-width: 357px;
height: 750px;
background-color: #1a1a1a;
}
.wrapper .box2 {
min-width: 357px;
height: 750px;
background-color: #333;
}
.wrapper .box3 {
min-width: 702px;
height: 750px;
background-color: #4d4d4d;
}
.wrapper .box4 {
min-width: 630px;
height: 750px;
background-color: #666;
}
.wrapper .box5 {
min-width: 630px;
height: 750px;
background-color: #808080;
}
.wrapper .box6 {
min-width: 357px;
height: 750px;
background-color: #999;
}
.wrapper .box7 {
min-width: 630px;
height: 750px;
background-color: #b3b3b3;
}
.wrapper .box8 {
min-width: 630px;
height: 750px;
background-color: #ccc;
}
.shadow {
box-shadow: -4px 0px 40px rgba(0, 0, 0, 0.2);
}
<div class="wrapper">
<div class="box box1"></div>
<div class="box box2"></div>
<div class="box box3"></div>
<div class="box box4"></div>
<div class="box box5"></div>
<div class="box box6"></div>
<div class="box box7"></div>
<div class="box box8"></div>
</div>
If anyone can help me out, please show me code with explanation, so i can see and know what and how.
I try to do it with some flag or without, but every time the class is added when element reaches the end (left padding). I want to add class when element is on top of other element. If it is not, remove class. Also, how to make this so it works on mouse scroll wheel? I was testing this with apple magic mouse, but on scroll wheel it does not work.
Oh and please, if you see something very wrong please let me know, i am beginner and would like to learn something from this post.
For now i have managed to update my code. It works when i scroll and shadow is also applying to the panel. There is still something i wonder.
When i add shadow class i created transition. It works perfect, but when i remove shadow class it just disappears, no transition back. Why is that? I want shadow to appear and disappear in same way
How to track every single panel if it has reached the left margin, and than apply eventListener with mouse enter and mouse leave on it? So when i hover to "closed" panel, i get that item and if i hover on NOT "closed" panel i will not get item. I was trying with console.log "this" but it returned every panel i mouse entered it
How to target every panel, so i can later say, when 4th panel reaches left margin, the margin of stacked elements change?
My updated code:
const boxes = Array.from(document.querySelectorAll(".box"));
const wrapper = document.querySelector(".wrapper");
const leftMargin = 60; //px
function scrollWrap(e) {
let scrollCoord = wrapper.scrollLeft; // horizontal scroll value
boxes.forEach((box, index) => {
let leftMarginStop = (index) * leftMargin; // calculation for left margin stop (60, 120, 180,...)
const boxCoord = box.getBoundingClientRect();
const leftSideOfCurrent = boxCoord.left; // coordinarion of left side of panel
const rightSideOfCurrent = boxCoord.right; // coordinarion of right side of panel
const leftSideOfNextItem = box.nextElementSibling.getBoundingClientRect().left; // coordinarion of left side of NEXT panel
box.style.position = "sticky";
box.style.left = `${leftMarginStop}px`;
// controll shadow of first element
scrollCoord > 0 ? boxes[1].classList.add("shadow") : boxes[1].classList.remove("shadow");
// controll shadow of all 0+ elements
if (leftSideOfCurrent <= leftMarginStop) { // if left side of pannel is less than margin 60, 120, 180,...
box.nextElementSibling.classList.add("shadow");
}
// controll removal of shadow of all 0+ elements
if (leftSideOfNextItem === rightSideOfCurrent) {
box.nextElementSibling.classList.remove("shadow");
}
// when panel 5 reach left margin, left margin change from 60 to 30 to all panels
if (boxes[4] && leftSideOfCurrent < leftMarginStop) {
console.log("helo");
}
});
}
wrapper.addEventListener("scroll", scrollWrap);
body {
margin: 0;
padding: 0;
}
.wrapper, .box1, .box2, .box3, .box4, .box5, .box6, .box7, .box8 {
position: sticky;
height: 750px;
z-index: 1;
}
.wrapper {
width: 1442px;
border-right: 1px solid #f2f2f2;
border-bottom: 1px solid #f2f2f2;
display: flex;
overflow: scroll;
}
.wrapper .box0 {
min-width: 357px;
background-color: #1a1a1a;
}
.wrapper .box1 {
min-width: 357px;
background-color: #333;
}
.wrapper .box2 {
min-width: 702px;
background-color: #4d4d4d;
}
.wrapper .box3 {
min-width: 630px;
background-color: #666;
}
.wrapper .box4 {
min-width: 630px;
background-color: #808080;
}
.wrapper .box5 {
min-width: 357px;
background-color: #999;
}
.wrapper .box6 {
min-width: 630px;
background-color: #b3b3b3;
}
.wrapper .box7 {
min-width: 630px;
background-color: #ccc;
}
.shadow {
box-shadow: -4px 0px 40px rgba(0, 0, 0, 1.2);
-webkit-transition: box-shadow 0.2s cubic-bezier(0.4,-0.01, 0, 0.98);
-moz-transition: box-shadow 0.2s cubic-bezier(0.4,-0.01, 0, 0.98);
-o-transition: box-shadow 0.2s cubic-bezier(0.4,-0.01, 0, 0.98);
transition: box-shadow 0.2s cubic-bezier(0.4,-0.01, 0, 0.98);
}
<div class="wrapper">
<div class="box box0"></div>
<div class="box box1"></div>
<div class="box box2"></div>
<div class="box box3"></div>
<div class="box box4"></div>
<div class="box box5"></div>
<div class="box box6"></div>
<div class="box box7"></div>
</div>
Tips for your code:
In your CSS code, the wrapper element has a width property. This
causes the page and the wrapper element to have a scrollbars. So,
remove it.
You do not need to use javascript to add stickiness to the
boxes. The only CSS will do this for you. You need JavaScript only
for add the left property and shadow to the boxes.
Don’t try to use overflow: auto|scroll|hidden on the parent element
of a position:sticky element. It completely breaks the stickiness.
overflow: visible is fine. See the code snippet below.
In your JavaScript code, the flag variant value, always is true, So
the shadow class can't remove from elements.
Other notes:
If you’re wanting to use position:absolute on an element inside of
a sticky element you have to be careful. If your app is running in
an older browser that doesn’t support position:sticky, then that
sticky element won’t act like a relative positioned element. So
the absolute positioned element will skip it and look up the DOM
tree until it finds the next non-static element (absolute / relative / fixed position), defaulting to the html element if none
found. In other words, your absolute positioned element is going
to be in a way different place on the screen than you expected it to
be.
position: sticky; is supported in a lot of browsers, but not yet
in Edge. IE doesn’t matter at this point. There are many
polyfills out there if you absolutely have to have this behavior,
but they all use JavaScript. A better option is to design your app
so that sticky position is a slick addition, but the app still
functions without it.
Example:
const boxes = Array.from( document.querySelectorAll( '.box' ) ),
scroller = document.querySelector( '.scroller' ),
leftMargin = 30,
length = boxes.length - 1;
function scrollWrap() {
boxes.forEach( function( box, index ) {
let leftMarginStop = index * leftMargin;
const boxCoord = box.getBoundingClientRect();
let leftCoordPanel = boxCoord.left;
if ( leftCoordPanel <= leftMarginStop ) {
box.style.left = leftMarginStop + 'px';
if ( index < length ) boxes[ index + 1 ].classList.add( 'shadow' )
if ( index == 0 && boxes[ 1 ].getBoundingClientRect().left == box.offsetWidth ) boxes[ 1 ].classList.remove( 'shadow' )
} else {
box.style.left = 0;
if ( index < length ) boxes[ index + 1 ].classList.remove( 'shadow' )
}
} );
}
scroller.addEventListener( 'scroll', scrollWrap )
html,
body {
margin: 0;
height: 100%
}
.scroller {
height: 100%;
display: flex;
align-items: center;
overflow-x: auto;
overflow-y: hidden
}
.wrapper {
height: 100%;
display: flex
}
.box {
min-width: 630px;
height: 100%;
position: -webkit-sticky;
position: sticky;
left: 0 /* <-- become sticky once touching left edge */
}
.box1 {
min-width: 357px;
background: #1a1a1a url(https://cdn.pixabay.com/photo/2015/12/10/16/09/seamless-pattern-1086662__340.jpg)
}
.box2 {
min-width: 357px;
background: #333 url(https://cdn.pixabay.com/photo/2015/12/18/23/46/template-1099298__340.png)
}
.box3 {
min-width: 702px;
background: #4d4d4d url(https://cdn.pixabay.com/photo/2014/07/28/16/00/pattern-403769__340.png)
}
.box4 {
background: #666 url(https://cdn.pixabay.com/photo/2017/06/10/03/14/damask-2388884__340.png)
}
.box5 {
background: #808080 url(https://cdn.pixabay.com/photo/2015/12/12/17/34/seamless-pattern-1089797__340.png)
}
.box6 {
min-width: 357px;
background: #999 url(https://cdn.pixabay.com/photo/2016/03/06/16/23/background-1240686__340.png)
}
.box7 {
background: #b3b3b3 url(https://cdn.pixabay.com/photo/2018/04/24/05/00/backdrop-3346304__340.png)
}
.box8 {
background: #ccc url(https://cdn.pixabay.com/photo/2016/04/01/09/03/floral-1299131__340.png)
}
.shadow {
box-shadow: -10px 0px 40px rgba(0, 0, 0, 1);
}
<div class="scroller">
<div class="wrapper">
<div class="box box1"></div>
<div class="box box2"></div>
<div class="box box3"></div>
<div class="box box4"></div>
<div class="box box5"></div>
<div class="box box6"></div>
<div class="box box7"></div>
<div class="box box8"></div>
</div>
</div>
About your updated code:
the following line in your jS code:
const leftSideOfNextItem = box.nextElementSibling.getBoundingClientRect().left;
causes an error. Because, when index become 8, box.nextElementSibling can't retrieve any element. So you can change it to this:
const leftSideOfNextItem = ( index < boxes.length - 1 ) ? box.nextElementSibling.getBoundingClientRect().left : 0;
Also at the end of your JS code, the following code snippet:
if (index[4] && leftSideOfCurrent < leftMarginStop) {
console.log("helo");
}
must change to:
// when panel 5 reach left margin, left margin change from 60 to 30 to all panels
if (index == 4 && leftSideOfCurrent <= leftMarginStop) {
console.log("helo");
leftMargin = 30
}
Also you must change const leftMargin = 60; to var leftMargin = 60;
Updated code:
const boxes = Array.from(document.querySelectorAll(".box"));
const wrapper = document.querySelector(".wrapper");
var leftMargin = 60; //px
function scrollWrap(e) {
let scrollCoord = wrapper.scrollLeft; // horizontal scroll value
boxes.forEach((box, index) => {
let leftMarginStop = (index) * leftMargin; // calculation for left margin stop (60, 120, 180,...)
const boxCoord = box.getBoundingClientRect();
const leftSideOfCurrent = boxCoord.left; // coordinarion of left side of panel
const rightSideOfCurrent = boxCoord.right; // coordinarion of right side of panel
const leftSideOfNextItem = ( index < boxes.length - 1 ) ? box.nextElementSibling.getBoundingClientRect().left: 0; // coordinarion of left side of NEXT panel
box.style.position = "sticky";
box.style.left = `${leftMarginStop}px`;
// controll shadow of first element
scrollCoord > 0 ? boxes[1].classList.add("shadow") : boxes[1].classList.remove("shadow");
// controll shadow of all 0+ elements
if (leftSideOfCurrent <= leftMarginStop) { // if left side of pannel is less than margin 60, 120, 180,...
box.nextElementSibling.classList.add("shadow");
}
// controll removal of shadow of all 0+ elements
if (leftSideOfNextItem === rightSideOfCurrent) {
box.nextElementSibling.classList.remove("shadow");
}
// when panel 5 reach left margin, left margin change from 60 to 30 to all panels
if (index == 4 && leftSideOfCurrent <= leftMarginStop) {
console.log("helo");
leftMargin = 30
}
});
}
wrapper.addEventListener("scroll", scrollWrap);
body {
margin: 0;
padding: 0;
}
.wrapper, .box0, .box1, .box2, .box3, .box4, .box5, .box6, .box7 {
position: sticky;
height: 750px;
z-index: 1;
}
.wrapper {
width: 1442px;
border-right: 1px solid #f2f2f2;
border-bottom: 1px solid #f2f2f2;
display: flex;
overflow: scroll;
}
.wrapper .box0 {
min-width: 357px;
background-color: #1a1a1a;
}
.wrapper .box1 {
min-width: 357px;
background-color: #333;
}
.wrapper .box2 {
min-width: 702px;
background-color: #4d4d4d;
}
.wrapper .box3 {
min-width: 630px;
background-color: #666;
}
.wrapper .box4 {
min-width: 630px;
background-color: #808080;
}
.wrapper .box5 {
min-width: 357px;
background-color: #999;
}
.wrapper .box6 {
min-width: 630px;
background-color: #b3b3b3;
}
.wrapper .box7 {
min-width: 630px;
background-color: #ccc;
}
.shadow {
box-shadow: -4px 0px 40px rgba(0, 0, 0, 1.2);
-webkit-transition: box-shadow 0.2s cubic-bezier(0.4,-0.01, 0, 0.98);
-moz-transition: box-shadow 0.2s cubic-bezier(0.4,-0.01, 0, 0.98);
-o-transition: box-shadow 0.2s cubic-bezier(0.4,-0.01, 0, 0.98);
transition: box-shadow 0.2s cubic-bezier(0.4,-0.01, 0, 0.98);
}
/* To make the console visible. */
.box0 {
height: 700px;
)
<div class="wrapper">
<div class="box box0"></div>
<div class="box box1"></div>
<div class="box box2"></div>
<div class="box box3"></div>
<div class="box box4"></div>
<div class="box box5"></div>
<div class="box box6"></div>
<div class="box box7"></div>
</div>
This was helpful. I know for error but could not fix it. I have set let leftMargin = 60; i use let instead var.
I am working on the margins, if the 5th panel reaches the left margin the margin of all panels get 30px. I did it also for reverse:
if (index > 4 && leftSideOfCurrent <= leftMarginStop) {
leftMargin = 30;
} else if (index < 5 && leftSideOfCurrent > leftMarginStop) {
leftMargin = 60;
}
But now when 5th panel reaches left margin, the panels less than 5 get EACH transitioned seperately instead of all, but when the 5th element is no longer in left margin, all gets transitioned at same time. Why is it like that? I do not understand. Can you explain please?
I want to make a draggle splitter between 2 panels. The following is a working version.
Now, I want to make the width of handle as thin as possible (less than 0.1px?), so there is no way to make the width (appear) smaller than 1px?
Additionally, when the splitter is thin, it is hard to select by the mouse. Is there a way to make a splitter easy to grab?
Taking JSBin as example, how did they manage to realise the splitters among the panels?
(function($) {
$.fn.drags = function(opt) {
opt = $.extend({
handle: "",
cursor: "ew-resize",
min: 10
}, opt);
if (opt.handle === "") {
var $el = this;
} else {
var $el = this.find(opt.handle);
}
var priorCursor = $('body').css('cursor');
return $el.css('cursor', opt.cursor).on("mousedown", function(e) {
priorCursor = $('body').css('cursor');
$('body').css('cursor', opt.cursor);
if (opt.handle === "") {
var $drag = $(this).addClass('draggable');
} else {
var $drag = $(this).addClass('active-handle').parent().addClass('draggable');
}
var z_idx = $drag.css('z-index'),
drg_h = $drag.outerHeight(),
drg_w = $drag.outerWidth(),
pos_y = $drag.offset().top + drg_h - e.pageY,
pos_x = $drag.offset().left + drg_w - e.pageX;
var mouseMove = function(e) {
var prev = $('.draggable').prev();
var next = $('.draggable').next();
var total = prev.outerWidth() + next.outerWidth();
var totalPercentage = parseFloat(prev.css('flex')) + parseFloat(next.css('flex'));
var offset = prev.offset();
if(offset){
var leftPercentage = ((e.pageX - offset.left - drg_w / 2) / total) * totalPercentage;
var rightPercentage = totalPercentage - leftPercentage;
if (leftPercentage * 100 < opt.min || rightPercentage * 100 < opt.min) {
return;
}
prev.css('flex', leftPercentage.toString());
next.css('flex', rightPercentage.toString());
}
}
$drag.css('z-index', 1000).parent().on("mousemove", mouseMove).on("mouseup", function() {
$(this).off("mousemove", mouseMove).off("mouseup");
$('body').css('cursor', priorCursor);
$('.draggable').removeClass('draggable').css('z-index', z_idx);
});
e.preventDefault(); // disable selection
});
}
})(jQuery);
$('.handle').drags();
.flex-box {
display: flex;
width: 100%;
margin: 0;
height: 300px;
}
.flex-box .col {
border: 1px solid grey;
flex: 0.33;
padding: 12px;
overflow-y: auto;
overflow-x: hide;
}
.handle {
width: 1px;
text-align: center;
background: grey;
transition: all ease-in 0.1s;
}
.draggable {
background: grey;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="flex-box">
<div class="col">
<p>Pellentesque ...</p>
</div>
<div class="handle"></div>
<div class="col">
<p>Pellentesque ...</p>
</div>
</div>
If you'd like the handle to appear thinner try applying a negative value to the right "col" e.g. margin-left: -2px; so it overlaps the left "col" border on the left of it. I don't think you can make the width "appear" as 0.1px. Firefox is the only browser that renders such value. (https://css-tricks.com/forums/topic/0-1px-borders/)
.flex-box .col:last-child {
margin-left: -2px;
}
//raise handle layer to top
.handle {
.....
z-index: 9999;
}
Hope this helps...
*Edit:
This is the closest I could get to your request:
.flex-box {
display: flex;
width: 100%;
margin: 0;
height: 300px;
}
.flex-box .col {
border: 1px solid grey;
flex: 0.33;
padding: 12px;
overflow-y: auto;
overflow-x: hide;
}
.flex-box .col:last-child {
margin-left: -6px;
}
.handle {
width: 5px;
text-align: center;
transition: all ease-in 0.1s;
z-index: 999;
overflow: visible;
}
.handle-inner{
width: 5px;
height: 100%;
position: relative;
margin-left: -10px;
}
.draggable {
background: grey;
}
Jsbin :
https://jsbin.com/nupefekuhu/edit?html,css,js,output
How can I remove mouse interaction over the slider but keep the function where it decreases when I click the button and change color? (only in jquery mobile and jquery)
So if I press on the slider nothing should happen, only when I press the button.
Can also the slider decrease in the opposite direction? From left to right?
This is the code:
HTML:
<div id='slider' class='sliderBar'></div>
<button>Remove 10%</button>
CSS:
html, body {
height:100%;
width:100%;
margin:0;
padding:0;
}
#slider {
height:20px;
max-height:20px;
}
.sliderBar-progress {
background:rgb(0, 255, 0);
transition-duration: 0.5s;
-webkit-transition-duration: 0.5s; /* for Safari */;
}
JS:
$('#slider').sliderBar({
start: 100,
onChange: function (val) {
var red = 0,
green = 0;
if (val >= 50) {
red = 255 - Math.round(((val - 50) / 50) * 255);
green = 255;
} else {
red = 255;
green = Math.round(((val) / 50) * 255);
}
$('.sliderBar-progress').css({
background: "rgb(" + red + "," + green + ",0)"
});
}
});
$('button').on('click', function () {
$('#slider').setsliderBar($('#slider').getsliderBar()-10, true);
});
Thank you!
What you are really looking for is a progress bar, not a slider. In your example you appear to be using a third party plugin for the slider; so eliminating mouse interaction and getting right to left functionality would involve changing the plugin code.
Alternatively, it is pretty easy to roll your own with just the functionality you need.
Here is a DEMO
For markup you just need 2 divs:
<div id="slider" class="progressBar">
<div class="progress"></div>
</div>
Then 2 CSS rules to make the track and bar look the way you want (tweak to your taste). Setting the position of the progress div to right: 0 will make it go from left to right.
.progressBar{
position: relative;
box-sizing: border-box;
box-shadow: 1px 1px 3px #777 inset ;
-webkit-box-shadow: 1px 1px 6px #777 inset;
height: 24px;
max-height: 24px;
overflow: hidden;
width: 100%;
border: 1px solid rgb(193, 193, 193);
background-color: rgb(224, 224, 224);
border-radius: 6px;
}
.progress {
position: absolute;
box-sizing: border-box;
box-shadow: inset 0px 0 5px 0 #777;
-webkit-box-shadow: inset 0px 0 5px 0 #777;
right: 0px;
height: 24px;
margin-top: 0px;
background-color: orange;
border-top-right-radius: 6px;
border-bottom-right-radius: 6px;
transition-duration: 0.5s;
-webkit-transition-duration: 0.5s; /* for Safari */;
}
For getting and setting the progress/color, add these functions:
function GetProgress(){
var val = $("#slider .progress").outerWidth();
var tot = $("#slider").outerWidth();
if (tot <= 0) return 0;
return Math.floor(val * 100 / tot);
}
function SetProgress(val){
if (val < 0) val = 0;
if (val > 100) vall = 100;
var color = GetColorForVal(val);
$("#slider .progress").css({"background": color, "width": val + "%"});
}
function GetColorForVal(val){
var red = 0,
green = 0;
if (val >= 50) {
red = 255 - Math.round(((val - 50) / 50) * 255);
green = 255;
} else {
red = 255;
green = Math.round(((val) / 50) * 255);
}
return "rgb(" + red + "," + green + ",0)";
}
You can then get and set progress by calling these functions:
$('#subtract').on('click', function () {
var curVal = GetProgress() - 10;
SetProgress(curVal);
});
UPDATE: There can be rounding errors calculating current width, so instead we can read it from the style:
function GetProgress(){
var curWid = $("#slider .progress")[0].style.width || 100;
return parseInt(curWid);
}
Updated DEMO