Javascript - move elements by pressing another element - javascript

Lets say I have a div with images, however not all have space to be displayed at same the time, so I used CSS property white-space: nowrap and overflow: hidden, so elements don't break into new lines or expand over div.
Now I need JavaScript technique that will allow me to move them left or right so user can reach these not visible images aswell. Think of it as a slider.
It should have two navigation buttons, left and right, by pressing each, images move in specific direction. Movement should be animated (not moving instantly, instead, they should move over specific period, frame by frame)
Here is jsfiddle demo: http://jsfiddle.net/rfLffev7/
(red and green div represent a button that should trigger functions)
HTML:
<div id="container">
<div id="left"></div>
<div id="track">
<img src="">
<img src="">
<img src="">
<img src="">
<img src="">
<img src="">
<img src="">
<img src="">
</div>
<div id="right"></div>
</div>
CSS:
#container {
width: 600px;
height: 200px;
margin: 10px auto;
}
#left {
width: 50px;
height: 200px;
float: left;
background: #500;
}
#track {
width: 500px;
height: 200px;
float: left;
background: #333;
white-space: nowrap;
overflow: hidden;
}
#track img {
width: 100px;
height: 100px;
border: 1px solid #fff;
margin-top: 50px;
margin-left: 10px;
}
#right {
width: 50px;
height: 200px;
float: left;
background: #050;
}

I would use absolute positioning for that as the CSS will be simpler. For the JavaScript, it's quite simple.
Here, I subtract 116px from the "margin-left" to move #track to the left and add 116px to #track to move it back to the right. I have not added any "stops" at either end, so in theory you could keep scrolling indefinitely.
document.getElementById("left").onclick = function(){
var currentPlace = parseInt(document.getElementById("track").style.marginLeft) || 0;
document.getElementById("track").style.marginLeft = (currentPlace - 116) + "px"
}
document.getElementById("right").onclick = function(){
var currentPlace = parseInt(document.getElementById("track").style.marginLeft) || 0;
document.getElementById("track").style.marginLeft = (currentPlace + 116) + "px"
}
Here's a working example (using absolute positioning): http://jsfiddle.net/rfLffev7/1/
I also added an additional :nth-child(even) class to make it more obvious that the images are moving:
#track img:nth-child(even) {
border: 1px solid #f00;
}

You can move the inner track using margins. For example, check the element for its margin value, then for the size of the image (or whatever distance you want to move the track), then add those two values together, then apply the new value to the track.
$('#right').click(function(){
var moveDistance = $('#track').find('img').width()
var moved = $('#track').css('marginLeft');
var moveIt = moveDistance - parseInt(moved)
$('#track').css('marginLeft', -moveIt);
});
I have updated your example with what I mean. The green button is rigged to move the distance of 1 image + the previous value of the element margin.
http://jsfiddle.net/rfLffev7/4/
You'll also need to make a few changes to your css to keep the other elements positions.
#container {
width: 600px;
height: 200px;
margin: 10px auto;
overflow:hidden;
position:relative;
}
#left {
width: 50px;
height: 200px;
left:0;
background: #500;
position:absolute;
z-index:1;
}
#track {
width: auto;
height: 200px;
float: left;
background: #333;
white-space: nowrap;
overflow: hidden;
position:absolute;
left:50px;
}
#track img {
width: 100px;
height: 100px;
border: 1px solid #fff;
margin-top: 50px;
margin-left: 10px;
}
#track img:nth-child(even) {
border: 1px solid #f00;
}
#right {
width: 50px;
height: 200px;
background: #050;
position:absolute;
right:0;
}

Related

How can i get 2 classes by id inside the same function

I need to target two div elements and toggle their classes simultanouesly.
I understand that I can get multiple divs "by ID" by using .querySelectorAll
but when I get to .classlist.toggle ("NewClassName"); how can I target two classes??
So here's some code:
#small-div{
background-color:#aaaaaa;
border: 3px solid #aaaaaa;
padding: 0px 0px 0px 0px;
margin: auto 10px auto auto;
border-radius: 10px;
overflow: auto;
}
.tobetoggled{
width: 45%;
float: left;
}
#small-div2{
background-color:#aaaaaa;
border: 3px solid #aaaaaa;
padding: 0px 0px 0px 0px;
margin: auto 10px auto auto;
border-radius: 10px;
overflow: auto;
}
.tobetoggled2{
width: 45%;
float: right;
}
.toggletothis{
width: 100%;
float: left;
position: fixed;
display: block;
z-index: 100;
}
.toggletothis2{
width: 100%;
float: left;
position: fixed;
display: block;
z-index: 100;
}
.whensmalldivistoggled{
display: none;
}/* when small-div is clicked, small-div toggles to class "tobetoggled" while small-div 2 simultaneously toggles to class "whensmalldivistoggled" (the display none class) */
<div id="container">
<div class="tobetoggled" onclick="function()" id="small-div">
</div>
<div class="tobetoggled2" onclick="separatefunction()" id="small-div2">
</div>
</div> <!-- end container -->
<script>
function picClicktwo() {
document.querySelectorAll("small-div, small-div2").classList.toggle("toggletothis, whensmalldivistoggled");
}
</script>
So as you can see one div is on the right, the other is on the left, each set to 45% width. So if I toggle one div to 100% width the browser still respects the other divs space instead of taking the whole 100%.
So I'm thinking if I can get the div on the right ,for example, to not display when the div on the left is toggled, it will be out of the way so the left div can take all 100%
Maybe im going about this the wrong way. Any help is welcome. Thanks.
You can create a single javascript function that sets appropriate classes on each element. Since you have only two elements it is not too complex.
HTML
<div id="container">
<div id="lefty" onclick="toggle('lefty', 'righty')">Lefty</div>
<div id="righty" onclick="toggle('righty', 'lefty')">Righty</div>
</div>
JS
function toggle(target, other)
{
var t = document.getElementById(target);
var o = document.getElementById(other);
if (!t.className || t.className == "inative")
{
t.className = "active";
o.className = "inactive";
}
else
{
t.className = "";
o.className = "";
}
}
CSS
#container {
background-color: lightgreen;
padding: 15px 0;
}
#container div {
color: white;
width: 45%;
display: inline-block;
}
#lefty {
background-color: blue;
}
#righty {
background-color: purple;
}
#container div.active {
width: 90%;
}
#container div.inactive {
display:none;
}
https://jsfiddle.net/dLbu9odf/1/
This could be made more elegant or capable of handling more elements with something like toggle(this) and then some DOM traversal and iteration in javascript, but that's a bit beyond scope. If that were the case I would recommend jQuery.

How do you make a div only extend in one direction when the outer container size increases?

I'm trying to make a a page container with a navigation bar on the left (inside of the container). When the outer page is wider than the container, I would like just the navigation bar to extend left up to a certain size while the rest of the container's contents to remain the same and stay in the middle of the outer page.
To illustrate my idea, here are the before and after images, with black representing the outer page, blue the page container, pink the leftnav, and green the rest of the container.
Here is also the general structure of the code I am writing. The jsfiddle link includes some css for detail.
<div id="page">
<div id="container">
<div id="leftCol">
LEFT
</div>
<div id="rightCol">
RIGHT
</div>
</div>
https://jsfiddle.net/6L1zrj6e/1/
Currently, my container has a fixed width and automatic margins so as to center it. Is what I am trying to achieve even possible with the current layout? Would I need to move the leftnav div outside of the container?
Here's a pure css solution: fiddle
This is a trick I learned here: here
where you have to put the float first, then make the div respect it by creating a new block formatting context, then the div will expand to the remaining space. Throw in a couple min/max widths to conform it and a wrapper with min/max widths as well and it falls into place. The html background makes the body background not extend past the body as it normally would. Another little trick.
<div class="wrap">
<main></main>
<nav></nav>
</div>
html {
background: white;
}
body {
background: purple;
padding: 0;
margin: 0;
}
.wrap {
margin: 0 auto;
max-width: 1080px;
min-width: 920px;
}
nav {
overflow: auto; /* force a new context to respect float */
background: red;
height: 300px;
min-width: 200px;
max-width: 360px;
}
main {
float: right;
background: green;
height: 300px;
width: 720px;
}
You can try the following: Full screen example
jsFiddle
HTML:
(Took leftCol out of container)
<div id="page">
<div id="leftCol">
LEFT
</div>
<div id="container">
<div id="rightCol">
RIGHT
</div>
</div>
</div>
JS: (Update the width on page resize and on load)
$(window).on('resize', function(){
var containerWidth = 980;
var pageWidth = $(window).width();
var tempW = Math.max(0, pageWidth-containerWidth) / 2;
tempW += 200;
var w = Math.min(tempW, 360); // 360 = max width
var l = Math.max(0, tempW - w);
$('#leftCol').css({'width': w+'px', 'left': l+'px'});
}).resize();
CSS: (Removed floats, using absolute position for leftCol)
#page{
background-color: purple;
position:relative;
}
#container {
background-color: blue;
width: 980px;
height: 300px;
margin: 0 auto;
}
#leftCol {
position:absolute;
top: 0;
left: 0;
background-color: red;
height: 300px;
width: 200px;
}
#rightCol {
padding-left:200px;
background-color: green;
height: 300px;
width: auto;
}
This is what I think you're after - forgive me if I'm wrong!
EDIT: Added outer container wrapper for right margin:
Updated HTML:
<div id="page">
<div id="outercontainer">
<div id="container">
<div id="leftCol">
LEFT
</div>
<div id="rightCol">
RIGHT
</div>
</div>
</div>
</div>
And the CSS:
#page{
background-color: purple;
height: 300px;
}
#outercontainer {
margin: 0 5% 0 0;
}
#container {
background-color: blue;
height: 300px;
margin: 0 auto;
min-width: 300px;
max-width: 600px;
position: relative;
}
#leftCol {
background-color: red;
height: 300px;
margin-right: 200px;
}
#rightCol {
position: absolute;
background-color: green;
width: 200px;
top: 0;
right: 0;
bottom: 0;
}
This gives the #container a min and max width, and the margins will show beyond the max. These are set quite small to show up well in JSFiddle.
leftCol will expand to fit the available space, and it's right-margin prevents it overflowing the rightCol.
rightCol is absolutely positioned (within #container) in the leftCol's margin.
JSFiddle here: https://jsfiddle.net/xuew6og5/1/
The #outerwrapper allows a visible right margin, until the page gets to minimum width at least. If you want the margins to be balanced, change its margin to 0 5%
Update: New JS Fiddle with right margin: https://jsfiddle.net/xuew6og5/2/
Update 3: Sorry, I missed your requirement for a max-width of 360px on the leftCol. Updated the CSS above, and a fiddle here: https://jsfiddle.net/xuew6og5/4/
In order to achieve the wanted effect you need to move the leftCol outside of your container and give your rightCol a margin-left with the size of your leftCol.
Also add a min-width and max-width to your lefCol and a width using calc to adjust it's width to your goals.
Note: lefCol width is calculated like this:
100% / 2 - (Container width / 2 - leftCol min-width)
So your altered html looks like this:
<div id="page">
<div id="leftCol">
LEFT
</div>
<div id="container">
<div id="rightCol">
RIGHT
</div>
</div>
</div>
Your new CSS looks like this:
#page{
background-color: purple;
}
#container {
background-color: blue;
width: 300px;
height: 300px;
margin: 0 auto;
}
#leftCol {
float: left;
background-color: red;
height: 300px;
min-width:100px;
width:calc(100%/2 - 50px);
max-width:200px;
}
#rightCol {
margin-left:100px;
background-color: green;
height: 300px;
width: 200px;
}
Take a look at the updated example:
https://jsfiddle.net/xxyv7nwf/2/
CSS solution using CSS3 calc.
Edited. According to OP updates.
#media screen and (min-width: 1600px) {
#container{
margin:0 auto;
}
}
body {
overflow-x:hidden;
}
#page{
background-color: purple;
height:300px;
}
#container{
background-color: blue;
min-width:980px;
max-width: 1140px;
}
#leftCol {
float: left;
background-color: red;
height: 300px;
width: calc(100% - 780px);
}
#rightCol {
float: left;
background-color: green;
height: 300px;
width: 780px;
}
HTML
<div id="page">
<div id="container">
<div id="leftCol">
LEFT
</div>
<div id="rightCol">
RIGHT
</div>
</div>
</div>

Adding A Div Caption To Divs Containing Sliders (Follow Up On Previous Q)

I currently have a grid layout made up of image sliders and text slider with square divs. I have just asked a question of how to add captions to these squares within the grid. Now I can do this nicely when the div contains a text slider. However when I try to apply the same caption to divs containing the image slider it does not work, could somebody please show me how I can do this.
CSS FOR DIVS
.slider2 { position: relative; }
.caption-box {
position: absolute;
right: 0;
height: 20px;
width:100px;
background-color: red; // change to suit
color: #fff; // change to suit
}
.trigger {
width: 200px;
height: 200px;
}
.static {
position: relative;
width: 200px;
height: 200px;
text-align: center;
font-size: 0;
border-style: solid;
border-width: 1px;
border-color: #CCCCB2;
border-radius: 5px;
}
BELOW IS THE HTML CODE OF THE TEXT SLIDER DIV WHERE THE CAPTION DIV WORKS WELL
<div class="trigger">
<div class="slider2">
<div style="border-style: solid; border-width: 1px; border-color: #CCCCB2; border-radius: 5px; height: 200px; width: 200px; color: #CCC;" class="just_text"><div class="caption-box">Monthly Plan</div>As part of our budget graphic design service we also offer a money saving monthly advertising schedule option. Whether it be for 6, 9 or 12 months we will remove all stress of advertising from your office leaving you to concentrate on your customers. </div>
<div style="border-style: solid; border-width: 1px; border-color: #CCCCB2; border-radius: 5px; height: 200px; width: 200px; color: #CCC;" class="just_text"><div class="caption-box">Web Updates</div>Our website design service also includes a money saving update scheme. For a monthly fee you can have updates to keep your website fresh and dynamic. No other company can offer this service.</div>
</div>
</div>
BELOW IS THE HTML CODE OF THE IMAGE SLIDER WHERE I CAN NOT GET THE CAPTION DIV TO WORK
<div class="trigger">
<div tabindex="0" class="maincontent static"><div class="slider2">
<img src="client9.jpg" height="200" width="200" />
<img src="client10.jpg" height="200" width="200" />
<img src="client11.jpg" height="200" width="200" />
<img src="client2.jpg" height="200" width="200" />
</div></div>
</div>
JAVASCRIPT
<script>
$(function(){
$('.slider').sss({
slideShow : true, // Set to false to prevent SSS from automatically animating.
startOn : 0, // Slide to display first. Uses array notation (0 = first slide).
transition : 400, // Length (in milliseconds) of the fade transition.
speed : 20000, // Slideshow speed in milliseconds.
showNav : true // Set to false to hide navigation arrows.
});
$('.slider2').sss({
slideShow : true, // Set to false to prevent SSS from automatically animating.
startOn : 0, // Slide to display first. Uses array notation (0 = first slide).
transition : 400, // Length (in milliseconds) of the fade transition.
speed : 10000, // Slideshow speed in milliseconds.
arrows : false // Set to false to hide navigation arrows.
});
});
</script>
CSS THAT JAVASCRIPT LINKS TO CALLED SSS.CSS
.sss {
height: 0;
margin: 0;
padding: 0;
position: relative;
display: block;
overflow: hidden;
}
.ssslide {
width: 100%;
margin: 0;
padding: 0;
position: absolute;
top: 0;
left: 0;
display: none;
overflow: hidden;
}
.ssslide img {
max-width: 100%;
height: auto;
margin: 0;
padding: 0;
position: relative;
display: block;
}
.sssnext, .sssprev {
width: 25px;
height: 100%;
margin: 0;
position: absolute;
top: 0;
background: url('images/arr.png') no-repeat;
}
.sssprev {
left: 3%;
background-position: 0 50%;
}
.sssnext {
right: 3%;
background-position: -26px 50%;
}
.sssprev:hover, .sssnext:hover {
cursor: pointer;
}.row .col .trigger .slider2 .just_text {
color: #CCC;
}
The code for the images is incomplete, and had to create my own version to be able to replicate the issue. But once that was done, the problem was easy to find. You can see it working on this JSFiddle: http://jsfiddle.net/Lbrcbhxw/2/ (I took the liberty of cleaning it a bit so it was easier to read).
The problem is that .static has a font-size:0 that makes the text invisible. Remove it (or don't wrap the div with the images with it), and the problem will be solved.
.static {
position: relative;
width: 200px;
height: 200px;
text-align: center;
/* font-size: 0; */
border-style: solid;
border-width: 1px;
border-color: #CCCCB2;
border-radius: 5px;
}
The text version isn't wrapped around that .static, so that's why it was displayed correctly and didn't have the problem.

css overflow hidden to display images that are within defined "window" div

I'm trying to setup the css for a native javascript animation. There are going to be several images that enter a "window" which is 600px. As one image slides in or out, the only visible part will be the part of the images that is within the window. I've had several attempts at setting this up with css before I start javascript animating, which include things like overflow:hidden on the rotator div and setting it's width, however that doesn't seem to work.
#rotator {
width: 600px;
height: 320px;
background: #131313;
/*text-align: left;*/
/*display: inline-block;*/
overflow: hidden;
/*position: relative;*/
/*float: left;*/
}
.box_wrapper {
width: 450px;
/*position: absolute;*/
display: inline-block;
/*overflow: hidden;*/
}
<div id="rotator">
<div class="box_wrapper">
<h4>Header1</h4>
<img src="../img/kat_3.jpg" /><br/>
</div>
<div class="box_wrapper box_2">
<h4>Header2</h4>
<img src="../img/kat_2.jpg" /><br/>
</div>
</div>
The images either fully show up or not at all when messing with the css properties.
you need set the width or height of the images, so they can be scaled into the the divs.
<style>
#rotator {
width: 600px;
height: 320px;
background: #131313;
overflow: hidden;
}
.box_wrapper {
width: 450px;
height: 100%;
display: inline-block;
}
</style>
$('.box_wrapper').each(function() {
var $el = $(this), $img = $el.find('img'), fixedRatio = 600 / 320,
ratio = $img.width() / $img.height(),
offset = $img.offset().top - $el.offset().top;
if (ratio > fixedRatio) {
$img.width($el.width()).height('auto');
} else {
$img.height($el.height() - offset).width('auto');
}
});

How do I make one element change by hovering over another?

I'm trying to do what many have asked before, but even after trying everything I still can't get the results I want.
I have an image 600px by 1600px, 4 images of 600px by 400px in a vertical line. I want to show 600px by 400px of the image at any one time. Ideally I would be able to hover over an element somewhere on my page and move the image upwards to reveal the other portions of the 600px by 400px image. In effect, I'd have 4 images viewable by hovering over 4 the elements.
I've tried various css3 and jquery solution but none have worked. I would appreciate any help with this.
HTML
<div class="mainimage">
<div class="buttonsection">
<div class="button1">Button 1</div>
<div class="button2">Button 2</div>
<div class="button3">Button 3</div>
<div class="button4">Button 4</div>
</div><!--end of buttonsection-->
<div class="rollingimage">
<img src="IMG/four-pics.png">
</div><!--end of rollingimage-->
</div><!--end of mainimage-->
</div><!--end of main content-->
CSS
.mainimage {
position: relative;
top: 0px;
left: 0px;
width: 900px;
height: 400px;
border: 2px solid #E78F25;
margin: 0 10px 20px 0;
}
.buttonsection {
width: 290px;
height: 400px;
position: relative;
float: left;
}
.button1,
.button2,
.button3,
.button4 {
display: inline;
height: 98px;
width: 290px;
border: 1px solid #E78F24;
text-align: center;
float: left;
}
.rollingimage {
width: 598px;
height: 400px;
position: relative;
overflow: hidden;
top: 0px;
left: 0px;
float: right;
}
jquery
$(document).ready(function(){
$(".button1").hover(function(){
$('.rollingimage').stop().animate({'top': '-200px'}, 1500);
});
});
Here is the jsfidle: http://jsfiddle.net/dirtyd77/jCvYm/1/
Thanks yet again
Gary
Just for fun, no JS:
http://jsfiddle.net/coma/MTWdb/5/
HTML
<div id="foo">
Button 1
Button 2
Button 3
Button 4
<div></div>
</div>
CSS
#foo {
width: 400px;
border: 2px solid #E78F25;
position: relative;
}
#foo > div {
position: absolute;
top: 0;
right: 0;
bottom: 0;
width: 200px;
background: #fff url(http://placekitten.com/600/1600) no-repeat 0 0;
transition: background-position .5s;
}
#foo > a {
display: block;
width: 200px;
line-height: 100px;
text-align: center;
text-decoration: none;
}
#foo > a + a {
border-top: 1px solid #E78F25;
}
#foo > a:nth-child(1):hover ~ div {
background-position: 0 0;
}
#foo > a:nth-child(2):hover ~ div {
background-position: 0 -400px;
}
#foo > a:nth-child(3):hover ~ div {
background-position: 0 -800px;
}
#foo > a:nth-child(4):hover ~ div {
background-position: 0 -1200px;
}
You need to change the positioning of the image inside the div, not the div itself. To animate my example, you could add CSS transitions for better performance than JS animations.
http://jsfiddle.net/jCvYm/8/
$('.rollingimage').find('img')
As Dom mentioned, the jsFiddle you provided didn't reference the jQuery library. It also didn't included any actual images, and only contained code for one of the three buttons. I doubt those were the original problems you were having, though. (The missing reference to jQuery might have been.)
Once I had those straightened out, I noticed that hovering the button caused the picture to slide out of the screen, instead of scrolling. The simplest way to fix that is to move the img element, instead of moving the div. (The more natural way would be to change the scroll position of the div, but I don't recall how to do that off the top of my head.)
Added CSS:
.rollingimage img {
position: relative;
}
New JS:
$(document).ready(function(){
$(".button1").hover(function(){
$('.rollingimage img').stop().animate({'top': '0px'}, 1500);
});
$(".button2").hover(function(){
$('.rollingimage img').stop().animate({'top': '-400px'}, 1500);
});
$(".button3").hover(function(){
$('.rollingimage img').stop().animate({'top': '-800px'}, 1500);
});
$(".button4").hover(function(){
$('.rollingimage img').stop().animate({'top': '-1200px'}, 1500);
});
});
jsFiddle: http://jsfiddle.net/jCvYm/6/

Categories

Resources