Search code examples
javascriptjqueryhtmlcssjcarousel

jcarousel - How do I link an image to a url?


Using jcarousel connected carousels, I would like to link each image to an url. I have tried adding link tags around each image, but the link only works if the image is the first or the last in the slideshow, otherwise, clicking on the image skips to the next slide. An example can be seen here: https://www.bostonrescue.net/special-needs-spotlight/special-needs-spotlight.html

HEAD:

<link href="../styles.css" rel="stylesheet" type="text/css"/>
<link href="../jcarousel.connected-carousels.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> 
<script type="text/javascript" src="/scripts/jquery.jcarousel.min.js"></script>
<script type="text/javascript" src="/scripts/jcarousel.connected-carousels.js"></script>

HTML:

<div class="connected-carousels">
  <div class="stage">
    <div class="carousel carousel-stage">
      <ul>
        <li><a href="/url_1.html"><img src="/image_1.jpg" alt="Image 1" /></a><br /><a href="/url_1.html">Image 1</a></li>
        <li><a href="/url_2.html"><img src="/image_2.jpg" alt="Image 2" /></a><br /><a href="/url_2.html">Image 2</a></li>
        <li><a href="/url_3.html"><img src="/image_3.jpg" alt="Image 3" /></a><br /><a href="/url_3.html">Image 3</a></li>                          
      </ul>
    </div>
    <a href="#" class="prev prev-stage"><span>&lsaquo;</span></a>
    <a href="#" class="next next-stage"><span>&rsaquo;</span></a>
</div>

CSS:

 /** Stage container **/

.connected-carousels .stage {
    width: 585px;
    margin: 20px auto;
    position: relative;
}

.connected-carousels .carousel img {
    border-style: solid;
    border-width: 2px;
    margin: 0px 5px 5px 0px;
    height: 200px;
}

.connected-carousels .photo-credits {
    position: absolute;
    right: 15px;
    bottom: 0;
    font-size: 13px;
    color: #fff;
    text-shadow: 0 0 1px rgba(0, 0, 0, 0.85);
    opacity: .66;
}

.connected-carousels .photo-credits a {
    color: #fff;
}

/** Navigation container **/

.connected-carousels .navigation {
    width: 500px;
    margin: 20px auto;
    position: relative;
}

/** Shared carousel styles **/

.connected-carousels .carousel {
    overflow: hidden;
    position: relative;
}

.connected-carousels .carousel ul {
    width: 20000em;
    position: relative;
    list-style: none;
    margin: 0;
    padding: 0;
}

.connected-carousels .carousel li {
    float: left;
    text-align: center;
}

/** Stage carousel specific styles **/

.connected-carousels .carousel-stage {
    height: 225px;
    border: 10px solid #fff;
    -webkit-border-radius: 5px;
       -moz-border-radius: 5px;
            border-radius: 5px;
    -webkit-box-shadow: 0 0 2px #999;
       -moz-box-shadow: 0 0 2px #999;
            box-shadow: 0 0 2px #999;
}

/** Navigation carousel specific styles **/

.connected-carousels .carousel-navigation {
    height: 60px;
    width: 480px;
    background: #fff;
    border: 10px solid #fff;
    -webkit-border-radius: 5px;
       -moz-border-radius: 5px;
            border-radius: 5px;
    -webkit-box-shadow: 0 0 2px #999;
       -moz-box-shadow: 0 0 2px #999;
            box-shadow: 0 0 2px #999;
}

.connected-carousels .carousel-navigation li {
    cursor: pointer;
}

.connected-carousels .carousel-navigation li img {
    display: block;
    border: 5px solid #fff;
}

.connected-carousels .carousel-navigation li.active img {
    border-color: #ccc;
}

/** Stage carousel controls **/

.connected-carousels .prev-stage,
.connected-carousels .next-stage {
    display: block;
    position: absolute;
    top: 0;
    width: 305px;
    height: 410px;
    color: #fff;
}

.connected-carousels .prev-stage {
    left: 0;
}

.connected-carousels .next-stage {
    right: 0;
}

.connected-carousels .prev-stage.inactive,
.connected-carousels .next-stage.inactive {
    display: none;
}

.connected-carousels .prev-stage span,
.connected-carousels .next-stage span {
    display: none;
    position: absolute;
    top: 25%;
    width: 30px;
    height: 30px;
    text-align: center;
    background: #4E443C;
    color: #fff;
    text-decoration: none;
    text-shadow: 0 0 1px #000;
    font: 24px/27px Arial, sans-serif;
    -webkit-border-radius: 30px;
       -moz-border-radius: 30px;
            border-radius: 30px;
    -webkit-box-shadow: 0 0 2px #999;
       -moz-box-shadow: 0 0 2px #999;
            box-shadow: 0 0 2px #999;
}

.connected-carousels .prev-stage span {
    left: 20px;
}

.connected-carousels .next-stage span {
    right: 20px;
}

.connected-carousels .prev-stage:hover span,
.connected-carousels .next-stage:hover span {
    display: block;
}

/** Navigation carousel controls **/

.connected-carousels .prev-navigation,
.connected-carousels .next-navigation {
    display: block;
    position: absolute;
    width: 30px;
    height: 30px;
    background: #4E443C;
    color: #fff;
    text-decoration: none;
    text-shadow: 0 0 1px #000;
    font: 16px/29px Arial, sans-serif;
    -webkit-border-radius: 30px;
       -moz-border-radius: 30px;
            border-radius: 30px;
    -webkit-box-shadow: 0 0 2px #999;
       -moz-box-shadow: 0 0 2px #999;
            box-shadow: 0 0 2px #999;
}

.connected-carousels .prev-navigation {
    left: -15px;
    top: 22px;
    text-indent: 6px;
}

.connected-carousels .next-navigation {
    right: -15px;
    top: 22px;
    text-indent: 20px;
}

.connected-carousels .prev-navigation.inactive,
.connected-carousels .next-navigation.inactive {
    opacity: .5;
    cursor: default;
}

JAVASCRIPT: jcarousel.connected-carousels.js (connector function loaded in addition to jquery.jcarousel.min.js)

(function($) {
    // This is the connector function.
    // It connects one item from the navigation carousel to one item from the
    // stage carousel.
    // The default behaviour is, to connect items with the same index from both
    // carousels. This might _not_ work with circular carousels!
    var connector = function(itemNavigation, carouselStage) {
        return carouselStage.jcarousel('items').eq(itemNavigation.index());
    };

    $(function() {
        // Setup the carousels. Adjust the options for both carousels here.
        var carouselStage      = $('.carousel-stage').jcarousel();
        var carouselNavigation = $('.carousel-navigation').jcarousel();

        // We loop through the items of the navigation carousel and set it up
        // as a control for an item from the stage carousel.
        carouselNavigation.jcarousel('items').each(function() {
            var item = $(this);

            // This is where we actually connect to items.
            var target = connector(item, carouselStage);

            item
                .on('jcarouselcontrol:active', function() {
                    carouselNavigation.jcarousel('scrollIntoView', this);
                    item.addClass('active');
                })
                .on('jcarouselcontrol:inactive', function() {
                    item.removeClass('active');
                })
                .jcarouselControl({
                    target: target,
                    carousel: carouselStage
                });
        });

        // Setup controls for the stage carousel
        $('.prev-stage')
            .on('jcarouselcontrol:inactive', function() {
                $(this).addClass('inactive');
            })
            .on('jcarouselcontrol:active', function() {
                $(this).removeClass('inactive');
            })
            .jcarouselControl({
                target: '-=1'
            });

        $('.next-stage')
            .on('jcarouselcontrol:inactive', function() {
                $(this).addClass('inactive');
            })
            .on('jcarouselcontrol:active', function() {
                $(this).removeClass('inactive');
            })
            .jcarouselControl({
                target: '+=1'
            });

        // Setup controls for the navigation carousel
        $('.prev-navigation')
            .on('jcarouselcontrol:inactive', function() {
                $(this).addClass('inactive');
            })
            .on('jcarouselcontrol:active', function() {
                $(this).removeClass('inactive');
            })
            .jcarouselControl({
                target: '-=1'
            });

        $('.next-navigation')
            .on('jcarouselcontrol:inactive', function() {
                $(this).addClass('inactive');
            })
            .on('jcarouselcontrol:active', function() {
                $(this).removeClass('inactive');
            })
            .jcarouselControl({
                target: '+=1'
            });
    });
})(jQuery);

Solution

  • In order to achieve your result you need to change the height, width of your:

    .connected-carousels .prev-stage,
    .connected-carousels .next-stage
    

    var connector = function(itemNavigation, carouselStage) {
        return carouselStage.jcarousel('items').eq(itemNavigation.index());
    };
    
    $(function() {
        // Setup the carousels. Adjust the options for both carousels here.
        var carouselStage      = $('.carousel-stage').jcarousel();
        var carouselNavigation = $('.carousel-navigation').jcarousel();
    
        // We loop through the items of the navigation carousel and set it up
        // as a control for an item from the stage carousel.
        carouselNavigation.jcarousel('items').each(function() {
            var item = $(this);
    
            // This is where we actually connect to items.
            var target = connector(item, carouselStage);
    
            item
                    .on('jcarouselcontrol:active', function() {
                        carouselNavigation.jcarousel('scrollIntoView', this);
                        item.addClass('active');
                    })
                    .on('jcarouselcontrol:inactive', function() {
                        item.removeClass('active');
                    })
                    .jcarouselControl({
                        target: target,
                        carousel: carouselStage
                    });
        });
    
        // Setup controls for the stage carousel
        $('.prev-stage')
                .on('jcarouselcontrol:inactive', function() {
                    $(this).addClass('inactive');
                })
                .on('jcarouselcontrol:active', function() {
                    $(this).removeClass('inactive');
                })
                .jcarouselControl({
                    target: '-=1'
                });
    
        $('.next-stage')
                .on('jcarouselcontrol:inactive', function() {
                    $(this).addClass('inactive');
                })
                .on('jcarouselcontrol:active', function() {
                    $(this).removeClass('inactive');
                })
                .jcarouselControl({
                    target: '+=1'
                });
    
        // Setup controls for the navigation carousel
        $('.prev-navigation')
                .on('jcarouselcontrol:inactive', function() {
                    $(this).addClass('inactive');
                })
                .on('jcarouselcontrol:active', function() {
                    $(this).removeClass('inactive');
                })
                .jcarouselControl({
                    target: '-=1'
                });
    
        $('.next-navigation')
                .on('jcarouselcontrol:inactive', function() {
                    $(this).addClass('inactive');
                })
                .on('jcarouselcontrol:active', function() {
                    $(this).removeClass('inactive');
                })
                .jcarouselControl({
                    target: '+=1'
                });
    });
    /** Stage container **/
    .connected-carousels .stage {
        width: 450px;
        margin: 20px auto;
        position: relative;
    }
    
    .connected-carousels .carousel img {
        border-style: solid;
        border-width: 2px;
        margin: 0px 5px 5px 0px;
        height: 200px;
    }
    
    .connected-carousels .photo-credits {
        position: absolute;
        right: 15px;
        bottom: 0;
        font-size: 13px;
        color: #fff;
        text-shadow: 0 0 1px rgba(0, 0, 0, 0.85);
        opacity: .66;
    }
    
    .connected-carousels .photo-credits a {
        color: #fff;
    }
    
    /** Navigation container **/
    .connected-carousels .navigation {
        width: 500px;
        margin: 20px auto;
        position: relative;
    }
    
    /** Shared carousel styles **/
    .connected-carousels .carousel {
        overflow: hidden;
        position: relative;
    }
    
    .connected-carousels .carousel ul {
        width: 20000em;
        position: relative;
        list-style: none;
        margin: 0;
        padding: 0;
    }
    
    .connected-carousels .carousel li {
        float: left;
        text-align: center;
    }
    
    /** Stage carousel specific styles **/
    .connected-carousels .carousel-stage {
        height: 250px;
        border: 10px solid #fff;
        -webkit-border-radius: 5px;
        -moz-border-radius: 5px;
        border-radius: 5px;
        -webkit-box-shadow: 0 0 2px #999;
        -moz-box-shadow: 0 0 2px #999;
        box-shadow: 0 0 2px #999;
    }
    
    /** Navigation carousel specific styles **/
    .connected-carousels .carousel-navigation {
        height: 60px;
        width: 480px;
        background: #fff;
        border: 10px solid #fff;
        -webkit-border-radius: 5px;
        -moz-border-radius: 5px;
        border-radius: 5px;
        -webkit-box-shadow: 0 0 2px #999;
        -moz-box-shadow: 0 0 2px #999;
        box-shadow: 0 0 2px #999;
    }
    
    .connected-carousels .carousel-navigation li {
        cursor: pointer;
    }
    
    .connected-carousels .carousel-navigation li img {
        display: block;
        border: 5px solid #fff;
    }
    
    .connected-carousels .carousel-navigation li.active img {
        border-color: #ccc;
    }
    
    /** Stage carousel controls **/
    .connected-carousels .prev-stage,
    .connected-carousels .next-stage {
        display: block;
        position: absolute;
        top: 100px;
        left: 410px;
        width: 30px;
        height: 20px;
        color: #fff;
    }
    
    .connected-carousels .prev-stage {
        left: 0;
    }
    
    .connected-carousels .next-stage {
        right: 0;
    }
    
    .connected-carousels .prev-stage.inactive,
    .connected-carousels .next-stage.inactive {
        display: none;
    }
    
    .connected-carousels .prev-stage span,
    .connected-carousels .next-stage span {
        display: none;
        position: absolute;
        top: 25%;
        width: 30px;
        height: 30px;
        text-align: center;
        background: #4E443C;
        color: #fff;
        text-decoration: none;
        text-shadow: 0 0 1px #000;
        font: 24px/27px Arial, sans-serif;
        -webkit-border-radius: 30px;
        -moz-border-radius: 30px;
        border-radius: 30px;
        -webkit-box-shadow: 0 0 2px #999;
        -moz-box-shadow: 0 0 2px #999;
        box-shadow: 0 0 2px #999;
    }
    
    .connected-carousels .prev-stage span {
        left: 20px;
    }
    
    .connected-carousels .next-stage span {
        right: 20px;
    }
    
    .connected-carousels .prev-stage:hover span,
    .connected-carousels .next-stage:hover span {
        display: block;
    }
    
    /** Navigation carousel controls **/
    .connected-carousels .prev-navigation,
    .connected-carousels .next-navigation {
        display: block;
        position: absolute;
        width: 30px;
        height: 30px;
        background: #4E443C;
        color: #fff;
        text-decoration: none;
        text-shadow: 0 0 1px #000;
        font: 16px/29px Arial, sans-serif;
        -webkit-border-radius: 30px;
        -moz-border-radius: 30px;
        border-radius: 30px;
        -webkit-box-shadow: 0 0 2px #999;
        -moz-box-shadow: 0 0 2px #999;
        box-shadow: 0 0 2px #999;
    }
    
    .connected-carousels .prev-navigation {
        left: -15px;
        top: 22px;
        text-indent: 6px;
    }
    
    .connected-carousels .next-navigation {
        right: -15px;
        top: 22px;
        text-indent: 20px;
    }
    
    .connected-carousels .prev-navigation.inactive,
    .connected-carousels .next-navigation.inactive {
        opacity: .5;
        cursor: default;
    }
    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jcarousel/0.3.5/jquery.jcarousel.min.js"></script>
    
    
    <div class="connected-carousels">
        <div class="stage">
            <div class="carousel carousel-stage">
                <ul>
                    <li><a href="/url_1.html"><img src="https://dummyimage.com/100x100/fff/000&text=1" alt="Image 1" /></a><br /><a href="/url_1.html">Image 1</a></li>
                    <li><a href="/url_2.html"><img src="https://dummyimage.com/100x100/fff/000&text=2" alt="Image 2" /></a><br /><a href="/url_2.html">Image 2</a></li>
                    <li><a href="/url_3.html"><img src="https://dummyimage.com/100x100/fff/000&text=3" /></a><br /><a href="/url_3.html">Image 3</a></li>
                    <li><a href="/url_4.html"><img src="https://dummyimage.com/100x100/fff/000&text=4" /></a><br /><a href="/url_4.html">Image 4</a></li>
                    <li><a href="/url_5.html"><img src="https://dummyimage.com/100x100/fff/000&text=5" /></a><br /><a href="/url_5.html">Image 5</a></li>
                </ul>
            </div>
            <a href="#" class="prev prev-stage"><span>&lsaquo;</span></a>
            <a href="#" class="next next-stage"><span>&rsaquo;</span></a>
        </div>
    </div>