最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - jQuery image crossfade with pre-loader - Stack Overflow

programmeradmin4浏览0评论

I want a simple image crossfade, similar to /, but with a pre-loader. Is there a good jQuery plugin that does both? Also, I'm not looking for a load bar.

This question is close, but not the same => jQuery Crossfade Plugin

It would be great if it was a solution that defaulted to CSS3, but would otherwise fall back to JS to keep the processing native as possible.

Looking for something that..

  • will autoplay
  • without controls
  • will go to the next image based on time setting, ie. 5 seconds, unless the next image isn't loaded in which case it finishes loading the image and then displays it.
  • crossfade transition, not fade to black or white, but cross-fade. from the start it would fadein.
  • no thumbnails or galleries, etc. just the image
  • If images could be CSS background images, that would be best, so users can't drag out the image simply
  • Each panel needs to be clickable so a user could click the image and go to a part of the website.

I want a simple image crossfade, similar to http://malsup./jquery/cycle/, but with a pre-loader. Is there a good jQuery plugin that does both? Also, I'm not looking for a load bar.

This question is close, but not the same => jQuery Crossfade Plugin

It would be great if it was a solution that defaulted to CSS3, but would otherwise fall back to JS to keep the processing native as possible.

Looking for something that..

  • will autoplay
  • without controls
  • will go to the next image based on time setting, ie. 5 seconds, unless the next image isn't loaded in which case it finishes loading the image and then displays it.
  • crossfade transition, not fade to black or white, but cross-fade. from the start it would fadein.
  • no thumbnails or galleries, etc. just the image
  • If images could be CSS background images, that would be best, so users can't drag out the image simply
  • Each panel needs to be clickable so a user could click the image and go to a part of the website.
Share Improve this question edited May 23, 2017 at 10:29 CommunityBot 11 silver badge asked Oct 5, 2011 at 1:37 Kirk StrobeckKirk Strobeck 18.6k21 gold badges81 silver badges122 bronze badges 2
  • for preloading and to hijack image loading to indicate progress you will need to construct the img tags on the front end... Are you ok with this? ie passing a json object of images? – samccone Commented Oct 7, 2011 at 17:59
  • here is an example of what I am talking about jsfiddle/samccone/QTEk6 – samccone Commented Oct 7, 2011 at 18:08
Add a ment  | 

4 Answers 4

Reset to default 6 +75

Well, here's my poke at it. The preloader is in vanilla js and the slideshow loop is in jQuery. It's very simple to implement and the concept is even simpler.

Demo

a very simple Demo that illustrates the DOM manipulation approach


HTML

<!-- not much here... just a container -->
<div id="content"></div>

CSS

/* just the important stuff here.  The demo has example styling. */
#content
{
    position:relative;
}
#content img
{
    position:absolute;
}

javascript/jQuery

// simple array
var images = [
    "http://imaging.nikon./lineup/dslr/d90/img/sample/pic_003t.jpg",
    "http://imaging.nikon./lineup/dslr/d90/img/sample/pic_005t.jpg",
    "http://imaging.nikon./lineup/dslr/d90/img/sample/pic_001t.jpg"
];

// some adjustable variables
var delay = 2000;
var transition = 1000;

// the preloader
for(var i in images)
{
    var img = document.createElement("img");
    img.src = images[i];
    img.onload = function(){
        var parent = document.getElementById("content");
        parent.insertBefore(this,parent.childNodes[0]);
        if(i == images.length - 1)
        {
            i = 0;
            startSlides();
        }
    }
}

// and the actual loop
function startSlides()
{
    $("#content img:last").delay(delay).fadeTo(transition,0,function(){
        $(this).insertBefore($(this).siblings(":first")).fadeTo(0,1);
        startSlides();
    });
}

The concept in brief is to fade the first image in a container, once plete change it's position in the DOM (effectively hiding it behind equal tree level siblings), and call the function again. The reason why this works is because it only fades the first child of the container, but on callback it changes what node that is constantly looping the nodes. This makes for a very small source file that is quite effective.

EDIT 1:


and 32 minutes tweaking later...

Demo 2

EDIT 2:


My oh so simple script is now very plicated :P I added in some scaling features that only work on modern browsers but are there if needed. This one also has a loading bar as it preloads the images (may or may not be desirable :P)

small images demo

large images demo

I think you can still do this with the jQuery cycle plugin; other than image preloading, even the jQuery cycle lite version does everything you want by default out-of-the-box.

And if you look here, you'll see that it's pretty simple to add a little Javascript that will add images (after the first two) as they load. You would need to modify the code a little (instead of stack.push(this), you'd want something like stack.push("<div style="background-image:url("+img.src+")"></div>"), for example) but I think it's totally doable.

Edit: here's a link to a SO question about how to make a div into a clickable link.

Edit 2: I liked Joseph's idea to just move the elements to a hidden DIV, so I updated my code a bit. It now also preserves the links each div points to as well: http://jsfiddle/g4Hmh/9/

Edit 3: Last update! http://jsfiddle/g4Hmh/12/

UPDATE Added the ability to load everything asynchronously.

A wrapper for the jQuery cycle plugin should suffice. You really just need something that monitors if the images loaded and then calls $(elem).cycle(/* options */). Here's my take:

$.fn.cycleWhenLoaded = function(options) {
    var target = this,
        images = options.images,
        loaded = 0,
        total  = 0,
        i;

    if(images) {
        for(i = 0; i < images.length; i ++) {
            $('<img/>').attr('src', images[i]).appendTo(target);
        }
    }

    this.find('> img').each(function(index) {
        var img = new Image(),
            source = this;

        total ++;

        if(index > 1)
            $(this).hide();

        img.onload = function() {
            loaded ++;
            if(loaded == total) {
                target.trigger('preloadplete');
                target.cycle(options);
            }
        };

        setTimeout(function() {img.src = source.src}, 1);
    });

    return this;
};

This allows you to either do a simple delay load:

$('.slideshow').cycleWhenLoaded({
    fx: 'fade'
});

Or you can do something more plicated and load your images in the script and capture the preload plete event:

$('.slideshow2').hide().cycleWhenLoaded({
    fx: 'fade',
    images: [
        "http://cloud.github./downloads/malsup/cycle/beach1.jpg",
        "http://cloud.github./downloads/malsup/cycle/beach2.jpg",
        "http://cloud.github./downloads/malsup/cycle/beach3.jpg",
        "http://cloud.github./downloads/malsup/cycle/beach4.jpg",
        "http://cloud.github./downloads/malsup/cycle/beach5.jpg"
    ]
}).bind('preloadplete', function() { $(this).show(); });

You can see it in action here: http://fiddle.jshell/vmAEW/1/

I don't know how close this is to what you are looking for, but I figured since no one else did I would at least try to help. http://galleria.aino.se/

It at least has a preloader and a fade transition.

发布评论

评论列表(0)

  1. 暂无评论