Scroll function on hover won't work unless resizing screen - javascript

I miss 1% to finish my script, I just don't know how to do it :D
When you hover over the target to the left, you can see the image will scroll. But after clicking on a new image it won't. I then have to resize the window to make it work again. How to fix that? Below is my code but for a working example, here's a CodePen
(function($) {
// virables
var layoutContainer = '.container';
var layoutTarget = '#target';
var layoutTargetIMG = '#target img';
var layoutIMG = '.container .gallery .item img';
var layoutIMGFirst = '.container .gallery .item:first-child img';
// Add first image to target
$(layoutIMGFirst).clone().appendTo(layoutTarget);
// Add image to target when click on gallery image
$(layoutIMG).click(function() {
$(this).closest(layoutContainer).find(layoutTarget).empty();
$(this).clone().appendTo(
$(this).closest(layoutContainer).find(layoutTarget)
);
});
// Image scroll on hover
// This won't work after clicking on an image unless resizing the browser
$(window).resize(function() {
// If i remove this it won't work on the start image.
// Any other solution?
setTimeout(function() {
$('#target img').each(function() {
var itemHeight = $('#target').outerHeight();
var imgHeight = $(this).outerHeight();
// Work out what percentage the image is of the item and remove 100% from that
var topHeight = (imgHeight / itemHeight) * 100 - 100;
//Make the animation speed proptional to that ratio
var animationSpeed = (imgHeight / itemHeight) / 1; //change 2 to tweak the speed
$(this).css({
transition: 'all ease ' + animationSpeed + 's'
});
$(this).mouseleave(function() {
$(this).css({
top: '0'
});
})
// The 'top' property of the image needs
// to be set as as a percentage of the parent
$(this).mouseenter(function(e) {
$(this).css({
top: '-' + topHeight + '%',
});
})
});
}, 200);
});
$(document).ready(function() {
setTimeout(function() { // Add delay after resize so function will load
$(window).triggerHandler('resize');
}, 200);
});
})(jQuery);
.container {
display: flex;
flex-flow: row wrap;
align-items: flex-start;
margin-left: -40px;
max-width: 1000px;
background: lightblue;
padding: 20px;
.column {
flex: 1;
min-width: 30%;
margin-left: 40px;
.target {
height: 400px;
background: pink;
position: relative;
overflow: hidden;
img {
position: absolute;
top: 0;
left: 0;
width: 100%;
}
}
.cta {
display: flex;
a {
background: lightgreen;
width: 50%;
padding: 16px 8px;
;
text-align: center;
justify-content: center;
text-decoration: none;
&:last-child {
background: orange;
}
}
}
.gallery {
display: flex;
flex-flow: row wrap;
margin-left: -4px;
.item {
flex: 1;
margin-left: 4px;
position: relative;
overflow: hidden;
&::before {
content: '';
padding-top: 80%;
display: block;
}
img {
position: absolute;
min-width: 100%;
min-height: 100%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
cursor: pointer;
}
}
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
<div class="column">
<div id="target" class="target"></div>
<div class="cta">
SE DEMO
KØB LAYOUT
</div>
</div>
<div class="column">
<div class="gallery">
<div class="item">
<img src="https://picsum.photos/600/1200" alt="">
</div>
<div class="item">
<img src="https://picsum.photos/500/1600" alt="">
</div>
<div class="item">
<img src="https://picsum.photos/400/2000" alt="">
</div>
</div>
</div>
</div>

Just change this
$(layoutIMG).click(function() {
$(this).closest(layoutContainer).find(layoutTarget).empty();
$(this).clone().appendTo(
$(this).closest(layoutContainer).find(layoutTarget)
);
});
to
$(layoutIMG).click(function() {
$(this).closest(layoutContainer).find(layoutTarget).empty();
$(this).clone().appendTo(
$(this).closest(layoutContainer).find(layoutTarget)
);
$(window).triggerHandler('resize'); // added this line
});

Related

position sticky using javascript makes div goes outside the parent

I have a menu on the left that I want to be always sticky, I'm using javascript for that for IE11 support.
The problem I'm having is that the right div goes to the left when it's sticky and doesn't keep it's position, the second issue is that the .content div width grows when the right div is sticky.
For the javascript part, I don't know how to make the right div to stop when it reaches the footer.
EDIT:
I managed to solve the second issue, the code is updated, I also tried to add a right value for the right div so it sticks in its initial vertical position, but that's not working because it changes when the screen gets resized.
How can I solve this?
Edit 2:
For the javascript issue I found this post which helped me resolve my issue:
Make sticky/fixed element stop at footer
var sticky = document.getElementsByClassName("sticky-element")[0];
var stickyAnchor = sticky.parentNode;
var state = false;
function getAnchorOffset() {
return stickyAnchor.getBoundingClientRect().top;
}
updateSticky = function (e) {
if (!state && (getAnchorOffset() < 0)) {
sticky.classList.add("is-sticky");
sticky.parentElement.classList.add("has-sticky");
state = true;
} else if (state && (getAnchorOffset() >=0 )) {
sticky.classList.remove("is-sticky");
sticky.parentElement.classList.remove("has-sticky");
state = false;
}
}
window.addEventListener('scroll', updateSticky);
window.addEventListener('resize', updateSticky);
updateSticky();
.main-wrapper {
margin: 48px 48px 0 48px;
max-width: 1366px;
}
.wrapper {
width: 100%;
display: flex;
justify-content: space-between;
position: relative;
}
.wrapper.has-sticky .content{
margin-right: calc(199px + 72px);
}
.content {
flex: 0 1 1040px;
width: calc(1040px - 72px);
min-width: 1%;
margin-right: 72px;
height: 1200px;
background-color: #e6e9f0;
}
.nav-menu {
position: static;
flex: 0 1 199px;
width: 199px;
min-width: 199px;
color: white;
height: 300px;
background-color: #04246a;
right: 10%;
}
footer {
background-color: yellow;
height: 300px;
margin-top: 50px;
}
.is-sticky {
top: 0;
position: fixed;
}
<div class="main-wrapper">
<div class="wrapper">
<div class="content">
Main content
</div>
<div class="nav-menu sticky-element">
<nav>
Side content
</nav>
</div>
</div>
<footer>
Footer content
</footer>
</div>
Are you looking for this?
The problem on your code is that whenever you set the position of your right div to fixed it then looks for its relative parent and jumps to the upper left position inside the parent. In your case, the parent div was the .wrapper, that's why it keeps on jumping to the left side and overlaps your main content div.
I added a parent container for the .nav-menu so it will still be in the same position when scrolling. With this, your .nav-menu element won't be using the .wrapper as its main parent. This will create a smooth scroll without noticing any change in position.
Happy coding!
var sticky = document.getElementsByClassName('sticky-element')[0];
var stickyAnchor = sticky.parentNode;
var state = false;
function getAnchorOffset() {
return stickyAnchor.getBoundingClientRect().top;
}
updateSticky = function (e) {
if (!state && getAnchorOffset() < 0) {
sticky.classList.add('is-sticky');
state = true;
} else if (state && getAnchorOffset() >= 0) {
sticky.classList.remove('is-sticky');
state = false;
}
};
window.addEventListener('scroll', updateSticky);
window.addEventListener('resize', updateSticky);
updateSticky();
.main-wrapper {
margin: 48px 48px 0 48px;
max-width: 80%;
}
.wrapper {
width: 100%;
display: flex;
justify-content: space-between;
position: relative;
}
.content {
flex: 0 1 80%;
width: calc(80% - 24px);
min-width: 1%;
margin-right: 24px;
height: 1200px;
background-color: #e6e9f0;
}
.nav-container {
flex-grow: 1;
width: 20%;
min-width: 200px;
position: relative;
display: block;
}
.nav-menu {
color: white;
width: 100%;
min-width: inherit;
height: 300px;
background-color: #04246a;
}
.is-sticky {
top: 0;
position: fixed;
width: calc(20% - 97px);
}
<div class="main-wrapper">
<div class="wrapper">
<div class="content">Main content</div>
<div class="nav-container">
<div class="nav-menu sticky-element">
<nav>Side content</nav>
</div>
</div>
</div>
</div>
var sticky = document.getElementsByClassName("sticky-element")[0];
var stickyAnchor = sticky.parentNode;
var state = false;
function getAnchorOffset() {
return stickyAnchor.getBoundingClientRect().top;
}
updateSticky = function (e) {
if (!state && (getAnchorOffset() < 0)) {
sticky.classList.add("is-sticky");
state = true;
} else if (state && (getAnchorOffset() >=0 )) {
sticky.classList.remove("is-sticky");
state = false;
}
}
window.addEventListener('scroll', updateSticky);
window.addEventListener('resize', updateSticky);
updateSticky();
.main-wrapper {
margin: 48px 48px 0 48px;
max-width: 80%;
}
.wrapper {
width: 100%;
display: flex;
justify-content: space-between;
position: relative;
}
.content {
flex: 0 1 80%;
width: calc(80% - 24px);
min-width: 1%;
margin-right: 24px;
height: 1200px;
background-color: #e6e9f0;
}
.nav-menu {
position: static;
flex: 0 1 20%;
width: 20%;
min-width: 20%;
color: white;
height: 300px;
background-color: #04246a;
}
.is-sticky {
top: 0;
right:5%;
position: fixed;
}
<div class="main-wrapper">
<div class="wrapper">
<div class="content">
Main content
</div>
<div class="nav-menu sticky-element">
<nav>
Side content
</nav>
</div>
</div>
</div>

How can I trigger on mouse movement Variable font in different section?

I was looking to trigger different sections with a variable font based on my mouse movement.
For the first section, everything looks great, but when I tried to trigger the second section, it does not work as I expected since is connected to the first one I guess.
I would need to make the section working independently and in the correct way (to have an idea see section one how react in debug mode)
I was wondering what I have to modify in my Javascript code to make my snippet work with all the sections I want, working independently with their respective variable font interaction. Any ideas?
$('.square').on('mousemove', function(e) {
var x = e.pageX - $(this).offset().left;
var y = e.pageY;
var $tlSquare = $('.division--top.division--left');
var $trSquare = $('.division--top.division--right');
var $blSquare = $('.division--bottom.division--left');
var $brSquare = $('.division--bottom.division--right');
var squareWidth = $(this).width(),
squareHeight = $(this).height();
$tlSquare.width(x).height(y);
$trSquare.width(squareWidth - x).height(y);
$blSquare.width(x).height(squareHeight - y);
$brSquare.width(squareWidth - x).height(squareHeight - y);
stretchLetter(false);
});
stretchLetter(false);
$('.square').on('mouseleave', function() {
$('.division').width('50%').height('50%');
$('.letter').css('transform', '');
stretchLetter(false);
});
function stretchLetter(animation) {
$('.letter').each(function() {
var parentWidth = $(this).parent().width();
var parentHeight = $(this).parent().height();
var thisWidth = $(this).width();
var thisHeight = $(this).height();
var widthPercent = parentWidth / thisWidth;
var heightPercent = parentHeight / thisHeight;
var timing = animation == true ? .5 : 0;
TweenMax.to($(this), timing, {
scaleX: widthPercent,
scaleY: heightPercent
})
//$(this).css('transform', 'scalex('+ widthPercent +') scaley('+ heightPercent +')');
});
}
body,
html {
margin: 0;
padding: 0;
font-weight: bold;
font-family: helvetica;
}
section {
height: 200px;
background: blue;
color: white;
font-size: 28px;
}
.wrapper {
display: flex;
justify-content: center;
/*justify-content: flex-end;*/
width: 100%;
height: 100vh;
//background-color: blue;
overflow: hidden;
}
.square {
display: flex;
flex-wrap: wrap;
width: 100vh;
height: 100vh;
background-color: black;
}
.square-2 {
display: flex;
flex-wrap: wrap;
width: 100vh;
height: 100vh;
background-color: yellow;
}
.division {
//display: flex;
//align-items: center;
//justify-content: center;
width: 50%;
height: 50%;
//background-color: red;
//border: 1px solid white;
box-sizing: border-box;
}
.letter {
cursor: -webkit-grab;
cursor: grab;
}
.letter {
display: inline-block;
font-size: 50vh;
margin: 0;
padding: 0;
line-height: .8;
transform-origin: top left;
color: white;
}
/* .division:nth-child(1){
background-color: blue;
}
.division:nth-child(2){
background-color: red;
}
.division:nth-child(3){
background-color: green;
}
.division:nth-child(4){
background-color: orange;
} */
.circle {
width: 100%;
height: 100%;
border-radius: 50%;
border: 1px solid white;
background-color: blue;
box-sizing: border-box;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section>SECTION-01</section>
<main>
<div class="wrapper">
<div class="square">
<div class="division division--top division--left">
<div class="letter">L</div>
</div>
<div class="division division--top division--right">
<div class="letter">A</div>
</div>
<div class="division division--bottom division--left">
<div class="letter">S</div>
</div>
<div class="division division--bottom division--right">
<div class="letter">T</div>
</div>
</div>
</main>
<section>SECTION-02</section>
<div class="wrapper">
<div class="square">
<div class="division division--top division--left">
<div class="letter">F</div>
</div>
<div class="division division--top division--right">
<div class="letter">A</div>
</div>
<div class="division division--bottom division--left">
<div class="letter">S</div>
</div>
<div class="division division--bottom division--right">
<div class="letter">T</div>
</div>
</div>
</main>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.0.2/TweenMax.min.js"></script>
https://jsfiddle.net/CAT999/ohaf61qp/5/
See working FIDDLE
You had to change the y variable because you were calculating with the offset top of the mouse position inn the document. This is always bigger than the element, so you have to extract the offset top of the element you were scrolling on, to get the right value.
var y = e.pageY - $(this).offset().top;

Custom jQuery carousel transition bug

I am working on a custom image carousel, with jQuery and CSS. I am trying to avoid using a multiple-features carousel plugin download from Github, for performance reasons.
My aim is to obtain a vertical transition, like the one on www.pcgarage.ro, but without using the plugin they (might) have used. For this purpose, I have written:
var $elm = $('.slider'),
$slidesContainer = $elm.find('.slider-container'),
slides = $slidesContainer.children('a'),
slidesCount = slides.length,
slideHeight = $(slides[0]).find('img').outerHeight(false);
//Set slide height
$(slides).css('height', slideHeight);
// Append bullets
for (var i = 0; i < slidesCount; i++) {
var bullets = '' + i + '';
if (i == 0) {
// active bullet
var bullets = '' + i + '';
// active slide
$(slides[0]).addClass('active');
}
$('.slider-nav').append(bullets);
}
// Set (initial) z-index for each slide
var setZindex = function() {
for (var i = 0; i < slidesCount; i++) {
$(slides[i]).css('z-index', slidesCount - i);
}
}
setZindex();
$('.slider-nav a').on('click', function() {
activeIdx = $(this).text();
$('.slider-nav a').removeClass('activeSlide');
$(this).addClass('activeSlide');
setActiveSlide();
slideUpDown();
});
var setActiveSlide = function() {
$(slides).removeClass('active');
$(slides[activeIdx]).addClass('active');
}
var slideUpDown = function() {
// set top property for all the slides
$(slides).css('top', slideHeight);
// then animate to the next slide
$(slides[activeIdx]).animate({
'top': 0
});
}
body {
margin: 0;
padding: 0;
}
body * {
box-sizing: border-box;
}
.container {
max-width: 1200px;
margin: 0 auto;
}
.slider {
width: 100%;
height: 300px;
position: relative;
overflow: hidden;
}
.slider .slider-nav {
position: absolute;
left: 10px;
bottom: 10px;
z-index: 30;
}
.slider .slider-nav a {
display: block;
float: left;
width: 10px;
height: 10px;
border-radius: 50%;
margin-right: 3px;
text-indent: -9999px;
background: #fff;
}
.slider .slider-nav a.activeSlide {
background: transparent;
border: 2px solid #fff;
}
.slider .slider-container {
width: 100%;
text-align: center;
}
.slider .slider-container a {
display: block;
position: absolute;
top: 0;
left: 0;
right: 0;
}
.slider .slider-container img {
transform: translateX(-50%);
margin-left: 50%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<div class="container">
<div class="slider slider-homepage">
<div class="slider-nav"></div>
<div class="slider-container">
<a href="#">
<img src="https://picsum.photos/1200/300/?gravity=east" alt="">
</a>
<a href="#">
<img src="https://picsum.photos/1200/300/?gravity=south" alt="">
</a>
<a href="#">
<img src="https://picsum.photos/1200/300/?gravity=north" alt="">
</a>
</div>
</div>
</div>
The problem with my code is the (obvious) white screen that accompanies every transition, whose cause I do not understand.
Where is my mistake?
I have added some variable and function to fix this issue kindly check the script.
var $elm = $('.slider'),
$slidesContainer = $elm.find('.slider-container'),
slides = $slidesContainer.children('a'),
slidesCount = slides.length,
slideHeight = $(slides[0]).find('img').outerHeight(false);
//Set slide height
$(slides).css('height', slideHeight);
// Append bullets
for (var i = 0; i < slidesCount; i++) {
var bullets = '' + i + '';
if (i == 0) {
// active bullet
var bullets = '' + i + '';
// active slide
$(slides[0]).addClass('active');
}
$('.slider-nav').append(bullets);
}
// Set (initial) z-index for each slide
var setZindex = function () {
for (var i = 0; i < slidesCount; i++) {
$(slides[i]).css('z-index', slidesCount - i);
}
}
setZindex();
var displayImageBeforeClick = null;
$('.slider-nav a').on('click', function () {
displayImageBeforeClick = $(".slider-container .active");
activeIdx = $(this).text();
if($(slides[activeIdx]).hasClass("active")){ return false; }
$('.slider-nav a').removeClass('activeSlide');
$(this).addClass('activeSlide');
setActiveSlide();
slideUpDown();
});
var setActiveSlide = function () {
$(slides).removeClass('active');
$(slides[activeIdx]).addClass('active');
}
var slideUpDown = function () {
// set top property for all the slides
$(slides).not(displayImageBeforeClick).css('top', slideHeight);
// then animate to the next slide
$(slides[activeIdx]).animate({
'top': 0
});
$(displayImageBeforeClick).animate({
'top': "-100%"
});
}
body {
margin: 0;
padding: 0;
}
body * {
box-sizing: border-box;
}
.container {
max-width: 1200px;
margin: 0 auto;
}
.slider {
width: 100%;
height: 300px;
position: relative;
overflow: hidden;
}
.slider .slider-nav {
position: absolute;
left: 10px;
bottom: 10px;
z-index: 30;
}
.slider .slider-nav a {
display: block;
float: left;
width: 10px;
height: 10px;
border-radius: 50%;
margin-right: 3px;
text-indent: -9999px;
background: #fff;
}
.slider .slider-nav a.activeSlide {
background: transparent;
border: 2px solid #fff;
}
.slider .slider-container {
width: 100%;
text-align: center;
}
.slider .slider-container a {
display: block;
position: absolute;
top: 0;
left: 0;
right: 0;
}
.slider .slider-container img {
transform: translateX(-50%);
margin-left: 50%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<div class="container">
<div class="slider slider-homepage">
<div class="slider-nav"></div>
<div class="slider-container">
<a href="#">
<img src="https://picsum.photos/1200/300/?gravity=east" alt="">
</a>
<a href="#">
<img src="https://picsum.photos/1200/300/?gravity=south" alt="">
</a>
<a href="#">
<img src="https://picsum.photos/1200/300/?gravity=north" alt="">
</a>
</div>
</div>
</div>
Add Transition to your ".slider .slider-container a" with a transition-duration and transition-timing-function.... for reference you can see https://www.w3schools.com/css/css3_transitions.asp

Draggable split-pane windows in flexbox can't get past child elements [duplicate]

This question already has answers here:
Why don't flex items shrink past content size?
(5 answers)
Closed 3 years ago.
I implemented my own split-pane with HTML/JS/CSS Flexbox.
I'm having trouble with the splitter in the following case- one of the panels has a fixed size (in px), and the other one is set to grow (flex-grow: 1).
In case the other panel has children with size, it won't scroll to the end. It gets stuck at the size of the children.
Can this be fixed with CSS on the split-pane panels but not on the children?
It's very important for me to use flex as I want to maintain responsiveness of my application, and want to avoid fixed sizes wherever I can.
This is a JSFiddle sample
of my question.
Code snippet given below. Thanks!
function startDrag() {
glass.style = 'display: block;';
glass.addEventListener('mousemove', drag, false);
}
function endDrag() {
glass.removeEventListener('mousemove', drag, false);
glass.style = '';
}
function drag(event) {
var splitter = getSplitter();
var panel = document.getElementById('c2');
var currentWidth = panel.offsetWidth;
var currentLeft = panel.offsetLeft;
panel.style.width = (currentWidth - (event.clientX - currentLeft)) + "px";
}
function getSplitter() {
return document.getElementById('splitter');
}
var con = document.getElementById('container');
var splitter = document.createElement('div');
var glass = document.getElementById('glass');
splitter.className = 'splitter';
splitter.id = 'splitter';
con.insertBefore(splitter, con.lastElementChild);
splitter.addEventListener('mousedown', startDrag, false);
glass.addEventListener('mouseup', endDrag, false);
.container {
display: flex;
border: 1px solid;
width: 500px;
height: 300px;
position: absolute;
}
.c1 {
background-color: blue;
flex: 1;
height: 100%;
}
.c2 {
background-color: green;
width: 150px;
}
.splitter {
width: 20px;
cursor: col-resize;
}
.glass {
height: 100%;
width: 100%;
cursor: col-resize;
display: none;
position: absolute;
}
.grandchild {
background-color: red;
width: 50px;
height: 50px;
}
<div id="container" class="container">
<div id="glass" class="glass"></div>
<div class="c1">
<div class="grandchild"></div>
</div>
<div id="c2" class="c2"></div>
</div>
In case the other panel has children with size, it won't scroll to the end. It gets stuck at the size of the children.
This is because an initial setting of a flex container is min-width: auto on the flex items. This means that a flex item, by default, cannot be smaller than the size of its content.
Can this be fixed with CSS on the split-pane panels but not on the children?
Yes. Override the default with min-width: 0 or with any overflow other than visible:
.c1 {
background-color: blue;
flex: 1;
height: 100%;
overflow: hidden; /* or min-width: 0 */
}
revised fiddle
function startDrag() {
glass.style = 'display: block;';
glass.addEventListener('mousemove', drag, false);
}
function endDrag() {
glass.removeEventListener('mousemove', drag, false);
glass.style = '';
}
function drag(event) {
var splitter = getSplitter();
var panel = document.getElementById('c2');
var currentWidth = panel.offsetWidth;
var currentLeft = panel.offsetLeft;
panel.style.width = (currentWidth - (event.clientX - currentLeft)) + "px";
}
function getSplitter() {
return document.getElementById('splitter');
}
var con = document.getElementById('container');
var splitter = document.createElement('div');
var glass = document.getElementById('glass');
splitter.className = 'splitter';
splitter.id = 'splitter';
con.insertBefore(splitter, con.lastElementChild);
splitter.addEventListener('mousedown', startDrag, false);
glass.addEventListener('mouseup', endDrag, false);
.container {
display: flex;
border: 1px solid;
width: 500px;
height: 300px;
position: absolute;
}
.c1 {
background-color: blue;
flex: 1;
height: 100%;
overflow: hidden;
}
.c2 {
background-color: green;
width: 150px;
}
.splitter {
width: 20px;
cursor: col-resize;
}
.glass {
height: 100%;
width: 100%;
cursor: col-resize;
display: none;
position: absolute;
}
.grandchild {
background-color: red;
width: 50px;
height: 50px;
}
<div id="container" class="container">
<div id="glass" class="glass"></div>
<div class="c1">
<div class="grandchild"></div>
</div>
<div id="c2" class="c2"></div>
</div>
It gets stuck at the size of the children
This is expected behavior when using a flexbox. I guess if you want to scroll to the end then you can use position: absolute for the grandchild relative to c1:
.grandchild {
background-color: red;
width: 50px;
height: 50px;
position: absolute;
top: 0;
left: 0;
}
Give overflow: hidden to c1 too:
.c1 {
background-color: blue;
flex: 1;
height: 100%;
position: relative;
overflow: hidden;
}
Cheers!
function startDrag() {
glass.style = 'display: block;';
glass.addEventListener('mousemove', drag, false);
}
function endDrag() {
glass.removeEventListener('mousemove', drag, false);
glass.style = '';
}
function drag(event) {
var splitter = getSplitter();
var panel = document.getElementById('c2');
var currentWidth = panel.offsetWidth;
var currentLeft = panel.offsetLeft;
panel.style.width = (currentWidth - (event.clientX - currentLeft)) + "px";
}
function getSplitter() {
return document.getElementById('splitter');
}
var con = document.getElementById('container');
var splitter = document.createElement('div');
var glass = document.getElementById('glass');
splitter.className = 'splitter';
splitter.id = 'splitter';
con.insertBefore(splitter, con.lastElementChild);
splitter.addEventListener('mousedown', startDrag, false);
glass.addEventListener('mouseup', endDrag, false);
.container {
display: flex;
border: 1px solid;
width: 500px;
height: 300px;
position: absolute;
}
.c1 {
background-color: blue;
flex: 1;
height: 100%;
position: relative;
overflow: hidden;
}
.c2 {
background-color: green;
width: 150px;
}
.splitter {
width: 20px;
cursor: col-resize;
}
.glass {
height: 100%;
width: 100%;
cursor: col-resize;
display: none;
position: absolute;
}
.grandchild {
background-color: red;
width: 50px;
height: 50px;
position: absolute;
top: 0;
left: 0;
}
<div id="container" class="container">
<div id="glass" class="glass"></div>
<div class="c1">
<div class="grandchild"></div>
</div>
<div id="c2" class="c2"></div>
</div>
Solution:
So I guess your strategy should be to use an absolute grandchild that fills the whole side-panel, and then put the content inside like:
<div class="grandchild">
<div class="content"></div>
</div>
and change these styles:
.grandchild {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.grandchild .content{
background-color: red;
width: 50px;
height: 50px;
}
Example below:
function startDrag() {
glass.style = 'display: block;';
glass.addEventListener('mousemove', drag, false);
}
function endDrag() {
glass.removeEventListener('mousemove', drag, false);
glass.style = '';
}
function drag(event) {
var splitter = getSplitter();
var panel = document.getElementById('c2');
var currentWidth = panel.offsetWidth;
var currentLeft = panel.offsetLeft;
panel.style.width = (currentWidth - (event.clientX - currentLeft)) + "px";
}
function getSplitter() {
return document.getElementById('splitter');
}
var con = document.getElementById('container');
var splitter = document.createElement('div');
var glass = document.getElementById('glass');
splitter.className = 'splitter';
splitter.id = 'splitter';
con.insertBefore(splitter, con.lastElementChild);
splitter.addEventListener('mousedown', startDrag, false);
glass.addEventListener('mouseup', endDrag, false);
.container {
display: flex;
border: 1px solid;
width: 500px;
height: 300px;
position: absolute;
}
.c1 {
background-color: blue;
flex: 1;
height: 100%;
position: relative;
overflow: hidden;
}
.c2 {
background-color: green;
width: 150px;
}
.splitter {
width: 20px;
cursor: col-resize;
}
.glass {
height: 100%;
width: 100%;
cursor: col-resize;
display: none;
position: absolute;
}
.grandchild {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.grandchild .content{
background-color: red;
width: 50px;
height: 50px;
}
<div id="container" class="container">
<div id="glass" class="glass"></div>
<div class="c1">
<div class="grandchild">
<div class="content"></div>
</div>
</div>
<div id="c2" class="c2"></div>
</div>

Navigation buttons with a CSS slider

I have a CSS slider that works for the most part except for two things I cannot figure out. The first being, how to get my slider navigation buttons to work the way I am after. Right now, if you click on one, my addClass adds .active to all of the buttons instead of only the one clicked on. Along with that I cannot figure out how to associate the slider position with the navigation menu. What I mean is if the user does not click any of the buttons I still want the buttons to show which slide is active.
MY second issue is whenever the buttons are clicked it stops the slide show.
What am I doing wrong in my attempts?
Off-topic, but would it be difficult to transition what I have now to fade in the slides rather than sliding them?
$('.control-button').click(function() {
button = $(this).attr('id');
id = button.replace('slide', '');
pos = (id - 1) * 100;
$('div#slider figure').css('animation-play-state', 'paused');
$('div#slider figure').removeClass('figure2');
$('.control-button').addClass('active');
posStr = '-' + pos + '%';
$('.figure').css('left', posStr);
});
$('img').click(function() {
$('div#inner').css('left', '0px');
$('div#slider figure').addClass('figure2');
$('div#slider figure').css('animation-play-state', 'running');
})
div#slider {
width: 100%;
overflow: hidden;
}
div#slider .figure {
position: relative;
width: 400%;
margin: 0;
padding: 0;
font-size: 0;
text-align: left;
/*animation: 20s company-slider infinite;*/
}
.figure2 {
animation: 20s company-slider infinite;
}
#keyframes company-slider {
0% {
left: 0%;
}
30% {
left: 0%;
}
35% {
left: -100%;
}
55% {
left: -100%;
}
60% {
left: -200%;
}
90% {
left: -200%;
}
95% {
left: -300%;
}
100% {
left: -300%;
}
}
div#slider figure img {
width: 25%;
min-height: 100%;
float: left;
}
/*div#slider figure:hover { animation-play-state:paused; }*/
div#slider li {
list-style: none;
}
div#slider label {
background-color: #111;
bottom: .5em;
cursor: pointer;
display: block;
height: .5em;
position: absolute;
width: .5em;
z-index: 10;
}
#controls {
width: 100%;
height: auto;
}
#control-container {
padding: 25px 12%;
}
.control-button {
display: inline;
margin: 0 2%;
width: 25%;
background: gray;
height: 10px;
border: none;
}
.control-button.active {
display: inline;
margin: 0 2%;
width: 25%;
background: black;
height: 10px;
border: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<div id="slider">
<figure class="figure figure2">
<img src="https://iso.500px.com/wp-content/uploads/2016/02/stock-photo-139669245.jpg" alt>
<img src="http://i.cbc.ca/1.3376224.1450794847!/fileImage/httpImage/image.jpg_gen/derivatives/4x3_620/tundra-tea-toss.jpg" alt>
<img src="https://static.pexels.com/photos/22804/pexels-photo.jpg" alt>
<img src="https://iso.500px.com/wp-content/uploads/2016/02/stock-photo-139669245.jpg" alt>
</figure>
<div id="controls">
<div id="control-container">
<button id="slide1" class="control-button"></button>
<button id="slide2" class="control-button"></button>
<button id="slide3" class="control-button"></button>
</div>
</div>
</div>
This makes all of the buttons active:
$('.control-button').addClass('active');
Replace it with:
$('.control-button').removeClass('active');
$(event.target).addClass('active');
Add the event parameter to the function so you can use event.target:
$('.control-button').click(function(event) {
EDIT:
Making the control buttons activate "naturally" as the images slide is a bit harder.
Make each image have an attribute that says which slide it is:
<figure class="figure figure2">
<img data-number="slide1" src="https://iso.500px.com/wp-content/uploads/2016/02/stock-photo-139669245.jpg" alt>
<img data-number="slide2" src="http://i.cbc.ca/1.3376224.1450794847!/fileImage/httpImage/image.jpg_gen/derivatives/4x3_620/tundra-tea-toss.jpg" alt>
<img data-number="slide3" src="https://static.pexels.com/photos/22804/pexels-photo.jpg" alt>
<img data-number="slide4" src="https://iso.500px.com/wp-content/uploads/2016/02/stock-photo-139669245.jpg" alt>
</figure>
Create a system to detect when the image comes into view:
window.setInterval(function() {
Detect which image is being shown:
var activeImage = document.elementFromPoint($(window).width()/2, 10); // The image at the horizontal midpoint of the screen
Set the class of the corresponding control button to active:
$('.control-button').removeClass('active');
$("#"+$(activeImage).attr("data-number")).addClass('active'); // Sets whichever control button that corresponds to the image under the horizontal midpoint of the screen as active
Set how often you want to check at the closing of the setInterval:
}, /*time interval in miliseconds*/);
As far as adding 'active' to all buttons you should replace this:
$('.control-button').addClass('active');
with this:
$('.control-button').removeClass('active'); //this removes all '.active' first
$(this).addClass('active');
What's happening here is that within the .control-button click function, $(this) represents the current .control-button element.
https://jsfiddle.net/q3j01xrs/
What about this? I improved your script. I took out your CSS animation and replaced it by another JavaScript animation. Have a look!
$('.control-button').click(function() {
clearInterval(setInt);
$('.control-button').removeClass('active');
$(this).addClass('active');
var getIndex = $(this).index('.control-button');
$('.figure img').hide();
$('.figure img').eq(getIndex).show();
setInt = setInterval(slide, 5000);
});
function slide() {
var getIndex = $('.figure img:visible').index('.figure img');
$('.control-button').removeClass('active');
$('.figure img:visible').animate({
width: 'toggle'
}, 350);
getIndex++;
if ((getIndex) == $('.control-button').length) {
$('.control-button').eq(0).addClass('active');
$('.figure img').eq(0).animate({
width: 'toggle'
}, 350);
} else {
$('.control-button').eq(getIndex).addClass('active');
$('.figure img').eq(getIndex).animate({
width: 'toggle'
}, 350);
}
};
var setInt = setInterval(slide, 5000);

Categories

Resources