3
\$\begingroup\$

I currently got into coding and I am completely self taught. Since I know that my code is far from being perfect, I am asking for advice and tips on how to improve. Feel free to drop in any comments related to the topic - any helpful advice and food for thought is highly appreciated. It doesn't matter if the advice is regarded to my html file, my JavaScript syntax or my css skills. I really want to improve and every help is great!

Edit: I uploaded a demo to my workspace that you can visit under: https://cedricjansen.com

Here is an image so that you can better understand about what i am talking: MeadowJS in Chrome Browser

So let my try to explain my concept. I created a div with the id="meadow" where you can specify an interval as attribute as well as the width and the height of the div. All images are later 'drawn' to this div, so it acts as a container and wrapper.

Then I created a tab container with the id="meadow-tabs" which contains all tabs. Tabs are little dots, which are shown at the bottom of the main div and each dot refers to one image. The dot with the image that is currently displayed is highlighted and marked with the class active-tab.

When the html file is loaded, all images get preloaded and then the first image ( depends on which tab is active on start ) gets displayed. Now you can either wait the specified interval until the image changes itself or you can click one of the tabs to jump to a certain image immediately.

The pause button can stop and resume the interval.

INDEX.HTML

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" type="text/css" href="meadow.css">
</head>
<body >
    <!-- The image container to which the images are drawn -->
    <div id="meadow" class="meadow demo banner" interval="5000" m-width="100%" m-height="100%"> 
        <!-- The loader which is hidden after the images are preloaded -->
        <div  id="meadow-load" class="meadow-loader"></div> 
        <!-- Pause Button -->
        <div id="meadow-pause" class="pause-tab"></div>
        <!-- The Tab Container -->
        <div id="meadow-tabs" class="tabs-bottom" show>
        <!-- The single tabs which contain the image paths and an index -->
            <div class="meadow-tab active-tab" 
                 image="./images/img1.jpg" 
                 index="0">
            </div>
            <div class="meadow-tab" 
                 image="./images/img2.jpg" 
                 index="1">
             </div>
            <div class="meadow-tab" 
                 image="./images/img3.jpg" 
                 index="2" >
            </div>
        </div>
    </div>
<script src="meadow.js" type="text/javascript"></script>
</body>
</html>

MEADOW.JS

var tabs = [];
var fetchedImages = [];
var imageUrls = [];
var images = [];

var carouselIndex = [];
var meadow;

var pauseTab = document.getElementsByClassName('pause-tab')[0];
pauseTab.addEventListener("click", pausePlay);

const meadowDom = document.getElementById('meadow');
//Gets the interval time.
const interval = meadowDom.getAttribute('interval');
const banner = document.getElementsByClassName('banner')[0];

//Grabs the attributes from the html file for width and height
const width = meadowDom.getAttribute('m-width');
const height = meadowDom.getAttribute('m-height');

//Looks if the the attribute show is present;
const showTabs = document.getElementById("meadow-tabs").hasAttribute('show');

//If the attribute show is not present, hide the tabs
if(!showTabs)
{
    document.getElementById("meadow-tabs").style.display = "none";
}

//Set the custom height and width of the banner container, to which the images are drawn.
banner.style.height = height;
banner.style.width = width;


var loader = document.getElementById("meadow-load");


//Get all Tabs
var fetchedTabs = document.getElementById("meadow-tabs").querySelectorAll('.meadow-tab');

for( var i = 0; i < fetchedTabs.length; i++ )
{
    //Push all Image Links from the tabs to the ImageUrls array to preload them
    imageUrls.push(fetchedTabs[i].getAttribute('image'));
}
//Preloads the images
preload(imageUrls);
// Shows the first image of the active tab
initImage();



for( var i = 0; i < fetchedTabs.length; i++)
{

    fetchedTabs[i].addEventListener("click", toggleTab);
}

// Function used then pause button is clicked. Toggles between
// pausing and resuming the carousel.
function pausePlay()
{
    if(pauseTab.classList.contains('active'))
    {
        pauseTab.classList.remove('active');
        meadow = setInterval(play, interval);
    }
    else
    {
        pauseTab.classList.add('active');
        clearInterval(meadow);
    }
}

// Used when a certain tab is clicked. If the tab is not activated,
// activate it and deactive the current activated tab.
// Checks if the carousel is paused. If yes, keep it paused, if no
// continue from there with the given interval time.
function toggleTab()
{

    if( event.target.classList.contains('.active-tab'))
    {
        return;
    }
    var activeTab = document.getElementsByClassName('active-tab');
    console.log(activeTab);
    activeTab[0].classList.remove('active-tab');

    event.target.classList.add('active-tab');
    console.log("EVENT: " + event.target);
    changeImage(event.target);
    clearInterval(meadow);
    if(!pauseTab.classList.contains('active'))
    {
        meadow = setInterval(play, interval);   
    }

}

// Function which removes the active tab.
function removeActiveTab()
{
    var activeTab = document.getElementsByClassName('active-tab');
    activeTab[0].classList.remove('active-tab');
}

//Function to change the image.
function changeImage( tabToChangeTo )
{
    var imageToChangeTo = tabToChangeTo.getAttribute('image');
    banner.style.backgroundImage = "url('" + imageToChangeTo + "')" ;
}


//Used in the play function to continue to the next tab and change the image.
function changeInPlay( indexToChangeTo )
{
    var tab = document.querySelectorAll('[index="'+ indexToChangeTo + '"]')[0];
    changeImage(tab);
    removeActiveTab();
    tab.classList.add('active-tab');
}

//Display the first image of the first active tab.
function initImage()
{
    var activeTab = document.getElementsByClassName('active-tab')[0];
    var activeImage = activeTab.getAttribute('image');
    banner.style.backgroundImage = "url('" + activeImage + "')" ;
}

// Used in setInterval to iterate over the tabs and show the different images.
function play()
{

    var activeTab = document.getElementsByClassName('active-tab')[0];
    var activeIndex = activeTab.getAttribute('index');

    var nextIndex;
    if( activeIndex == (fetchedTabs.length - 1))
    {
        nextIndex = 0;
    }
    else 
    {
        nextIndex = +activeIndex + 1;
    }
    changeInPlay(nextIndex);

}

function preload( urls ) {
    for (var i = 0; i < urls.length; i++) {
        //Preload the images from the passed urls and keep them in a reference
        // so that they aren't erased from storage.
        images[i] = new Image();
        images[i].src = urls[i];
    }
    //Hide the carousel loader after images are preloaded.
    loader.style.display = 'none';
}

//Set the initial interval for images to change.
meadow = setInterval(play, interval);

MEADOW.CSS

html
{
    width: 100%;
    height: 100%;
}

html body
{
    width: 100%;
    height: 100%;
    margin: 0px;
    padding: 0px;
}

.meadow.demo.banner
{
    width: 100%;
    height: 100%;

    min-height: 100px;

    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;

    background-color: black; 

    position: relative;

    background-size: cover;
}

.meadow.demo.banner .meadow-loader
{
    position: absolute;
    width: 20px;
    height: 20px;

    border-radius: 10px;
    background-color:white;

    animation: meadow-pulse 2s infinite;
}

@keyframes meadow-pulse
{
    0%
    {
        opacity: 0;
    }
    50%
    {
        opacity: 0.8;
    }
    100%
    {
        opacity: 0;
    }
}

.meadow.demo.banner .pause-tab
{
    position: absolute;
    width: 20px;
    height: 20px;
    border-radius: 20px;
    background-color: white;

    left: 10px;
    bottom: 10px;

    opacity: 0.5;
}

.meadow.demo.banner .pause-tab:hover
{
    cursor: pointer;
}

.meadow.demo.banner .pause-tab.active
{
    opacity: 1;
}

.meadow.demo.banner .tabs-bottom
{
    width: auto;
    min-width: 45px;
    max-width: 100px;

    position: absolute;

    min-height: 15px;
    height: 5%;

    display: flex;
    justify-content: center;
    align-items: center;

    bottom: 5px;

    background-color: rgba(152, 152, 152, 0.5);
    border-radius: 10px;
}

.meadow.demo.banner .tabs-bottom .meadow-tab
{
    min-width: 7px;
    min-height: 7px;
    border-radius: 5px;
    margin-left: 2px;
    margin-right: 2px;

    background-color: black;
}

.meadow.demo.banner .tabs-bottom .meadow-tab:hover
{
    cursor: pointer;
}

.meadow.demo.banner .tabs-bottom .meadow-tab.active-tab
{
    background-color: white;
}

.meadow.demo.cover
{
    width: 100%;
    height: 100%;
    background-color: black;
}

If anyone finds this post and wants to build their own carousel/ image slider, feel free to use any of this code and rebuild it to your needs.

FYI: I called it meadow because I was sitting by a meadow when I came up with the idea to try to build a image slider thingy.

Thank you for your help!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.