Javascript set a variable that changes on each child item - javascript

This may seem like an easily answered question but it's one I've been struggling for a little while.
Let me first explain what I'm trying to achieve.
I have a gallery of images and I want each of the images to centered vertically inside their container. The images are of varying shapes, sizes and aspect ratios so my code needs to be variable for each image therein. Here is what I have so far:
<div id="cbp-fwslider" class="cbp-fwslider">
<img src="images/large/1.jpg" alt="img01"/>
<img src="images/large/2.jpg" alt="img02"/>
<img src="images/large/3.jpg" alt="img03"/>
</div>
And here is my javascript:
var $img = $('div#cbp-fwslider img');
var ih = $img.height();
var $div = $('div#cbp-fwslider');
var dh = $div.height();
if (dh > ih) {
var dif = (dh - ih);
$img.css('margin-top', + dif / 2 + "px");
}
Now, this works in part. What it does is calculates the correct "margin-top" to vertically center the first image within the container but then applies it to all involved. I have no doubt that this is because I have set the javascript to set the "margin-top" as the same for all the images.
My question is, how do I set a variable to make it so it does this separately for all the items that I put in my gallery?
Forgive me if this is a basic question that I could have found the answer for elsewhere, I am pretty wet behind the ears when it comes to javascript.
Also if anybody knows of an easier/more efficient way of achieving what I want then it would be great if you could point me in the right direction.
I must advise that the container has a dynamic height and so do all images. With the nature of how the gallery works, I can't use absolute positioning and THIS technique doesn't seem to work either.
Thanks in advance for any help.

You'll want to run your code individually on each image rather than on the collection of images. You can do this by using each to loop through the collection:
$('div#cbp-fwslider img').each(function(){
var $img = $(this);
var ih = $img.height();
var $div = $('div#cbp-fwslider');
var dh = $div.height();
if (dh > ih) {
var dif = (dh - ih);
$img.css('margin-top', + dif / 2 + "px");
}
});

You can just use css to vertically align all images to center.
<div id="cbp-fwslider" class="cbp-fwslider">
<img src="images/large/1.jpg" alt="img01"/>
<img src="images/large/2.jpg" alt="img02"/>
<img src="images/large/3.jpg" alt="img03"/>
</div>
css
img {
vertical-align: middle;
}​
see http://jsfiddle.net/vishnurajv/xR28t/

Try to find the maximum height of img in your div, after that set margin-top for all of other img. This is my idea, you or someone can do better.
var maxHeight = 0;
$('div#cbp-fwslider img').each(function(){
if($(this).height() > maxHeight) maxHeight = $(this).height();
});
$('div#cbp-fwslider img').each(function(){
$(this).css('margin-top', Number(maxHeight - $(this).height()) / 2 + 'px');
});
Hope help!

Related

Thumbnail image swap on mousemove

I would love to have a gallery website with multiple thumbnails including 3 images that rotate as soon as I mousemove over each one.
I've found this amazing responsive fiddle in another thread from #matthias_h going through multiple thumbnail images while mousemove over the thumbnail box.
His fiddle: http://jsfiddle.net/matthias_h/2f2tth47/
The HTML
<article>
<figure data-image-list="http://dummyimage.com/200x200/000000/cccccc.png&text=img1,http://dummyimage.com/200x200/dedede/cccccc.png&text=img2,http://dummyimage.com/200x200/b31031/cccccc.png&text=img3">
<img class="imageHolder" data-src="http://dummyimage.com/200x200/cdcdcd/dddddd.png&text=+" src="http://dummyimage.com/200x200/cdcdcd/dddddd.png&text=+" />
</figure>
The Javascript
$(".imageHolder").mousemove(function (event) {
var xPos = event.pageX,
imgPos = $(".imageHolder").offset().left,
imgWidth = $(".imageHolder").width();
console.log("xPos: ", xPos, ", imgPos: ", imgPos, ", imgWidth: ", imgWidth);
var change1 = imgPos,
change2 = imgPos + imgWidth / 3,
change3 = imgPos + 2 * imgWidth / 3;
console.log("change1: ", change1, "change2: ", change2, "change3: ", change3);
$images = $("figure").data("imageList");
var array = $images.split(',');
if (xPos > change1) {
$("img").attr("src", array[0]);
}
if (xPos > change2) {
$("img").attr("src", array[1]);
}
if (xPos > change3) {
$("img").attr("src", array[2]);
}});$("img").mouseout(function (){$("img").attr("src", $("img").data("src"));});
Unfortunately there are two issues with this.
When duplicating it, moving over any of them also switches the
images on the other ones.
It takes single images instead of bg positions via css which is less efficient since I'm personally using image sprites for all my work.
I have good experience with html/css but no experience with javascript. Would love to get some insight how I can fix these two issues. Mainly the first one to make a gallery with multiple images work in the first place.
Thanks in advance!
Now that you duplicated the elements, it is targeting a collection instead of just one element.
In general, jQuery method's setter applies to all matching elements, and getter return a value for the first matching element.
Question #1:
Use
$(this) instead of $("img")
$(this) instead of $(".imageHolder")
$(this).parent("figure") instead of $("figure")
Question #2:
You will have to use .css() to change the background position instead of changing the href.
That would be something like $(this).css({background-position: newPosition}) where newPosition has to be defined...
CodePen

I want to Aspect-Fill Image Slider in fixed sized div element

I have several images with different sizes, and I am going to make image slider using these images.
I refer to this document.
But in this library, images are aspect fit in div element.
How to make image slider in which images are aspect-filled using various sizes images?
The slideshow you linked to is set to display in aspect-fit mode. It's hard to tell this is happening but the images are filling the vertical and/or horizontal space depending on their aspect ratio.
The JSSOR slideshow has an option to define how the images are fit, and the example you linked to is set to 'Contain & Actual for Small Image'. This would mean it uses aspect-fit unless the image is too small to fill the height and/or width and it will center the image on the slide.
You can change how the images are fit by clicking the 'Edit This Slider' link, then clicking 'Layout' and changing the Fill Mode on the right side. By default it appears to be set to aspect-fit, or 'Contain & Actual for Small Image'. If you want the images to fill both the height and width, which would require some images to be zoomed in on, you can select cover. This will case each image to fill the entire slide, by zooming and cropping parts of the image.
One day, I had developed similar code in such a case.
I know my code is not a wonderful way, but it runs many javascript codes, so it can make a performance problem.
This is my trial code. I want to help you a little either.
html
<div class="swiper-container thumbnails-preview" data-autoplay="0" data-loop="1"
data-speed="500" data-center="0" data-slides-per-view="1">
<div class="swiper-wrapper">
<div class="swiper-slide active" data-val="0">
<div class="img_content">
<img class="img-responsive" src="img_url"alt="">
<img class="img-responsive" src="img_url"alt="">
...
</div>
</div>
<div class="pagination pagination-hidden poin-style-1"></div>
<div class="arr-t-3">
<div class="swiper-arrow-left sw-arrow"><span class="fa fa-angle-left" style="left: 10px"></span></div>
<div class="swiper-arrow-right sw-arrow"><span class="fa fa-angle-right" style="right: 10px"></span>
</div>
</div>
</div>
</div>
Javascript
$(".img_content").each(function () {
var parentWidth = $(this).width();
var parentHeight = parentWidth * 0.7;
$(this).css("height", parentHeight);
$(this).css("overflow", "hidden");
var target = $(this).children('img');
var width = target.width();
var height = target.height();
var ratioXY = 0.5;
var imgW = $(this).children('img').width();
var imgH = $(this).children('img').height();
//block size
var block_width = $(this).closest(".swiper-container").width();
var block_height = block_width * ratioXY;
//image ratio
var ratio = imgH / imgW;
//image block size
$(this).css("width", block_width);
$(this).css("height", block_height);
$(this).css("overflow", "hidden");
if (ratio > ratioXY) {
$(this).children('img').css("width", "100%");
var gap = (imgH * block_width / imgW - block_height) / 2;
$(this).children('img').css("margin-top", -gap);
}
else {
$(this).children('img').css("height", "100%");
$(this).children('img').css("max-width", 100 / ratio + "%");
var gap = (imgW * block_height / imgH - block_width) / 2;
$(this).children('img').css("margin-left", -gap);
}
});
As a matter of fact, I used idangerous swiper in my code.
However, it is okay to use another one, but I think how to use is almost same this.
Thank you.

jQuery add or remove class when modal open/close

First of all, thanks for reading. I don't know anything about jQuery or JavaScript, that's why I'm here.
Searching a little bit I found the code I want, but unfortunately the gallery I'm making has several elements, and this code doesn't work as I want.
This is the little script I have:
function showImage(imgName) {
var curImage = document.getElementById('currentImg');
var thePath = '/images/full/';
var theSource = thePath + imgName;
curImage.src = theSource;
curImage.alt = imgName;
}
<span class="thumb_ef"><img src="images/thumb/image1.png" alt="Image One"/></span>
<span class="thumb_ef"><img src="images/thumb/image2.png" alt="Image Two"/></span>
<span class="thumb_ef"><img src="images/thumb/image3.png" alt="Image Three"/></span>
<div id="first_window" class="modal_window">
<h2>Title here</h2>
<div id="preview">
<img id="currentImg" class="bigimg" src="images/full/image1.png" alt="images/full/image1.png">
</div>
<h3>Thumbnail preview</h3>
<div id="thumb">
<span class="thumb_mef"><img src="images/full/thumb_image1.png" alt="images/full/thumb_image1.png" onclick="showImage('image1.png');"></span>
<span class="thumb_mef"><img src="images/full/thumb_image2.png" alt="images/full/thumb_image2.png" onclick="showImage('image2.png');"></span>
<span class="thumb_mef"><img src="images/full/thumb_image3.png" alt="images/full/thumb_image3.png" onclick="showImage('image3.png');"></span>
<span class="thumb_mef"><img src="images/full/thumb_image4.png" alt="images/full/thumb_image4.png" onclick="showImage('image4.png');"></span>
</div>
</div>
Let me explain a little bit, because I'm not gonna put all the unnecesary code here.
In the gallery, I have several little images, when you click them, triggers a modal box with different ID for each image in order to load different content for each element.
Inside the modal, I have a title, a full-size image and four thumbnails preview images. This thumbnails images triggers the code I left before, loading the full-size image in the same ID when you click the thumbnail.
The problem I have is... I need to repeat this ID for the different modals, but if you want to click the thumbnails and load the full-size image of any other modal that's not the first, you don't gonna see the changes (Because the code works on the first ID).
I think the solution to this is add the ID (currentImg) only when the modal opens, and after remove this ID when the modal close, to solve the problem.
I don't know how to do that, and probably I need to mix both codes but again, I don't know anything about jQuery/Javascript, here's the modal code:
$(document).ready(function(){
var window_width = $(window).width();
var window_height = $(window).height();
$('.modal_window').each(function(){
var modal_height = $(this).outerHeight();
var modal_width = $(this).outerWidth();
var top = (window_height-modal_height) / 2;
var left = (window_width-modal_width) / 2;
$(this).css({'top' : top , 'left' : left});
});
$('.activate_modal').click(function(){
var modal_id = $(this).attr('name');
show_modal(modal_id);
});
$('.close_modal').click(function(){
close_modal();
});
function close_modal(){
$('#mask').fadeOut(500);
$('.modal_window').fadeOut(500);
}
function show_modal(modal_id){
$('#mask').css({ 'display' : 'block', opacity : 0});
$('#mask').fadeTo(500,0.8);
$('#'+modal_id).fadeIn(500);
}
});
Hope you can understand, my native language isn't english, please tell me if you don't understand.
Fixed: The only thing I need was to search the ID of the modal box, then search the class of the img element and add an ID to that. After this, on the close modal event, remove any ID from the img class.
This is the final result:
$(document).ready(function(){
var window_width = $(window).width();
var window_height = $(window).height();
$('.modal_window').each(function(){
var modal_height = $(this).outerHeight();
var modal_width = $(this).outerWidth();
var top = (window_height-modal_height) / 2;
var left = (window_width-modal_width) / 2;
$(this).css({'top' : top , 'left' : left});
});
$('.activate_modal').click(function(){
var modal_id = $(this).attr('name');
show_modal(modal_id);
$('#'+modal_id).find('.bigimg').attr('id', 'currentImg');
});
$('.close_modal').click(function(){
$('.bigimg').removeAttr('id');
close_modal();
});
function close_modal(){
$('#mask').fadeOut(500);
$('.modal_window').fadeOut(500);
}
function show_modal(modal_id){
$('#mask').css({ 'display' : 'block', opacity : 0});
$('#mask').fadeTo(500,0.8);
$('#'+modal_id).fadeIn(500);
}
});

Javascript image height and other calculation

I was having a problem on getting the height and also calculating other calculations.
I want to get the image height after it has loaded, so I put it on the onload attribute of <img></img> function, here's my code
<p class="test1" style="position:absolute;bottom:0px;">
<img src="'+getBaseURL()+'js/check/no-image.png" rel="fullname"
onload="verticalCenter()"/>
</p>
function verticalCenter(){
var imageHeight = jQuery(".test1 img").height(); //I get a result of 0
var total = imageHeight / 2 + 80
}
I already tried using setTimeout but it still fails.
What I was planning to do here is to set the css of <p class="test1"> into like this:
jQuery(".test1").css("bottom","-"+total);
As I said, this isn't working because I don't get a result in total.
How would I do this, Is there a way to solve this problems, I'm already scratching my head on this.
Thanks in advance!
$(window).load(function () {
var imageHeight = jQuery(".test1 img").height(); //I get a result of 0
var total = imageHeight / 2 + 80
}
<p class="test1" style="position:absolute;bottom:0px;">
<img src="'+getBaseURL()+'js/check/no-image.png" rel="fullname"/>
</p>
You need units on CSS dimensions.
jQuery(".test1").css("bottom","-"+total+"px");
You should also check to make sure that total is the value you are expecting it to be before setting it.
http://jsfiddle.net/jfriend00/yHqr7/
It might be easier to set all the image heights when the form is ready:
$(document).ready(
$('p.text1 img').each(verticalCenter);
)
Unless you're using ajax to load the images; if that is the case, then you should use the live() event:
$('p.text1 img').live(verticalCenter);
Then in your function you can set everything:
function verticalCenter(){
$(this).css('bottom',"-" + ($(this).height() / 2 + 80) + 'px');
}

Adding CSS Class According to Image Ratio

I'm creating an image gallery with dozens of landscape and portrait images on a single page. I want to style each image with a dynamically added CSS class (i.e. ".landscape" for landscape images) according to its orientation.
I came across the code below (from 2003!) For determining the ratio and adding a class for a single image, but I need the classes to be added automatically for all images within a certain div id. Honestly, I just don't know enough about JavaScript or jQuery to solve this on my own.
<script language="JavaScript" type="text/javascript">
<!--
function getDim() {
myImage = new Image;
myImage.src="myimage.gif";//path to image
document.divImage.src=myImage.src;
var imgProp;
var width = myImage.width;
var height = myImage.height;
var ratio = width/height;
if ( ratio > 1 ) {
document.getElementById('image').className="portrait";
}
else {
document.getElementById('image').className="landscape";
}
}
//-->
</script>
with jQuery:
$('#divID img').each(function(){
$(this).addClass(this.width > this.height ? 'landscape' : 'portrait');
});
Pretty straightforward jQuery:
$('#yourId').find('img').each(function(i,elem){
var $this = $(this),
ratio = $this.width() / $this.height();
$this.addClass((ratio < 1) ? 'portrait' : 'landscape');
});
See example →
Lets say, that your containing div is of class gallery and you are using jQuery :)
$(document).ready(function(){
$('.gallery img').each(function(){
var width = $(this).width();
var height = $(this).height();
var className;
if (width/height > 1) className = "portrait";
else className = "landscape";
$(this).addClass(className);
});
});
This way is longer, but allows you to add more rules (if there is any reason to do so :).. ie.:
if (width/height == 1) className = "square";
If setting img width/height interferes with your css, you can set it as data-width/data-height:
$('#your-div-Id').find('img').each(function(i,elem){
var $this = $(this),
ratio = $this.attr('data-width') / $this.attr('data-height');
$this.addClass((ratio < 1) ? 'portrait' : 'landscape');
});
HTML:
<div id="your-div-Id">
<img src="#" data-width="60" data-height="30" />
</div>
Edited mVChr's example

Categories

Resources