I have the following html structure
<div id="slide">
<div style=" position: absolute; left: 0; right: 0; margin-left: auto; margin-right: auto;overflow:hidden;">
<div class='DS_Banners_Topo' id='DS_Banners_Topo_1'>
<a href='#' target='_self'><img alt='Slide1' src='http://www.dotstore.com.br/74446_salessuplementos/banners/slide1.jpg' /></a>
</div>
<div class='DS_Banners_Topo' id='DS_Banners_Topo_2'>
<a href='#' target='_self'><img alt='Slide2' src='http://www.dotstore.com.br/74446_salessuplementos/banners/slide2.jpg' /></a>
</div>
<div class='DS_Banners_Topo' id='DS_Banners_Topo_3'>
<a href='#' target='_self'><img alt='Slide3' src='http://www.dotstore.com.br/74446_salessuplementos/banners/slide3.jpg' /></a>
</div>
</div>
</div>
Need to turn this into a slide to change anything in their structure. Keeping your classes. Is it possible to do this in html structure of these?
DEMO CODE JSFiddle
If you don't want to change you structure, but can change the css, here is an example of what you could do:
CSS
#slide {
margin: 22px 0 0 0;
position: relative;
height:200px;
overflow: hidden;
}
#slide>div{
position: relative;
}
.DS_Banners_Topo{
position: absolute;
top:0;
width:100%;
overflow: hidden;
}
.DS_Banners_Topo img{
width:100%;
display: block;
}
JS
$(document).ready(function(){
//current slide index
var counter = 0,
slides = $('.DS_Banners_Topo');
//position slides
slides.each(function(i,e){ $(this).css('left',i-1+'00%'); });
//change slide every 1000ms
setInterval(function(){
counter = counter>slides.length-3 ? 0 : ++counter;
$('#slide>div').animate({'left':-counter+'00%'});
},1000);
});
JS Fiddle Demo
Note that I removed the unwanted inline styles for the div inside #slide
It would be possible to use jQuery or another library to easily rotate the visibility on each of these divs. Just Google jQuery Carousel and you'll find and endless amount of solutions to your issue. Most will preserve all existing classes.
Related
I have a scrolling image gallery as follows. The CSS lays out the images in a row that scrolls horizontally. Underneath, I have a row of the same images, but as thumbnails. I want to be able to click on a thumbnail, and scroll the correct image into view.
HTML:
<div class="images_container">
<img id="image_1" src="/image1.jpg">
<img id="image_2" src="/image2.jpg">
<img id="image_3" src="/image3.jpg">
</div>
<div class="images_container thumbnails">
<img src="/image1.jpg" class="thumbnail">
<img src="/image2.jpg" class="thumbnail">
<img src="/image3.jpg" class="thumbnail">
</div>
CSS:
.images_container {
overflow-x: scroll;
overflow-y: hidden;
max-height: 50rem;
white-space: nowrap;
}
.images_container.thumbnails {
max-height: 10rem;
}
.images_container img {
vertical-align: top;
height: 50rem;
}
.images_container.thumbnails img {
height: 10rem;
}
This works up to a point, but jumping to the id of the image is problematic. If the larger image is even a few pixels into the visible viewport, it can't 'jump' to it, as it seems to be technically on the screen.
Is there a way I can use Javascript to 'scroll' the whole image into view when I click on it's corresponding thumbnail? I don't have access to jQuery on this project, but am happy to use JavaScript to make this work.
You can try this , no change in CSS, i add an id in html and call to scrollTo function :
<script>
function scrollTo(image_id){
var topLeft = document.getElementById(image_id).offsetTop;
document.getElementById('container').scrollLeft = topLeft;
}
</script>
<div id="container" class="images_container">
<img id="image_1" src="/image1.jpg" height="500px" width="500px">
<img id="image_2" src="/image2.jpg" height="500px" width="500px">
<img id="image_3" src="/image3.jpg" height="500px" width="500px">
</div>
<div class="images_container thumbnails">
<img src="/image1.jpg" class="thumbnail" onclick="scrollIntoView('image_1')">
<img src="/image2.jpg" class="thumbnail" onclick="scrollIntoView('image_2')">
<img src="/image3.jpg" class="thumbnail" onclick="scrollIntoView('image_3')">
</div>
To keep DOM cleaner I got this solution which requires only adding js
var elms = document.getElementsByClassName("thumbnail");
for (var i = 0; i < elms.length; i++) {
elms[i].onclick = function(event) {
event.preventDefault();
event.stopPropagation();
var id = this.parentNode.href.substr(this.parentNode.href.lastIndexOf('/') + 2);
var v = document.getElementById(id).getBoundingClientRect().left;
document.getElementsByClassName("images_container")[0].scrollLeft += v;
}
}
See on jsfiddle
Here's my attempt at a no (well, minimal) JS solution to a scrolling gallery. You could, in fact, remove the Javascript all together if you replaced the .active class with the :target pseudo-selector, allowing you to click your thumbnails to do the scrolling. It's just easier for me to do it this way through a fiddle
function removeClass(element, className) {
var classes = element.className.split(' ');
var key = classes.findIndex(function(name) {
return name == className
});
classes.splice(key, 1);
element.className = classes.join(' ');
}
function addClass(element, className) {
var classes = element.className.split(' ');
classes.push(className);
element.className = classes.join(' ');
}
setInterval(function() {
var current = document.querySelector('.images .image.active');
var next = current.nextElementSibling;
if (!next) {
next = document.querySelector('.images .image:first-child');
}
removeClass(current, 'active');
addClass(next, 'active');
}, 1500);
body {
margin: 0;
padding: 0;
width: 500px;
height: 500px;
}
.images {
width: 100%;
height: 100%;
position: relative;
overflow-x: hidden;
}
.image {
width: 100%;
height: 100%;
top: 0px;
position: absolute;
left: -100%;
float: left;
transition: 1s;
}
.image.active {
left: 0%;
}
.image.active ~ .image {
left: 100%;
}
.black {
background-color: black;
}
.red {
background-color: red;
}
.blue {
background-color: blue;
}
.yellow {
background-color: yellow;
}
<div class='images'>
<div class='image black active'></div>
<div class='image red'></div>
<div class='image blue'></div>
<div class='image yellow'></div>
</div>
Essentially the way it works is by making the div.images container a certain height and width, and therefore all images inside it can be positioned as you want. We initially set all .image to left: -100%, so that they're completely off screen to the left. We then set .image.active as left: 0 so that it's on screen. We then use the ~ selector to say that all siblings that come after the current (.image.current ~ .image) should be left: 100%, so completely to the right. Add in a transition, and you have a completely CSS scrolling gallery. The JS only acts as a way to change what the current active image is, and you can replace that with :target if you want.
I used div's, instead of img tags because it's easier to provide a POC with div's and background colors, but it's worked well with images in the past. Just put an <img> tag inside those <div class='image'></div> tags
I am trying to do an overview page on my website so that when I hover over a div on the overview page different sections of that div show different images. Essentially a slideshow but the image changes depending on where the cursor is.
I have managed to find some code that does what I want but it uses an a href to pull in the images which means if you click it, it goes to the link of the image.
Currently I just have placeholder images in but when finished each one will have specific project images in. As each div will just be one project the whole div should go to one html link and not just a specific image link of the image the user is hovering over.
All I want is the user to click and it go to a html link and not an img link.
Here is the code I am using:
The coding savvy people out there will probably have a much better solution for what I would like to achieve, I am interested to see any better solutions.
HTML
<div class="multi">
<ul class="rotator-nav fifth clearfix">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<div class="imgcontent">
<ul class="rotator-icons fifth">
<span class="img1 active"></span>
<span class="img2"></span>
<span class="img3"></span>
<span class="img4"></span>
<span class="img5"></span>
</ul>
<img src="/img/FoI.jpg" class="currentimg">
</div>
</div>
CSS
.multi {
display: block;
float:left;
position: relative;
width: 30.8%;
height: 20%;
padding: 0px;
margin:0% 1% 2% 1%;
overflow: hidden;
}
.multi .imgcontent {
display: block;
position: absolute;
top: 0px;
}
.imgcontent img {
display:block;
width: 100%;
height: auto;
margin-left: auto;
margin-right: auto;
}
.rotator-nav {
display: block;
position: relative;
width: 100%;
height: 100%;
z-index: 9;
}
.rotator-nav li {
display: block;
float: left;
height: 100%;
}
.rotator-nav.fourth li {
width: 25%;
}
.rotator-nav.fifth li {
width: 20%;
}
.rotator-nav li a {
display: block;
float: left;
width: 100%;
height: 100%;
border-bottom:0px solid #fff
}
.clearfix:after { content: "."; display: block; clear: both; visibility: hidden; line-height: 0; height: 0; }
.clearfix { display: inline-block; }
html[xmlns] .clearfix { display: block; }
* html .clearfix { height: 1%; }
JS
$(function(){
var $rotators = $('.multi');
var $imglinks = $('.rotator-nav a');
$imglinks.on('mouseenter', function(e){
var imgclass = '.'+$(this).attr('class');
var imglink = $(this).attr('href');
// update main image src
$(this).parent().parent().parent().find('.currentimg').attr('src',imglink);
// update current rotator icon
var $rotators = $(this).parent().parent().parent().find('.rotator-icons');
if($rotators.children(imgclass).hasClass('active')) {
// already active icon -- do nothing
} else {
// remove active class then add to new icon
$rotators.children('span').removeClass('active');
$rotators.children(imgclass).addClass('active');
}
});
});
Any help would be greatly appreciated!
Thanks,
Mark
I think you could best use a data attribute for this instead (if I understand the intention correctly) :
var imglink = $(this).data('image');
<div class="multi">
<ul class="rotator-nav fifth clearfix">
<li>
<a data-image="/img/FoI.jpg" href="#" class="img1"></a>
</li>
<li>
<a data-image="/images/card.jpg" href="#" class="img2"></a>
</li>
<li>
<a data-image="/images/amareal.jpg" href="#" class="img3"></a>
</li>
<li>
<a data-image="/images/edeva.jpg" href="#" class="img4"></a>
</li>
<li>
<a data-image="/images/amacover2.gif" href="#" class="img5"></a>
</li>
</ul>
...
If you'd still like to see the image over the original div, a pseudo element could be used. Advantage there is that they are not actual DOM elements and will not register clicks :
Demo
Now it would be great if the data attribute could be directly used for the content of the pseudo element as well but that doesn't seem possible. And you can't target them with JavaScript so each image would have to be defined with nth-of-type() in the stylesheet additionally.
You don't need to use .parent().parent()
Just use the parent's class to find the item.
Your $(this).parent() * 3 is the $(".multi")
So your $rotators can't find .rotator-icons,
you need to use one more parent or use siblings
And I suggest do not use class if there are no need to do one thing to lots of items.
I have made a custom jquery slideshow which is working as required. The only thing remaining is animating the caption inside the slide. I want the caption to respond to the current slide but the problem is all of the captions respond no matter which slide is showing. I cannot seem to fix this issue.
<body>
<div class="marquee_container">
<div class="holder">
<div class="slide">
<img class="marquee_panel_photo" src="images/photos/london.jpg" alt="London" />
<div class="marquee_caption">
<div class="marquee_caption_content">
<p>Content goes here</p>
</div>
</div>
</div>
<div class="slide">
<img class="marquee_panel_photo" src="images/photos/milan.jpg" alt="milan" />
<div class="marquee_caption">
<div class="marquee_caption_content">
<p>Content goes here</p>
</div>
</div>
</div>
<div class="slide">
<img class="marquee_panel_photo" src="images/photos/staugustine.jpg" alt="staugustine" />
<div class="marquee_caption">
<div class="marquee_caption_content">
<p>Content goes here</p>
</div>
</div>
</div>
</div>
<div class="marquee_nav">
</div>
</div>
</body>
</html>
CSS
.marquee_container {
width: 700px;
height: 350px;
overflow: hidden;
margin: 0px 0px 30px 0px;
padding: 0px;
position:relative;
}
.holder{
overflow: hidden;
position: relative;
width: 9999px;
height: 350px;
}
.slide{
width: 700px;
float: left;
position:relative;
}
.marquee_photos {
overflow:hidden;
}
.marquee_photos img{
display:block;
}
.marquee_caption {
width: 700px;
margin: 0px;
padding: 15px 0px 10px 0px;
color: #fff;
position: absolute;
top: 350px;
left: 0px;
background: url(images/template/marquee_caption.png) 0px 0px;
}
.marquee_caption_content {
width: 410px;
padding: 0px 0px 0px 25px;
}
.marquee_nav{
position:absolute;
bottom:5px;
right:0;
}
.marquee_nav .marquee_nav_item{
color:#fff;
text-decoration:none;
background:url(images/template/nav_buttons.png) no-repeat;
text-indent:-9999px;
overflow:hidden;
display:block;
width:17px;
height:18px;
float:left;
margin:0 4px;
}
.marquee_nav .marquee_nav_item:hover{
background:url(images/template/nav_buttons.png) no-repeat -25px 0;
}
.marquee_nav .marquee_nav_item.selected{
background:url(images/template/nav_buttons.png) no-repeat -50px 0;
}
JQUERY
$(document).ready(function(){
//1st STEP
//generating nav links automatically
//for each slide there should be a nav item
$('.slide').each(function(index, value){
$('.marquee_nav').append('');
});
//2nd STEP
//setting the nav links and running the slide
$('.marquee_nav .marquee_nav_item').on('click', function(){
$('.marquee_nav_item').removeClass('selected');
$(this).addClass('selected');
//3rd STEP
//animating the slideshow
//getting the index value of the clicked nav
var navClick = $(this).index();
/* holder width set to the parent width because the holder width is 9999px and we will use that to change
the margin-left position of the images */
var holderWidth = $('.marquee_container').width();
/* position of the new img according to the nav item clicked. If the 3 nav item is clicked jquery will get that
index value and will multiply it with the holder width to know how much distance it has to move for eg.
if the 2nd nav is clicked, the index is 1, so 1 * with the holderWidth which is 700 = 700. So it will move margin-left
-700px. See the animate function below */
var photoPosition = navClick * holderWidth;
//alert(photoPosition);
//slideshow animation
$('.marquee_container .holder').animate({'margin-left' : -photoPosition}, 1000);
//animating the caption
$('.marquee_caption').animate({'top':275}, 500);
});
});
Perhaps you need to first send all the .marquee_caption elements back to their original position and then bring only the selected one into the view.
Something like:
...
$('.marquee_caption').not(':eq(' + navClick + ')').animate({ 'top': 200 }, 500);
$('.marquee_caption').eq(navClick).animate({ 'top': 100 }, 500);
...
where navClick is the variable you already have in your code which stores .index() of the selected navigation element. And .eq() is the jQuery method you pass this navClick value into.
Here is a modified jsFiddle as an example using your own code for simplicity sake.
Hope this is what you were looking for.
Update:
The .eq() method of jQuery takes an index parameter to retrieve only one element out of a set of elements.
The .not() method selects everything except the selector rule passed to it.
So in the first line above, out of the 3 .marquee_caption elements, we are selecting all elements except the currently selected one as per the navClick index. So the resulting jQuery object contains 2 out of 3 elements. And then we .animate() them as usual.
Finally, you can simply trigger the click event on the respective .marquee_nav_item element by utilising the same .eq() method i.e. just before your $(document).ready(...) function closes, add this: $('.marquee_nav .marquee_nav_item').eq(0).trigger('click');.
This is one of the options by the way, and probably the quickest and dirtiest. What is happening is that you are triggering the click event manually and hence everything, defined in the click function above, follows.
//animation the caption
$(this).parents('.slide').find('.marquee_caption').animate({'top':275}, 500);
Is this what you mean?
What I want to do is to show the top photo (which is set to visibility: hidden) on hover. I have two photos positioned on each other like this:
<div class="frame">
<img src="./img/portfolio/default1.jpg" width="300" height="178" alt="Title Here"></a>
<div class="boxwrapper" style="visibility: hidden;"></div>
</div>
Added the second photo through css:
.boxwrapper {
background: url("../img/boxPlus.gif");
position: relative;
width: 300px;
height: 178px;
left: -6px;
top: -184px;
z-index: 1000;
}
Is it possible to do with css? Tried (and several more options):
#frame img:hover .boxwrapper {
visibility: visible;
}
But it is not working. Or this is only possible with javascript? If yes, please give some tips as I am not too much of javascript guy. Thanks!
You could set the photo as background of the boxwrapper
.boxwrapper{
background: url("../img/boxPlus.gif");
}
.boxwrapper:hover{
background: url("../img/portfolio/default1.jpg");
}
if this is not possible you could add it as background trough a style attribute inside your html
<div class="boxwrapper" style="background: url('../img/boxPlus.gif');" ></div>
You'd have to put the :hover class on a parent container. CSS does not allow such things to trickle "up" the tree, only down.
.boxwrapper {
display: none;
}
.frame:hover .boxwrapper {
display: block;
}
http://jsfiddle.net/awfex/4/
HTML:
<div class="section-header section-header-on" id="section_header_289" style="left: 50px;">
<span class="collapse"></span>
<div class="section-name">
<span class="name">Testing Facebox suff</span></div>
<ul class="tools">
<li>
<a class="trash" href="#"></a>
</li>
<li>
</li>
</ul>
<div class="clear"></div>
</div>
js:
$j = jQuery.noConflict();
$j(".section-header").hover(function(){
$j(this).find("ul").show();
});
So, I need this to be relative, because there are multiple "section-header"s and the ID is generally unknown / generated by the app. But, basically, I want to be able to hover over the section-header, and then have ul.tools change from display: none; to display: block. So I figured .show() could do that. but.. I guess my selector is wrong. =\
Your css specifies:
.section-header ul.tools,
.section-content li.content ul.tools {
visibility: hidden;
position: absolute;
top: 0;
left: -40px;
z-index: 1002;
cursor: default;
width: 40px;
height: 35px;
list-style: none;
}
Most notably visibility: hidden; which is not affected by the show()/hide() functions. So you need to change the css visibility property so your list will show-up.
Change:
$j(this).find("ul").show();
To:
$j(this).find("ul").css({visibility: 'visible'});
Or set the CSS to display: none; rather than use the visibility property.
show() documentation: http://api.jquery.com/show/
Demo
just needed a little coercion ;)
$j = jQuery.noConflict();
$j(".section-header").hover(function(){
$j(this).find(".tools").css({visibility:"visible"});
},function(){
$j(this).find(".tools").css({visibility:"hidden"});
});
Just needed a little css.
.tools {
display: none;
}
div.section-header:hover ul {
display: block;
}