-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Carousel #1
Conversation
index.html
Outdated
</div> | ||
<div class="container"> | ||
<div class="carousel"> | ||
<button class="button button--left"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rzeczy, które nie działają bez JS powinny zostać dodane dopiero przez skrypt.
A więc:
- przyciski
- kropeczki
- klasy "active"
- itp.
Hasło: Progressive Enhancement
index.html
Outdated
style="width:24px;height:24px" | ||
viewBox="0 0 24 24" | ||
> | ||
<path |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ten przycisk nie ma żadnej treści, a więc będzie całkowicie niedostępny dla czytników ekranowych
index.html
Outdated
class="carousel__image" | ||
/> | ||
</div> | ||
<div class="carousel__slide carousel__slide--active"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tę klasę powinien dodać skrypt
index.html
Outdated
</svg> | ||
</button> | ||
</div> | ||
<div class="dotsNav"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Te kropki powinien generować skrypt
index.html
Outdated
</button> | ||
<div class="carousel__container"> | ||
<div class="carousel__slide"> | ||
<img |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moim zdaniem to pierwsze zdjęcie powinno być aktywne na początku, a nie trzecie.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to akurat moja wina :) - muszę poprawić na makiecie
src/main2.js
Outdated
}); | ||
|
||
//Swipe Events | ||
document.addEventListener('touchstart', handleTouchStart, false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Czy nie lepiej byłoby użyć Pointer Events?
src/main2.js
Outdated
|
||
if (xDirection > 0) { | ||
moveToLeft(); | ||
} else if (xDirection < 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tutaj powinna być pewna wartość graniczna, np. 20 pikseli
src/main2.js
Outdated
|
||
//Swipe Events | ||
document.addEventListener('touchstart', handleTouchStart, false); | ||
document.addEventListener('touchmove', handleTouchMove, false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Jeśli dobrze rozumiem, to taki kod spowoduje, że lekkie drgnięcie palca w złą stronę spowoduje przesunięcie karuzeli.
src/styles.css
Outdated
@@ -0,0 +1,218 @@ | |||
@import url('https://fonts.googleapis.com/css?family=Poppins:400,600&display=swap'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lepiej umieścić to w pliku index.html
src/styles.css
Outdated
width: 40px; | ||
} | ||
|
||
@media (max-width: 1400px) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dlaczego nie mobile-first?
src/main2.js
Outdated
slides.forEach(slide => { | ||
slide.addEventListener('click', () => { | ||
//Middle Slide is 3rd position (0,1,2) from left, so we need to subtract two. | ||
if (isInTransition === true) return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wystarczy
if (isInTransition) { return ; }
jestem za tym abyś dodawał nawiasy { ... }
za ifem
index.html
Outdated
class="carousel__image" | ||
/> | ||
</div> | ||
<div class="carousel__slide"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
te slajdy jednak powinny być renderowane za pomocą JS.
jest tu bardzo dużo powtórzeń kodu
src/main2.js
Outdated
let elementWidth = slides[0].offsetWidth; | ||
let isInTransition = false; | ||
//Middle Dot | ||
let activeDot = 3; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wszelkie wartości "experckie" / "defaultowe" czy z innego względu magiczne warto zapisywać uppercasem:
const DEFAULT_ACTIVE_DOT = 3;
let activeDot = DEFULT_ACTIVE_DOT;
src/main2.js
Outdated
const carousel = document.querySelector('.carousel__container'); | ||
|
||
window.addEventListener('load', () => { | ||
let slides = document.querySelectorAll('.carousel__slide'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dlaczego let
a nie const
?
src/main2.js
Outdated
const moveToRight = () => { | ||
if (isInTransition === true) return; | ||
carousel.appendChild(carousel.firstElementChild); | ||
slides = carousel.querySelectorAll('.carousel__slide'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
może do osobnej funkcji:
getSlides(carousel) {
let element = carousel;
element.appendChild(carousel.firstElementChild);
return element.querySelectorAll('.carousel__slide')
}
wtedy nie mutujesz elementów (ale nie wiem czy to tak ma działać u Ciebie)
src/main2.js
Outdated
setActiveElement(slides); | ||
}; | ||
|
||
const moveToLeft = () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
te funkcje wykonują bardzo dużo side-effectów.
nie są zupełnie testowalne, mutują obiekty, pobierają dane ze scopa.
ich odpowiedzialność jest bardzo duża i rozmyta.
starałbym się pisać więcej małych pure funkcji, które przyjmują argumenty i zwracają jakąś wartość.
src/main2.js
Outdated
@@ -0,0 +1,272 @@ | |||
window.addEventListener('load', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
czy ten load jest w ogóle potrzebny?
imho nie :)
src/main2.js
Outdated
'afterbegin', | ||
'<svg class="container__svg" style="width:24px;height:24px" viewBox="0 0 24 24"><path class="container__path" fill="#000000" d="M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z"/></svg> <p class="screen-readers">Right button for moving photos.</p>' | ||
); | ||
carousel.appendChild(buttonRight); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wszystkie funkcje odpowiedzialne za tworzenie elementów DOM przeniósłbym do swoich osobnych plików i tylko importował tutaj:
export const renderButton(side) {
const button = document.createElement('button');
button.classList.add('button');
button.classList.add(`button--${side}`);
...
i tu lepiej skorzystać z insertAdjacentHTML niż tak dodawać po kolei atrybuty
}
i wtedy w tym pliku importujesz:
import {renderButton} from './renderButton'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dodatkowo masz funkcje renderButtonLeft i renderButtonRight -> aż się prosi o dodanie parametru jako argument w tej funkcji
src/main2.js
Outdated
); | ||
buttonLeft.classList.toggle('button--hidden'); | ||
buttonRight.classList.toggle('button--hidden'); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cały ten arrowSwitch -> do osobnego pliku jak buttony.
i łatwiej byłoby jak byś stworzył całe ten html jako string i skorzystał z insertAdjacentHTML
src/main2.js
Outdated
carouselContainer.appendChild(div); | ||
}; | ||
|
||
const images = document.querySelectorAll('.carousel__image'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wszystkie selektory przeniósłbym na górę pliku w 1 miejsce
src/main2.js
Outdated
const buttonRight = document.createElement('button'); | ||
buttonRight.classList.add('button'); | ||
buttonRight.classList.add('button--right'); | ||
buttonRight.insertAdjacentHTML( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dlaczego całego buttona nie stworzysz za pomocą insertAdjacentHTML
:
const button = <button class="button button--${side}"><svg>... </button>
bez sensu dodawać te klasy za pomocą classList.add można to zrobić w stringu
return subtractionOfMultipliers; | ||
}; | ||
|
||
const isApplicableForAddingClass = slide => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
jeśli funkcja ma zwracać booleana - to powinna zwracać true
lub false
tutaj zwraca true
albo nic :)
const isApplicableForAddingClass = slide => {
return checkMultipliersDiffrence(slide) === 0;
}
zwróci booleana
} | ||
}; | ||
|
||
const isOneMove = multipliersDiffrence => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return multipliersDiffrence < 2 && multipliersDiffrence > -2
} | ||
}; | ||
|
||
const isApplicableForMove = slide => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return checkMultipliersDiffrence(slide) !== 0
} | ||
}; | ||
|
||
const isActive = slide => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return slide.classList.contains('carousel__slide--scale')
'.arrows-switch__container' | ||
); | ||
|
||
arrowsSwitchContainer.addEventListener('click', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
truchę mi ten listener tutaj nie pasuje w tej funkcji
index.html
Outdated
</div> | ||
<div class="dotsNav"></div> | ||
</div> | ||
<script defer src="src/carousel.js"></script> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
script defer powinien chyba być w headzie. Jak dasz na końcu body to wydaje mi się, że zanim zacznie się pobierać to cały html się załaduje i nie bedziesz miał oczekiwanego efektu pobierania pliku podczas przetwarzania html.
const carouselRightButton = document.querySelector('.button--right'); | ||
const carouselLeftButton = document.querySelector('.button--left'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
jeśli elementy zawierają się w carouselContainer
, to można ograniczyć selector do tego elementu
}; | ||
|
||
const updateCurrentActiveSlide = slides => { | ||
const middleElement = (maxCountOnScreen + 1) / 2; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maxCountOnScreen
może być parzyste? jeśli tak to (maxCountOnScreen + 1) / 2
zwróci ułamek, który bezkrytycznie użyjesz jako index tablicy
src/carousel.js
Outdated
if (direction === 'left') { | ||
activeDot === 0 ? (activeDot = slides.length - 1) : activeDot--; | ||
} else if (direction === 'right') { | ||
activeDot === slidesCounter - 1 ? (activeDot = 0) : activeDot++; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
może activeDot = activeDot === 0 ? slides.length - 1 : activeDot - 1;
?
nie ładniej będzie? od razu widać jaką zmienną updatujesz i nie potrzeba nawiasów w środku wrzucać
src/carousel.js
Outdated
let dots = document.querySelectorAll('.dotsNav__dot'); | ||
let elementWidth = slides[0].offsetWidth; | ||
let isInTransition = false; | ||
let activeDot = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wyciągnąć do stałej
} | ||
|
||
function handleTouchMove(event) { | ||
if (!yStart || !xStart) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wydaje mi się czy nie zadeklarowałeś yStart
?
pageBackground.addEventListener('click', () => { | ||
if (!isInTransition) { | ||
if (carouselContainer.querySelector('.carousel__slide--scale')) { | ||
carouselContainer | ||
.querySelector('.carousel__slide--scale') | ||
.classList.remove('carousel__slide--scale'); | ||
pageBackground.classList.remove('pageBackground--scale'); | ||
} | ||
} | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
listenery, funkcje, listenery, wywołania funkcji (niżej), listenery.
można pogrupować?
src/renderButton.js
Outdated
right: | ||
'<svg class="container__svg" style="width:24px;height:24px" viewBox="0 0 24 24"><path class="container__path" fill="#000000" d="M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z"/></svg>', | ||
left: | ||
'<svg class="container__svg" style="width:24px;height:24px" viewBox="0 0 24 24"><path class="container__path" fill="#000000" d="M15.41,16.58L10.83,12L15.41,7.41L14,6L8,12L14,18L15.41,16.58Z"/></svg>' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
width i height możesz spokojnie w css sobie wrzucić. viewBox i tak zadba o dobre proporcje
src/styles.css
Outdated
.screen-readers { | ||
position: absolute; | ||
right: 2400px; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
opowiesz coś o tym? nie pisałem dla screen readerów więc może coś się dowiem ciekawego, ale na 1 rzut oka dziwnie mi to wygląda.
src/styles.css
Outdated
.container__svg { | ||
width: 50px !important; | ||
height: 50px !important; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
o jak przeniesiesz width i height z svg tu, to nie będziesz potrzebował !important
src/renderButton.js
Outdated
}; | ||
|
||
renderButton('left'); | ||
renderButton('right'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mi się generalnie nie podoba za bardzo idea wywoływania tych funkcji w tych komponentach.
powinieneś exportować funkcję renderButton
importować ją w jakimś głównym module i tam ją wywoływać
w ten sposób możesz też przekazywać scope z głownego modułu:
export default function renderButton(carouselElement, side) => ...
// index.js
import renderButton from './renderButton';
const carousel = document.querySelector('.carousel');
renderButton(carousel, 'left')
renderButton(carousel, 'right')
wtedy te funkcje są pure i znacznie bardziej reużywalne
src/renderDots.js
Outdated
} | ||
}; | ||
|
||
renderDots(slidesCounter); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
j.w. w renderButton.js
<div class="pageBackground"></div> | ||
`; | ||
|
||
document.body.insertAdjacentHTML('afterbegin', pageBackground); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
j.w.
src/renderSlides.js
Outdated
carouselContainer.appendChild(div); | ||
}; | ||
|
||
images.forEach(image => generateSlide(image)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
j.w.
</div> | ||
`; | ||
|
||
document |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
j.w.
wywoływanie tej funkcji powinno być w głównym module
Pull Request to master