Damien Rice
Damien Rice

Reputation: 81

Adapt slide show to respond to single key presses only

I found code for a slide show here:

https://www.developphp.com/video/JavaScript/Bubbles-Content-Slideshow-Application-JavaScript-CSS-HTML

I would like to add arrow key functionality so that the slide scrolls left or right depending on whether the left or right arrow key is pressed. Currently it keeps cycling through the slides but I would like it to scroll only once per key press.

<style>
#bubblebox{ width:650px; height:250px; margin:50px auto; border:1px solid    
#AAA; }
#bubbles{ width:auto; margin:0px auto; text-align:center; }
#bubbles > div{ display:inline-block; width:10px; height:10px; margin:24px    
10px 0px 10px; background:rgba(0,0,0,.1); text-align:center; border:2px   
solid #999; border-radius:100%; font-size:17px; text-decoration:none;   
transition: background 0.3s linear 0s; cursor:pointer; }
#bubblecontent{ margin:0px auto; transition:opacity 0.3s linear 0s; font-   
family: Arial;}
#bubblecontent > h2{ text-align:center; color:#7EA800; }
#bubblecontent > p{ font-size:17px; line-height:1.5em; padding:20px 50px;   
color:#777; }
</style>
<script>
// This simple function returns object reference for elements by ID
function _(x){return document.getElementById(x);}
// Variables for bubble array, bubble index, and the setInterval() variable
var ba, bi=0, intrvl;
// bca - Bubble Content Array. Put your content here.
var bca = [
'<h2>Heading Number 1</h2><p>Content for section 1</p>',
'<h2>Heading Number 2</h2><p>Content for section 2</p>',
'<h2>Heading Number 3</h2><p>Content for section 3</p>',
'<h2>Heading Number 4</h2><p>Content for section 4</p>'
];
// This function is triggered by the bubbleSlide() function below
function bubbles(bi){
// Fade-out the content
_("bubblecontent").style.opacity = 0;
// Loop over the bubbles and change all of their background color
for(var i=0; i < ba.length; i++){
    ba[i].style.background = "rgba(0,0,0,.1)";
}
// Change the target bubble background to be darker than the rest
ba[bi].style.background = "#999";
// Stall the bubble and content changing for just 300ms
setTimeout(function(){
    // Change the content
    _("bubblecontent").innerHTML = bca[bi];
    // Fade-in the content
    _("bubblecontent").style.opacity = 1;
}, 300);
}
// This function is set to run every 5 seconds(5000ms)
function bubbleSlide(){
bi++; // Increment the bubble index number
// If bubble index number is equal to the amount of total bubbles
if(bi == ba.length){
    bi = 0; // Reset the bubble index to 0 so it loops back at the beginning
}
// Make the bubbles() function above run
bubbles(bi);
}
// Start the application up when document is ready
window.addEventListener("load", function(){
// Get the bubbles array
ba = _("bubbles").children;
// Set the interval timing for the slideshow speed
intrvl = setInterval(bubbleSlide, 5000);
});

document.onkeydown = function(event) {
 if (!event)
      event = window.event;
 var code = event.keyCode;
 if (event.charCode && code == 0)
      code = event.charCode;
 switch(code) {
      case 37:  
     ba = _("bubbles").children;
          break;
      case 39: 
 ba = _("bubbles").children;
 }
 event.preventDefault();
};

</script>
<div id="bubblebox">
<div id="bubbles">
<div onclick="bubbles(0); clearInterval(intrvl);" style="background:#999;">   
</div>
<div onclick="bubbles(1); clearInterval(intrvl);"></div>
<div onclick="bubbles(2); clearInterval(intrvl);"></div>
<div onclick="bubbles(3); clearInterval(intrvl);"></div>
</div>
<div id="bubblecontent">
<h2>Heading Number 1</h2>
<p>Content for section 1</p>
</div>
</div>

Upvotes: 0

Views: 47

Answers (1)

Michael Laszlo
Michael Laszlo

Reputation: 12239

The script that you found relies on inline event handlers in the HTML, which will make it a hassle to add new content. Another problem is that style changes are hard-coded. Writing things like

ba[i].style.background = "rgba(0,0,0,.1)";

and

ba[bi].style.background = "#999";

is not a future-friendly way to code.

Below is an implementation that achieves the same layout and transition effects by setting CSS class names. You can improve on this by writing a function that adds and removes class names, or you can let jQuery let the work for you with .addClass() and .removeClass().

This is a self-contained example that responds to mouse clicks on the bubbles and to key presses on the left and right cursor keys. The keydownFired flag is used to prevent multiple keydown events per key press.

var contentItems = [  // Fill this array with the desired slide content.
  '<h2> Zoo animals </h2> <p> Giraffes have long necks and small horns. </p>',
  '<h2> All about cheese </h2> <p> Cheddar cheese is orange or white. </p>',
  '<h2> Weather forecast </h2> <p> It may rain. </p> <p> It may shine. </p>',
  '<h2> Rivalry </h2> <p> Puma and Adidas were founded by brothers. </p>'
];

var classNames = {
  slide: {
    default: 'slide',
    active: 'slide active'
  },
  bubble: { 
    default: 'bubble',
    active: 'bubble active'
  }
};

window.onload = function () {
  var currentSlide;
  var bubbleClick = function () {
    if (currentSlide) {
      currentSlide.className = classNames.slide.default;
      currentSlide.bubble.className = classNames.bubble.default;
    }
    currentSlide = this.slide;
    currentSlide.className = classNames.slide.active;
    this.className = classNames.bubble.active;
  };
  var slides = contentItems.map(function (content, index) {
        var slide = document.createElement('div'),
            bubble = document.createElement('div');
        slide.className = classNames.slide.default;
        slide.innerHTML = content;
        slide.index = index;    // The index will help with keydown events.
        slide.bubble = bubble;  // The slide and the bubble point to each
        bubble.slide = slide;   //  other to ease event handling.
        document.getElementById('slides').appendChild(slide);
        bubble.className = classNames.bubble.default;
        document.getElementById('bubbles').appendChild(bubble);
        bubble.onclick = bubbleClick;
        return slide;
      });
  slides[0].bubble.onclick();
  var keydownFired = false;
  window.onkeyup = function () {
    keydownFired = false;
  }
  window.onkeydown = function (event) {
    if (keydownFired) {         // Allow just one keydown event each time
      return;                   //  the user presses a key.
    }
    keydownFired = true;
    var code = event.which;
    if (code == 37) {
      var left = (currentSlide.index + slides.length - 1) % slides.length;
      slides[left].bubble.onclick();
    } else if (code == 39) {
      var right = (currentSlide.index + 1) % slides.length;
      slides[right].bubble.onclick();
    }
  };
};
* {
  box-model: border-box;
}
#slideshow {
  width: 650px;
  height: 250px;
  margin: 50px auto;
  border: 1px solid #aaa;
}
#bubbles {
  text-align: center;
}
.bubble {
  display: inline-block;
  width: 10px;
  height: 10px;
  margin: 24px 10px 0px 10px;
  background: rgba(0, 0, 0, .1);
  border: 2px solid #999;
  border-radius:100%;
  font-size: 17px;
  text-decoration: none;
  transition: background 0.3s linear 0s;
  cursor: pointer;
}
.bubble.active {
  background: #999;
}
#slides {
  position: relative;
}
.slide {
  font-family: Arial, sans-serif;
  position: absolute;
  width: 650px;
  opacity: 0;
  transition: opacity 0.3s linear 0s;
}
.slide.active {
  height: 100%;
  opacity: 1;
}
.slide h2 {
  text-align: center;
  color: #7ea800;
}
.slide p {
  font-size: 17px;
  line-height: 1.5em;
  padding: 10px 50px;
  color: #777;
}
<div id="slideshow">
  <div id="bubbles"></div>
  <div id="slides"></div>
</div>

Upvotes: 1

Related Questions