I have a page that is a series of N img elements. I need each image to, when clicked, change to the next image in their own series of three. I have listed my html below to explain.
<body>
<div class="images">
<div class="image_group">
<img id="first" src="group1_image1"></img>
<img id="second" src="group1_image2"></img> //this isn't displayed until clicked
<img id="third" src="group1_image3"></img> //when this is displayed, it cycles back to group1image1
</div>
...
<div class="image_group">
<img id="first" src="groupN_image1"></img>
<img id="second" src="groupN_image2"></img>
<img id="third" src="groupN_image3"></img>
</div>
</div>
</body>
Each image_group div displays only one image until clicked, when it displays the second, then the third when clicked, then cycles back to the first when clicked a third time.
My problem is writing a JQuery method that can do this cycling by making "second" images replace "first" images when clicked and so on. The below method rewrites the image source which seems silly but I can't think of a better way to do it. I'm also not sure if the "first" class image will be isolated in the "image_group" div (as it should) or if it will change all images on the page to their "second" class image.
$("#first").attr("src","group1_image2.jpg");
Can anyone think of a way to do this?
I would do something like this
$("image_group img").on("click", function() {
var index = $(this).index();
$(this).attr("src", index === $("img").length - 1 ? $(this).next().src : $("img")[0].src);
});
refine your html:
<body>
<div class="images">
<div class="image_group">
<img id="1,1" data_num="1,1" src="group1_image1"></img>
</div>
...
<div class="image_group">
<img id="n,1" data_num="n,1" src="groupN_image1"></img>
</div>
</div>
</body>
and then you might do something like:
$("image_group img").on("click", function() {
var max = 3;
var indexes = $(this).data('num').split(',');
if ( indexes[1] == max
indexes[1] = 1;
else
indexes[1]++;
$(this).attr("src", "group" + indexes[0] + "_image" + indexes[1]);
$(this).data('num', indexes.join(','))
});
Related
Online example of my goal:
I'm trying to display bike products on a category page. On each product there's a frame variant color, I'm displaying that using round divs.
When I click a color, the image should change as you can see on Specialized website: (underneath the product image) Specialized Example.
My own website
You can see my own example here: My own website example (scroll down till you see the product with multiple products).
My target functionality:
When I click the GREEN div I'd like to show picture 2 and when I click the RED div I'd like to see image 3, but as Default it will always be the firs
The first color = the first image
The second color = the second image
And so forth
My HTML:
<div class="frameColors">
<div class="frameColor" data-color="#95BD40" style="background-color:#95BD40"></div>
<div class="frameColor" data-color="#000000" style="background-color:#000000"></div>
<div class="frameColor" data-color="#C6352D" style="background-color:#C6352D"></div>
</div>
<a href="/produkter/cykler/mountain-bikes/specialized/epic-hardtails/epic-hardtail/">
<div class="categoryImage" data-frame-color="95BD40">
<img src="/media/1072/165519.jpg?anchor=center&mode=crop&width=500&height=350&rnd=131200748910000000" class="productImage">
</div>
<div class="categoryImage" data-frame-color="000000">
<img src="/media/1071/165518.jpg?anchor=center&mode=crop&width=500&height=350&rnd=131200746750000000" class="productImage">
</div>
<div class="categoryImage" data-frame-color="C6352D">
<img src="/media/1073/166762.jpg?anchor=center&mode=crop&width=500&height=350&rnd=131200749050000000" class="productImage">
</div>
</a>
My Foreach(s):
var imageIds = item.GetPropertyValue<string>("productImages").Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
var images = Umbraco.Media(imageIds);
<div class="frameColors">
#foreach (var bikeColor in images)
{
var color = bikeColor.GetPropertyValue("frameColor");
<div class="frameColor" data-color="##color" style="background-color:##color"></div>
}
</div>
<a href="#item.Url">
#foreach (var img in images)
{
<div class="categoryImage" data-frame-color="#img.GetPropertyValue("frameColor")">
<img src="#img.GetCropUrl("product image")" class="productImage" />
</div>
}
</a>
Based on Adeneo reply I managed to modify the code a little so it worked out as I wanted.
First, I added a css line: .categoryImage { display:none; } to hide ALL the product images.
I then added the script based on Adeneo's reply. I start off with targeting EACH of the .frameColor divs and inside that, I added this the following line to show the first image: categoryImage.first().show();
If the CSS line is not included, all of the product images will be displayed by default, so it was necessary to HIDE all the images and inside the script, show the first image.
$(function () {
$(".frameColor").each(function () {
var categoryImage = $(this).parent("div").next("a").find(".categoryImage");
categoryImage.first().show();
if ($(categoryImage).length > 1) {
$(this).on('click', function () {
var color = $(this).data('color').replace('#', '');
$(categoryImage).hide().filter(function () {
return $(this).data('frame-color') === color;
}).show();
});
}
else {
$(this).hide();
}
});
});
Credits goes to Adeneo for providing the original script.
I have an HTML img tag with an empty src and I use JSON and jquery to retrieve the src of the img from the database when the user hovers over a parent span that contain the img tag. The problem is when I retrieve the src with JSON everything is fine and the image src is retrieved but I a loop set for this span in the very same page, so when the first image is already retrieved it's src is applied for the other looped span images. It is like retrieving the same id of the first image for the other different looped images that suppose to have different id for different content image contents.
here's is my code :
$(document).ready(function(){
$('#key').hover(function(){
var id=$('#im').attr('value');
$.post('getjson.php',{id:id},function(data){
$('img').attr('src',data.user_img);
},'json');
});
});
Here is the HTML
{loop="data"} <span class="foo" id="key">{$value.user_key}</span> <span class="foo">
<img alt="ther is an image here" src="" value="{$value.id}" id="im"/></span>
The problem is that you have duplicated IDs on your page. So, $('#key') will always return the first DIV with the id key, the same for $('#im'). Instead this $('img') will select all images on your page. Here is a demo to illustrate the problem:
console.log("$('#key') count:"+$('#key').length);
console.log("$('#img') count:"+$('#key').length);
console.log("$('img') count:"+$('img').length);
$('#key').hover(function(){
console.log("ID hovered: "+$('#im').attr('value'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="key"> Div 1
<img src="" id="im" value="1" />
</div>
<div id="key"> Div 2
<img src="" id="im" value="2" />
</div>
<div id="key"> Div 3
<img src="" id="im" value="3" />
</div>
<div id="key"> Div 4
<img src="" id="im" value="4" />
</div>
To solve that you need to use another selector, for example, use a class:
$(document).ready(function(){
$('.my-selector').hover(function(){
//This will select all images inside 'this' (hovered .key)
var img = $('img', this);
$.post('getjson.php',{id : img.attr('value')},function(data){
img.attr('src',data.user_img);
},'json');
});
});
HTML:
{loop="data"} <div class="my-selector"> <!-- add parent div -->
<span class="foo" id="key">{$value.user_key}</span>
<span class="foo">
<img alt="ther is an image here" src="" value="{$value.id}" id="im"/>
</span>
</div>
Try changing
$('img').attr('src',data.user_img);
to
$("img[value='"+ id +"']").attr('src',data.user_img);
It is because you are setting the source to all images on the page.
$('img') should be replaced with $('#key')
in your case the code should be :
$(document).ready(function(){
$('#key').hover(function(){
var img = this;
var id=$('#im').attr('value');
$.post('getjson.php',{id:id},function(data){
$(img).attr('src',data.user_img);
},'json');
});
});
I'm using jquery-zoom and I have 4 images for a product on my website, when clicking one of the 4 images, I want the main image to change to the clicked image and still zoomable with jquery-zoom, now everytime when click different images, the main image gets updated to the clicked one but it's no longer zoomable, it's only zoomable when the page reloaded... How should I make my desired effect happen? Currently my code looks like this:
HTML:
<div class="product-main-image">
<img id="product-zoomable-image"src="/images/image1.jpg" alt="无图片" class="img-responsive" data-BigImgsrc="/images/image1.jpg">
</div>
<div class="product-other-images">
<img alt="无图片" src="/images/image1.jpg">
<img alt="无图片" src="/images/image2.jpg">
<img alt="无图片" src="/images/image3.jpg">
<img alt="无图片" src="/images/image4.jpg">
</div>
Javascript:
$('.product-carousel-image').click(function(event) { // change image shown as product image
var newImageUrl = $(this).attr('href');
console.log(newImageUrl) ;
$('#product-zoomable-image').attr('src', newImageUrl);
$('#product-zoomable-image').trigger('zoom.destroy');
$('#product-zoomable-image').zoom({url: newImageUrl});
});
Just figured out by myself, need to destroy the zoomImg first and then create another:
$('.product-carousel-image').click(function(event) { // change image shown as product image
var newImageUrl = $(this).attr('href');
$('#product-zoomable-image').attr('src', newImageUrl);
$('.product-main-image').trigger('zoom.destroy');
$('.product-main-image').zoom({url: newImageUrl});
});
I have a list of elements similar to simplified HTML below. When one of the images is clicked some JavaScript if fired, and the image that is clicked becomes this.theImage.
I now need to get the position of the image; for example if the first image was clicked, the position should be 1, if the second is clicked it should be 2, and so on.
I could use var elements = $('.image-preview', '#gallery');, to take a list of all elements with the image-preview class, and then loop through them and match the ID to the image, but that seems really inefficient.
Is there another way of achieving this task that is more efficient?
<div id="gallery">
<div class="image-preview">
<img id="image-1" src="http://www.mysite.com/image1.jpg" />
</div>
<div class="image-preview">
<img id="image-2" src="http://www.mysite.com/image2.jpg" />
</div>
<div class="image-preview">
<img id="image-3" src="http://www.mysite.com/image3.jpg" />
</div>
<div class="image-preview">
<img id="image-4" src="http://www.mysite.com/image4.jpg" />
</div>
</div>
Not sure I get it, you catch a click on the image like this
$('.image-preview img').on('click', function() {
});
and then to get the index you'd do
$('.image-preview img').on('click', function() {
var index = $('.image-preview img').index(this);
});
note that it's zero based
FIDDLE
You can make Array.prototype.indexOf do it for you:
var gallery = document.getElementById('gallery'),
els = [].slice.call(gallery.getElementsByTagName('img'));
gallery.onclick = function(e) {
if(e.target.tagName.toLowerCase() !== 'img') return;
var position = els.indexOf(e.target);
};
Demo
As the title suggests, I'm looking to have a little bit of jQuery - if an image is less than a defined width, it adds a class a certain element. This, for me, seems pretty easy but for some reason it's not working.
$(document).ready(function() {
var image = $('.work-each img');
if (image.width() < 500) {
$('.work-text').addClass('work-text-small');
}
});
This, should, add a class 'work-text-small' to the element 'work-text' if the image found under each .work-each is less than 500px.
Example of HTML (for each)
<div class="work-each">
<div>
<img src=""/>
<div class="work-text">
<p>Title</p>
<p>Text</p>
</div>
</div>
</div>
<div class="work-each">
<div>
<img src=""/>
<div class="work-text">
<p>Title</p>
<p>Text</p>
</div>
</div>
</div>
<div class="work-each">
<div>
<img src=""/>
<div class="work-text">
<p>Title</p>
<p>Text</p>
</div>
</div>
</div>
Thanks,
R
Use load instead, when DOM is ready only img tag is defined but the image isn't loaded yet. Its size comes when it's fully loaded
$(window).load(function () {
var image = $('.work-each img');
if (image.width() < 500) {
$('.work-text').addClass('work-text-small');
}
});
However as #rdck pointed if there are more images with class=".work-each img" code won't work so in that case you go trough each image and apply the class
$(window).load(function () {
var image = $('.work-each img');
image.each(function () {
var that = $(this);
if (that.width() < 500) {
that.next('div.work-text').addClass('work-text-small');
}
})
});
If you get dimensions using server code and set class accordingly, there would be no need to wait for image to load and css would immediately take effect as soon as html exists