开发者

How to hide/show divs from output of array

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 accomplish. The dynamic id that i开发者_StackOverflow社区s 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?


CSS

#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.net/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]').

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜