I have two arrays being generated, one is a group of small images with a unique numerical class attached to it. Then there is a larger version of the image with the same unique number associated to it. I have tried out the solutions listed so far (not the jQuery ones) but none of them are working for me. I am also updating my example to better represent what I am trying to acplish. The dynamic id that is being generated can be part of the small image but added to the whole div container of the big image.
So:
<img id="thumb_1" src="smallimage1.jpg">
<img id="thumb_2" src="smallimage2.jpg">
and
<div id="big_1" style="display:none">
<img class="1" src="largeimage1.jpg">
<p>Stuff</p>
</div>
<div id="big_2" style="display:none">
<img class="2" src="largeimage2.jpg">\
<p>Stuff</p>
</div>
Can I have some suggestions about a way to show each big div depending on which associated small image id is clicked? When another thumb is clicked I need it then to switch the display back to none for the inactive div.
I would like to use jQuery but I think there will be conflicts (even in "noConflict" mode) so I need to figure out a solution using plain javaScript or possibly Prototype. Any suggestions to help me get the ball rolling here?
I have two arrays being generated, one is a group of small images with a unique numerical class attached to it. Then there is a larger version of the image with the same unique number associated to it. I have tried out the solutions listed so far (not the jQuery ones) but none of them are working for me. I am also updating my example to better represent what I am trying to acplish. The dynamic id that is being generated can be part of the small image but added to the whole div container of the big image.
So:
<img id="thumb_1" src="smallimage1.jpg">
<img id="thumb_2" src="smallimage2.jpg">
and
<div id="big_1" style="display:none">
<img class="1" src="largeimage1.jpg">
<p>Stuff</p>
</div>
<div id="big_2" style="display:none">
<img class="2" src="largeimage2.jpg">\
<p>Stuff</p>
</div>
Can I have some suggestions about a way to show each big div depending on which associated small image id is clicked? When another thumb is clicked I need it then to switch the display back to none for the inactive div.
I would like to use jQuery but I think there will be conflicts (even in "noConflict" mode) so I need to figure out a solution using plain javaScript or possibly Prototype. Any suggestions to help me get the ball rolling here?
Share Improve this question edited Dec 27, 2011 at 21:16 Rob W 349k87 gold badges807 silver badges682 bronze badges asked Dec 30, 2010 at 22:55 ZacZac 12.9k21 gold badges77 silver badges124 bronze badges 5- Why do you think there will be conflicts in "noConflict" mode? – Pointy Commented Dec 30, 2010 at 22:58
- Are these are arrays of strings containing HTML or arrays of DOM nodes? – Hemlock Commented Dec 30, 2010 at 23:01
- @Pointy because anytime I try and use jQuery in this site build it breaks the core scripts which were built with Prototype. I am willing to keep trying if that is the only way but I was hoping for another solution – Zac Commented Dec 30, 2010 at 23:05
- @Hemlock the output of the array is html that looks like what my example above – Zac Commented Dec 30, 2010 at 23:05
- oh well I was just curious - I would be very reluctant to suggest adding jQuery to a Prototype site unless you're totally desparate – Pointy Commented Dec 30, 2010 at 23:11
6 Answers
Reset to default 3 +50CSS
#bigImages img { display:none; }
#bigImages img.active { display:block; }
HTML
<div id="smallImages">
<img class="1" src="smallimage1.jpg">
</div>
<div id="bigImages">
<img class="1" src="smallimage1.jpg">
</div>
JS
Event.observe('smallImages','click',function(event){
if(event.target.tagName=='IMG'){
if($$('#bigImages img.active')[0]){
$$('#bigImages img.active')[0].removeClassName('active'); //so you don't have to iterate through all images and conditionally hide them
}
var num = event.target.className;
$$('#bigImages img.'+num)[0].addClassName('active');
}
});
Use some simple, efficient, plain-old JavaScript. A single delegated event handler can do this.
Script:
document.getElementById("smallImages").onclick = function(e) {
if(e.target.tagName.toLowerCase() == 'img') {
var imgNumber = e.target.id.split("_")[1];
document.getElementById("full_" + imgNumber).style.display = 'block';
}
};
Markup:
<div id="smallImages"><img id="thumb_1" alt="foo1"/></div>
<br />
<div id="bigImages"><img id="full_1" alt="foo1" style="display:none"/></div>
Demo: http://jsfiddle/karim79/jMPcX/
This solution assumes you can assign a id to the images (similar to the class attribute) prefixed with big for "big" images and small for "small" images:
Not Using jQuery: EDIT: Removed the reference to jQuery.
<div id="smallImages">
<img id="small1" class="1" src="smallimage1.jpg" onclick="showImage(this)">
</div>
<div id="bigImages">
<img id="big1" class="1" src="largeimage1.jpg" style="display:none">
</div>
<script type="text/javascript">
function showImage(el)
{
var bigImageID = "big" + el.className;
var bigImage = document.getElementById(bigImageID)
if(bigImage)
{
bigImage.style.display = "";
}
else
{
//alert the user
}
}
</script>
Using jQuery:
<div id="smallImages">
<img id="small1" class="1" src="smallimage1.jpg">
</div>
<div id="bigImages">
<img id="big1" class="1" src="largeimage1.jpg" style="display:none">
</div>
<script type="text/javascript">
$("#smallImages img").click
(
function()
{
var bigImageID = "#big" + this.className;
$(bigImageID).css("display", "");
}
)
</script>
<div id="smallImages">
<img class="1" src="smallimage1.jpg" onclick="viewLargImage('largeimage1.jpg');" />
</div>
<script type="text/javascript">
function viewLargImage(url){
var bigImages=document.getElementById("bigImages");
bigImages.innerHTML='<img class="1" src="'+url+'" />';
}
</script>
Well unless you are using prototype, jQuery should not have any conflicts with other libraries, but never the less I'll write both solutions.
jQuery:
$(document).ready(function() {
// get small image div and select all images
$('div#smallImages').children('img').each(function() {
// each function iterates through all img tags inside div
$(this).click(function() { // attach onClick event
// get class name
var class_number = $(this).attr('class');
// find appropriate big image, and get 0, in case there are more images with same class
var big_image = $('div#bigImages').children('img.' + class_number).eq(0);
// do the showing stuff
});
});
});
Plain JavaScript: Now, this can be done by overriding onClick event or creating an Event Listener. Later is the proper way to program things since you can assign more than one event listener to the same object. You can also create event listener object but that might be a stretch. Although using event listeners is the right way to do it, IE (before version 9) has it's own philosophy about this.
function handleImageClick(event) {
}
var small_images = document.getElementById('smallImages').getElementsByTagName('img');
for (var i=0; i<small_images.length; i++)
small_images[i].onclick = handleImageClick;
While plain JavaScript looks simpler it has many downsides so my suggestion is to use jQuery.
Because no one has suggested a Prototype way, and because adding an equally or less capable library is just extra bloat, here is the alternative.
$('smallImages').observe('click', function(event){
var image = event.findElement('img');
if (image != document) {
$('bigImages').select('img').invoke('hide');
$('bigImages').select('.'+image.className).invoke('show');
}
});
However using className
is inadvisable, the small image might have other classes added to it by a later script which would understandably mess things up, or by mistake there may be more than one big image with a matching class. The semantic way would be more like this:
<div id="smallImages">
<a href="#bigImage1" rel="bigImage1">
<img src="smallimage1.jpg" />
</a>
</div>
<div id="bigImages">
<img id="bigImage1" src="largeimage1.jpg" />
</div>
<script type="text/javascript">
$('smallImages').observe('click', showBigImage);
$$('#bigImages img').slice(1).invoke('hide'); // hide all but the first
function showBigImage(event) {
var link = event.findElement('a[rel]');
if (link != document) {
$(link.rel).show().siblings().invoke('hide');
event.stop(); // this event is within an anchor, prevent it from continuing
}
}
</script>
This way is unobtrusive, if javascript is unavailable the smaller images link to the named larger images, all of which are visible so providing a graceful fallback. When javascript is available, all but the first large images are hidden, ensuring that only one is ever shown. The use of rel
makes more sense and is something we can check with findElement('a[rel]')
.