Skip to content

Typee8/Image-gallery-in-JS

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Image gallry in JS

It's the conclusion of 6th chapter (there's 20) of devmentor.pl mentoring program.

In this project I was asked to write new functionalities in JS:

1) Click on an image to zoom in.
2) Show pictures from the same group below the picked img.
3) Click on arrows to swipe pictures left/right.
4) Click on background to return to the gallery.
5) If the client swipes to the end of an image group, loop back to the beginning/end.
6) After clicking on a desired image, the automatic image swiping feature activates.

There were certain conditions I needed to make:

  • HTML, CSS and part of JS are ready. I should not change them.
  • Stick to the already written convention.

Here you can check pre-written JS | Here you can check my code!

To implement the functionalities, I had to work with custom events with predefined tasks:

js-slider-img-click - an event that is triggered when clicking on the image on the page (this is already done in the script.js file) and should display our slideshow.

js-slider-img-next - an event triggered by clicking the right arrow on the page and should show the next image (if it exists) among those visible in the thumbnails.

js-slider-img-prev - similar to above, but for the left arrow.

js-slider-close - an event triggered by clicking in the empty space around the displayed photo, i.e., in the .js-slider__zoom element (and only this element! Be careful with event propagation).


Content:

1. Event.target in custom events.
2. Stop automatic image swipe - clearInterval().
3. Write things down.


Event.target in custom events

In this project I was constantly using custom events to get comfortable with them. Combining the events with regular events can lead to some confusion on what event.target actually is. In the project custom events where handled like this:

event-propagation

1️⃣ clicking on the zoom element creates new event and dispatch it with fireCustomEvent(element, name);

  • element: is the place where the event has been dispatched.
  • name: is the name of the new event.

2️⃣ evokes onClose() as soon as specific element has been clicked to launch js-slider-close custom event.

3️⃣ the function executes.

While writing onClose():

  • I thought that event.target is the element on which I clicked like in 1️⃣. It was because in fireCustomEvent(element, name) the element = e.currentTarget which was the same as e.target of the 'click' event.
  • In fireCustomEvent(element, name), if I'd change the "element" for sliderRootElement, then in the onClose() event.target, event.currentTarget, and this would all refer to the sliderRootElement.
  • Event.target represents the element on which the event was triggered.

Stop automatic image swipe - clearInterval()

I had to implement code that automatically swipes images at regular intervals.

I've started with a function:

const imageNextTimeline = function (e) {
  setInterval(() => {
    fireCustomEvent(this, "js-slider-img-next");
  }, 5000;
}

It triggers the event which calls the function that swipes images every 5 seconds.

To stop setInterval(), I needed to create a variable to store its ID, which I could then use with clearInterval() to stop the interval. I was trying to utilize the variable in different ways like playing with some conditionals:

const imageNextTimeline = function (e) {
  if (this.getAttribute("class").includes("js-slider--active")) {
    const timer = setInterval(() => {
      fireCustomEvent(this, "js-slider-img-next");
    }, 5000);
  } else {
    clearInterval(timer);
  }
};

Due to the creation of the variable in first code block, it was impossible to access the timer in the second one. I experimented with a different approach, attempting to use an undefined parameter timer so that it would be created outside of conditionals:

const imageNextTimeline = function (e, timer) {
  if (this.getAttribute("class").includes("js-slider--active")) {
    timer = setInterval(() => {
      fireCustomEvent(this, "js-slider-img-next");
    }, 5000);
  } else {
    clearInterval(timer);
  }
};

However, the parameter was being destroyed as soon as the function finished executing. Nonetheless, the concept that the variable needed to exist outside of conditionals brought me closer to the solution.

I learned that I needed to define a global variable and then use it within those conditionals. I really didn't want to define it globally, though, because it's considered bad practice and it can lead to many issues. Instead, I decided to create an object and define a variable within it that is accessible by functions responsible for starting and stopping the swiping:

const slideStartStop = {
  intervalId: "",
  startSlide: function () {
    slideStartStop.intervalId = setInterval(() => {
      fireCustomEvent(this, "js-slider-img-next");
    }, 5000);
  },
  stopSlide: function () {
    clearInterval(slideStartStop.intervalId);
  },
};

Now auto swiping can be turn on/off with just a right click.


Write things down

Writing down informations about elements within a project using comments helps to find the way around the code. Let's delve into examples.

Function nesting is a common practice. Arguments are passed through multiple functions, making it easy to lose track of each argument's value. Consider the following example from this project, which illustrates the path arguments must take to reach the showSliderThumbsItems()

arguments-pass

It's a long way. Consistently naming parameters that accept the same inputs helps not to get lost. Additionally, I frequently insert comments within the function I'm currently working on:

// event - img's event object
// sliderRootElement = ".js-slider";
// imagesSelector = ".gallery__item";

At the end of the project I delete it so it won't create any confusion. It's only for me.

I also use comments to organize my efforts and break down problems into more manageable chunks, for example:

I had to create a function named onImageClick().

I write down:

  • What client sees: // click on img calls the function which shows clicked image enlarged.

  • What operations does the function do on specific elements: // takes src from clicked img and pastes it inside img with class js-slider__caption.

  • How can I divide each functionality inside the function: // onImageClick() will have two functions one for showing clicked img, second for showing images in thumbnails.

  • What other elements concerns the function: // initCustomEvents() calls the function. I'll need to add eventListener there. I need to use fireCustomEvent() to create "js-slider-img-click" event.

etc.

Again, It's only for me. I don't leave it in the final project. It helps to gather my thoughts.


Gained knowledge:

✅ Get around pre-written code.
✅ Working with custom events.
✅ Comprehension of Event object.
✅ Usage of setInterval().
✅ Improve readability of functions - decomposition.
✅ Keep the code DRY.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors