Jump to content

w3.css Image Carousel - Combined Auto & Manual


Goodness

Recommended Posts

I'm hoping someone can help me with this one.

 

I'm using the script from the following template Try It example for an image carousel:

 

http://www.w3schools.com/w3css/tryit.asp?filename=tryw3css_templates_marketing&stacked=h

 

Here's the script:

<script>

// Slideshow script
var slideIndex = 1;
showDivs(slideIndex);

function plusDivs(n) {
  showDivs(slideIndex += n);
}

function currentDiv(n) {
  showDivs(slideIndex = n);
}

function showDivs(n) {
  var i;
  var x = document.getElementsByClassName("mySlides");
  var dots = document.getElementsByClassName("demodots");
  if (n > x.length) {slideIndex = 1}    
  if (n < 1) {slideIndex = x.length} ;
  for (i = 0; i < x.length; i++) {
     x[i].style.display = "none";  
  }
    
  for (i = 0; i < dots.length; i++) {
     dots[i].className = dots[i].className.replace(" w3-white", "");
  }
  x[slideIndex-1].style.display = "block";  
  dots[slideIndex-1].className += " w3-white";
}
</script>

I also have this in the <head> inside a <style tag>:

.mySlides {display:none}
.w3-left, .w3-right, .w3-tag {cursor:pointer}
.w3-tag {height:15px;width:15px;padding:0;margin-top:6px}

Lastly, just under the carousel is the following to create the next/previous and individual, clickable, controls:

<!-- Slideshow next/previous buttons -->
  <div class="w3-container w3-dark-grey w3-padding-8 w3-xlarge">
    <div class="w3-left" onclick="plusDivs(-1)"><i class="fa fa-arrow-circle-left w3-hover-text-zot-red"></i></div>
    <div class="w3-right" onclick="plusDivs(1)"><i class="fa fa-arrow-circle-right w3-hover-text-zot-red"></i></div>
    
    <div class="w3-center">
      <span class="w3-tag demodots w3-border w3-transparent w3-hover-white" onclick="currentDiv(1)"></span>
      <span class="w3-tag demodots w3-border w3-transparent w3-hover-white" onclick="currentDiv(2)"></span>
      <span class="w3-tag demodots w3-border w3-transparent w3-hover-white" onclick="currentDiv(3)"></span>
      <span class="w3-tag demodots w3-border w3-transparent w3-hover-white" onclick="currentDiv(4)"></span>
      <span class="w3-tag demodots w3-border w3-transparent w3-hover-white" onclick="currentDiv(5)"></span>
      <span class="w3-tag demodots w3-border w3-transparent w3-hover-white" onclick="currentDiv(6)"></span>
      <span class="w3-tag demodots w3-border w3-transparent w3-hover-white" onclick="currentDiv(7)"></span>
    </div>
  </div>

What I'm hoping to do is have the images advance automatically if the user doesn't engage the manual controls by clicking on an individual slide button or the next/previous buttons.

 

Prior to adding the manual controls I had the following script that just played the images automatically:

// Automatic Slideshow - change image every 8 seconds
var myIndex = 0;
carousel();

function carousel() {
    var i;
    var x = document.getElementsByClassName("mySlides");
    for (i = 0; i < x.length; i++) {
       x[i].style.display = "none";  
    }
    myIndex++;
    if (myIndex > x.length) {myIndex = 1}    
    x[myIndex-1].style.display = "block";  
    setTimeout(carousel, 8000);    
}

<script>

This is based on the carousel from the following template Try It:

 

http://www.w3schools.com/w3css/tryit.asp?filename=tryw3css_templates_band&stacked=h

 

Is there a way to combine these?

 

NOTE: It would be perfectly acceptable to have the images change automatically until such time as the user interacts with any of the manual controls. Once that happens, the carousel could remain manual until the page is loaded again.

 

Thanks!

Edited by Goodness
Link to comment
Share on other sites

You would use a mouseover event on elements to trigger clearTimeout, and mouseout event to run carousel function again. If you do a search for slideshow on this forum you will find detail about implementation of this cause I'm pretty sure I've done this 2-3 times before.

Link to comment
Share on other sites

I should also mention that my images are inside a div and there is also a div for text that's associated with that image.

 

Here is an example:

<div class="mySlides w3-display-container w3-center w3-animate-left w3-padding-0">
    <img src="images/banner-2.jpg" style="width:100%; max-height:774px">
    <div class="w3-display-topright w3-text-white w3-container w3-padding-32 w3-hide-small">
      <span class="w3-dark-grey w3-padding-large w3-animate-bottom">This is an example of copy that animates in over the image</span>
    </div>
</div>

The example you showed on the link you provided floats the manual image controls over the image where I have them in a separate div just below the slideshow.

Your example also has the mySlides class assigned to the images where I have that class assigned to the div that contains the image.

 

I've been at this for a few days but still can't quite figure out how to accomplish my goal.

 

Any additional thoughts/advice will be great appreciated.

 

Thanks!

Edited by Goodness
Link to comment
Share on other sites

Thanks again. This is apparently beyond my current ability.

I'm kind of surprised there's not an automatic slideshow with manual controls as part of one of the w3.css example templates.

There are manual and there are auto. Just not combined.

 

Anyways, thanks for all of your suggestions!

Link to comment
Share on other sites

donesuk,

 

Yes I have followed the link you provided above and can get the example working.

However, the example has the manual controls floating over the image - which is fine until the viewport gets small and the controls drop below.

To me this is not totally responsive.

 

I'm using the slideshow found here:

 

http://www.w3schools.com/w3css/tryw3css_templates_marketing.htm

 

And, all I'm trying to do is introduce a carousel function so that this slideshow will also run automatically if the user doesn't interact to change the slides.

 

I realize this is probably a fairly simple task for a programmer. Unfortunately, I am not a programmer. I am more of a graphic/ web designer.

 

Thanks again.

Link to comment
Share on other sites

Wrap all slideshow elements with class 'mySlides' with a div element with id ref 'myslideFrame'.

 

If you look at JavaScript code, you will find dots refer to element classname of 'demo', while the class name to marketing template dots class name is 'demodots', the JavaScript code refering to classname 'demo' must be changed to 'demodots'.

Link to comment
Share on other sites

Thank you! That helped.

 

Here's what I did:

 

I changed the reference in the JavaScript from 'demo' to 'demodots'.

I added a wrapper div around the entire slideshow and gave it id="myslideFrame"

 

Since I am not using the flexbox, I eliminated that from the <style> in the head and in the html.

 

Here's what's happening:

 

There are 7 slides.

 

When the page loads the 1st slide shows in it's proper position but the carousel isn't running.

Once I click on any of the controls (demodots or next/prev), a replica of the slideshow appears directly below the 1st image and it starts to run both auto and manual - but only slides 2-6. The last individual selector (demodot) is not usable. If I click on it it automatically shifts to the 1st demodot which is actually slide #2. Slide #1 remains in view above but all of the manual controls have gone (now visible in the duplicate below).

 

I hope I'm explaining this clearly.

Link to comment
Share on other sites

Whoops - 1 last thing:

 

Here's an example of one of the 7 mySlides divs:

<div class="mySlides w3-display-container w3-center w3-animate-left w3-padding-0">
    <img src="images/banner-3.jpg" style="width:100%; max-height:774px">
    <div class="w3-display-topright w3-text-white w3-container w3-padding-32 w3-hide-small">
      <span class="w3-dark-grey w3-padding-large w3-animate-bottom">This Text Should Animate Over The Image</span>
    </div>
    </div>

The slideshow is working perfectly except the nested div with the class of 'w3-display-topright' is not showing up.

I just get a small grey box where the text should be.

 

Thoughts?

Link to comment
Share on other sites

Works OK for me, also make sure the left, right pointer elements and dots have

 onmouseover="pauseCarousel();" onmouseout="startCarousel()

placed with onclick event, this pauses slide show on hover, and starts again when mouse leaves, because the setTimeout still runs in background, it prevents when you select either of these buttons, the image moving forward to next as the setTimeout triggers the carousel function.

Link to comment
Share on other sites


 var slideIndex = 0;
            var t;
            var dots;
            var maxheight = 0;
            var timedelay = 5000;
            window.onload = function() {
                var x = document.getElementsByClassName("mySlides");
                var parent_elem = document.getElementById('myslideFrame')

                var widthRatio = parseInt(parent_elem.offsetWidth) / parseInt(x[0].width)
                for (i = 0; i < x.length; i++) {
                    // x[i].style.width = "100%";

                    if (x[i].height > maxheight)
                    {

                        maxheight = x[i].height;

                    }

                }

                document.getElementById('myslideFrame').style.height = maxheight * widthRatio + "px";

                showDivs(slideIndex);
                carousel();
            };

            function plusDivs(n) {
                showDivs(slideIndex += n);

            }

            function currentDiv(n) {
                showDivs(slideIndex = n);
            }

            function showDivs(n) {
                var i;
                var x = document.getElementsByClassName("mySlides");
                dots = document.getElementsByClassName("demodots");
                if (n > x.length) {
                    slideIndex = 1;
                }
                if (n < 1) {
                    slideIndex = x.length;
                }
                ;

                for (i = 0; i < x.length; i++) {
                    x[i].style.display = "none";
                }
                for (i = 0; i < dots.length; i++) {
                    dots[i].className = dots[i].className.replace("  w3-white", "");
                }
                x[slideIndex - 1].style.display = "inline-block";
                dots[slideIndex - 1].className += "  w3-white";
            }



            function carousel() {
                var i;

                var x = document.getElementsByClassName("mySlides");
                for (i = 0; i < x.length; i++) {
                    x[i].style.display = "none";
                    dots[i].className = dots[i].className.replace("  w3-white", "");
                }
                slideIndex++;
                if (slideIndex > x.length) {
                    slideIndex = 1
                }
                x[slideIndex - 1].style.display = "inline-block";
                dots[slideIndex - 1].className += "  w3-white";
                t = setTimeout(carousel, timedelay);
            }

            function pauseCarousel() {

                clearTimeout(t)
            }

            function startCarousel() {

                t = setTimeout(carousel, timedelay);
            }
</script>
<!-- Slideshow -->
<div id="myslideFrame">
  <div class="w3-display-container mySlides">
    <img src="/w3images/coffee.jpg" style="width:100%">
    <div class="w3-display-topleft w3-text-white w3-container w3-padding-32 w3-hide-small">
      <span class="w3-white w3-padding-large w3-animate-bottom">Lorem ipsum</span>
    </div>
  </div>
  <div class="w3-display-container mySlides">
    <img src="/w3images/workbench.jpg" style="width:100%">
    <div class="w3-display-middle w3-text-white w3-container w3-padding-32 w3-hide-small">
      <span class="w3-white w3-padding-large w3-animate-bottom">Lorem ipsum hipsum</span>
    </div>
  </div>
  <div class="w3-display-container mySlides">
    <img src="/w3images/sound.jpg" style="width:100%">
    <div class="w3-display-topright w3-text-white w3-container w3-padding-32 w3-hide-small">
      <span class="w3-white w3-padding-large w3-animate-bottom">Lorem ipsum hipsum</span>
    </div>
  </div>

  <div class="w3-display-container mySlides">
    <img src="/w3images/coffee.jpg" style="width:100%">
    <div class="w3-display-topleft w3-text-white w3-container w3-padding-32 w3-hide-small">
      <span class="w3-white w3-padding-large w3-animate-bottom">Lorem ipsum</span>
    </div>
  </div>
  <div class="w3-display-container mySlides">
    <img src="/w3images/workbench.jpg" style="width:100%">
    <div class="w3-display-middle w3-text-white w3-container w3-padding-32 w3-hide-small">
      <span class="w3-white w3-padding-large w3-animate-bottom">Lorem ipsum hipsum</span>
    </div>
  </div>

  <div class="w3-display-container mySlides">
    <img src="/w3images/sound.jpg" style="width:100%">
    <div class="w3-display-topright w3-text-white w3-container w3-padding-32 w3-hide-small">
      <span class="w3-white w3-padding-large w3-animate-bottom">Lorem ipsum hipsum</span>
    </div>
  </div>

<div class="mySlides w3-display-container w3-center w3-animate-left w3-padding-0">
    <img src="/w3images/workbench.jpg" style="width:100%; max-height:774px">
    <div class="w3-display-topright w3-text-white w3-container w3-padding-32 w3-hide-small">
      <span class="w3-dark-grey w3-padding-large w3-animate-bottom">This is an example of copy that animates in over the image</span>
    </div>
</div>

</div> <!--END OF myslideFrame -->
  <!-- Slideshow next/previous buttons -->
  <div class="w3-container w3-dark-grey w3-padding-8 w3-xlarge">
    <div class="w3-left" onclick="plusDivs(-1)" onmouseover="pauseCarousel()" onmouseout="startCarousel()"><i class="fa fa-arrow-circle-left w3-hover-text-teal"></i></div>
    <div class="w3-right" onclick="plusDivs(1)" onmouseover="pauseCarousel()" onmouseout="startCarousel()"><i class="fa fa-arrow-circle-right w3-hover-text-teal"></i></div>
    
    <div class="w3-center">
      <span class="w3-tag demodots w3-border w3-transparent w3-hover-white" onclick="currentDiv(1)" onmouseover="pauseCarousel()" onmouseout="startCarousel()"></span>
      <span class="w3-tag demodots w3-border w3-transparent w3-hover-white" onclick="currentDiv(2)" onmouseover="pauseCarousel()" onmouseout="startCarousel()"></span>
      <span class="w3-tag demodots w3-border w3-transparent w3-hover-white" onclick="currentDiv(3)" onmouseover="pauseCarousel()" onmouseout="startCarousel()"></span>
      <span class="w3-tag demodots w3-border w3-transparent w3-hover-white" onclick="currentDiv(4)" onmouseover="pauseCarousel()" onmouseout="startCarousel()"></span>
      <span class="w3-tag demodots w3-border w3-transparent w3-hover-white" onclick="currentDiv(5)" onmouseover="pauseCarousel()" onmouseout="startCarousel()"></span>
      <span class="w3-tag demodots w3-border w3-transparent w3-hover-white" onclick="currentDiv(6)" onmouseover="pauseCarousel()" onmouseout="startCarousel()"></span>
<span class="w3-tag demodots w3-border w3-transparent w3-hover-white" onclick="currentDiv(7)" onmouseover="pauseCarousel()" onmouseout="startCarousel()"></span>
    </div>
  </div>

Works fine using this with your last image styling.

Link to comment
Share on other sites

I've been messing with this for several days now and I don't see the issue.

 

My <script> code is exactly as you have listed above.

 

Here is the portion of the page that includes the slideshow:

<!-- Slideshow -->
  <div id="myslideFrame"> <!-- open slideShow frame-->
    
    <div class="mySlides w3-display-container w3-center w3-animate-left w3-padding-0">
    <img src="images/banner-1.jpg" style="width:100%; max-height:774px">
    <div class="w3-display-bottommiddle w3-text-white w3-container w3-padding-32 w3-hide-small">
      <span class="w3-dark-grey w3-padding-large w3-animate-bottom">Lorem ipsum hipsum;</span>
    </div>
    </div>
    
    <div class="mySlides w3-display-container w3-center w3-animate-left w3-padding-0">
    <img src="images/banner-2.jpg" style="width:100%; max-height:774px">
    <div class="w3-display-topright w3-text-white w3-container w3-padding-32 w3-hide-small">
      <span class="w3-dark-grey w3-padding-large w3-hover-zot-red w3-animate-bottom">Lorem ipsum hipsum</span>
    </div>
    </div>
    
    <div class="mySlides w3-display-container w3-center w3-animate-left w3-padding-0">
    <img src="images/banner-3.jpg" style="width:100%; max-height:774px">
    <div class="w3-display-topright w3-text-white w3-container w3-padding-32 w3-hide-small">
      <span class="w3-dark-grey w3-padding-large w3-animate-bottom">Lorem ipsum hipsum</span>
    </div>
    </div>
    
   <div class="mySlides w3-display-container w3-center w3-animate-left w3-padding-0">
    <img src="images/banner-4.jpg" style="width:100%; max-height:774px">
    <div class="w3-display-bottomright w3-text-white w3-container w3-padding-32 w3-hide-small">
      <span class="w3-dark-grey w3-padding-large w3-animate-bottom">Lorem ipsum hipsum</span>
    </div>
   </div>
 
  <div class="mySlides w3-display-container w3-center w3-animate-left w3-padding-0">
    <img src="images/banner-5.jpg" style="width:100%; max-height:774px">
    <div class="w3-display-topright w3-text-white w3-container w3-padding-32 w3-hide-small">
      <span class="w3-dark-grey w3-padding-large w3-animate-bottom">Lorem ipsum hipsum</span>
    </div>
  </div>
 
  <div class="mySlides w3-display-container w3-center w3-animate-left w3-padding-0">
    <img src="images/banner-6.jpg" style="width:100%; max-height:774px">
    <div class="w3-display-bottomright w3-text-white w3-container w3-padding-32 w3-hide-small">
      <span class="w3-dark-grey w3-padding-large w3-animate-bottom">Lorem ipsum hipsum</span>
    </div>
  </div>
 
   <div class="mySlides w3-display-container w3-center w3-animate-left w3-padding-0">
    <img src="images/banner-7.jpg" style="width:100%; max-height:774px">
    <div class="w3-display-topright w3-text-white w3-container w3-padding-32 w3-hide-small">
      <span class="w3-dark-grey w3-padding-large w3-animate-bottom">Lorem ipsum hipsum</span>
    </div>
  </div>
<!-- Slideshow next/previous buttons -->
  <div class="w3-container w3-dark-grey w3-padding-8 w3-xlarge"> <!--open manual controls div-->
    
    <div class="w3-left" onclick="plusDivs(-1)" onmouseover="pauseCarousel()" onmouseout="startCarousel()"><i class="fa fa-arrow-circle-left w3-hover-text-zot-red"></i></div>
    <div class="w3-right" onclick="plusDivs(1)" onmouseover="pauseCarousel()" onmouseout="startCarousel()"><i class="fa fa-arrow-circle-right w3-hover-text-zot-red"></i></div>
   
    <div class="w3-center"> <!-- open Slideshow individual selector buttons -->
      <span class="w3-tag demodots w3-border w3-transparent w3-hover-white" onclick="currentDiv(1)" onmouseover="pauseCarousel()" onmouseout="startCarousel()"></span>
      <span class="w3-tag demodots w3-border w3-transparent w3-hover-white" onclick="currentDiv(2)" onmouseover="pauseCarousel()" onmouseout="startCarousel()"></span>
      <span class="w3-tag demodots w3-border w3-transparent w3-hover-white" onclick="currentDiv(3)" onmouseover="pauseCarousel()" onmouseout="startCarousel()"></span>
      <span class="w3-tag demodots w3-border w3-transparent w3-hover-white" onclick="currentDiv(4)" onmouseover="pauseCarousel()" onmouseout="startCarousel()"></span>
      <span class="w3-tag demodots w3-border w3-transparent w3-hover-white" onclick="currentDiv(5)" onmouseover="pauseCarousel()" onmouseout="startCarousel()"></span>
      <span class="w3-tag demodots w3-border w3-transparent w3-hover-white" onclick="currentDiv(6)" onmouseover="pauseCarousel()" onmouseout="startCarousel()"></span>
      <span class="w3-tag demodots w3-border w3-transparent w3-hover-white" onclick="currentDiv(7)" onmouseover="pauseCarousel()" onmouseout="startCarousel()"></span>
    </div><!--close Slideshow individual selectors-->
  </div> <!--close manual controls-->
</div> <!--close slideshow frame-->

I realize that I have the manual controls inside the slideshow frame. I also tried it closing the slideshow frame div before the manual controls (like you did) but it has no impact.

 

The slideshow functions as it's suppose to. I just can't seem to get the copy inside the <span> tags to render. I still just get the small box where the copy should be.

 

Maybe there's something obvious in my code that I'm just not seeing.

 

Thanks again!

Edited by Goodness
Link to comment
Share on other sites

Yes. I've cleared cache and tried it in Firefox, Safari, IE, and Google Chrome.

 

There's obviously something interfering with the rendering of the text inside the <span> tags since the <div> that contains them is being rendered.

 

I say obviously, but it's not obvious to me (yet).

Link to comment
Share on other sites

It would if css is must be a selector probably with :last-child somewhere, if javascript it would add/remove a specific class OR add inline styling, which should be observed by using web developer console to identify any of these changes compared to original html and class attributes, and added style attributes.

Link to comment
Share on other sites

dsonesuk,

 

I'm not sure why this is working for you and not for me.

 

When I view the version of the page with the totally manual slideshow the copy inside the <span> tags renders perfectly.

When I view the version of the page with the new auto/manual slideshow the divs that contain the <span> tags still render but not the copy that's inside the <span> tags.

 

Both pages are using the exact same w3.css. You're not having any issues with the javascript - and my javascript matches what you wrote.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...