George Clement Perkins
Junior Member
Như tít, em code theo Youtube, nhìn họ code đến đâu làm theo đến đó nên còn hiểu. Mà em tưởng tượng cái đống này là của người khác chứ ko phải em thì chắc éo bao giờ em hiểu nổi đang làm cái gì luôn
, dù ông thầy organize code rất tốt
Có trick nào để đọc code dễ hiểu ko các bác
, dù ông thầy organize code rất tốtCó trick nào để đọc code dễ hiểu ko các bác
JavaScript:
class Workout {
date = new Date();
id = (Date.now() + '').slice(-10);
constructor(coords, distance, duration) {
this.coords = coords; // [lat, lng]
this.distance = distance; // in km
this.duration = duration; // in min
}
_setDescription() {
const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
this.description = `${this.type[0].toUppercase()}${this.type.slice(1)} on ${months[this.date.getMonth()]} ${this.date.getDate()}`;
}
}
class Running extends Workout {
type = 'running';
constructor(coords, distance, duration, cadance) {
super(coords, distance, duration);
this.cadance = cadance;
this.calcPace();
this._setDescription();
}
calcPace() {
// min/km
this.pace = this.duration / this.distance;
return this.pace;
}
}
class Cycling extends Workout {
type = 'cycling';
constructor(coords, distance, duration, elevationGain) {
super(coords, distance, duration);
this.elevationGain = elevationGain;
this.calcSpeed();
this._setDescription();
}
calcSpeed() {
// km/h
this.speed = this.distance / (this.duration / 60);
return this.speed;
}
}
const run1 = new Running([39, -12], 5.2, 24, 178);
const cycling1 = new Running([39, -12], 27, 95, 523);
// console.log(run1, cycling1);
// APPLICATION ARCHITECTURE
const form = document.querySelector('.form');
const containerWorkouts = document.querySelector('.workouts');
const inputType = document.querySelector('.form__input--type');
const inputDistance = document.querySelector('.form__input--distance');
const inputDuration = document.querySelector('.form__input--duration');
const inputCadence = document.querySelector('.form__input--cadence');
const inputElevation = document.querySelector('.form__input--elevation');
class App {
#map;
#mapEvent;
#workouts = [];
constructor() {
this._getPosition();
form.addEventListener('submit', this._newWorkout.bind(this));
// đổi option sẽ đổi nội dung 1 ô
inputType.addEventListener('change', this._toggleElevationField);
}
_getPosition() {
if (navigator.geolocation) // Check if support on old browser
navigator.geolocation.getCurrentPosition(this._loadMap.bind(this),
function () { // 2nd function triggered when fail to get location
alert('Could not get your position');
});
}
_loadMap(position) { // 1st function triggered when get location success
const { latitude } = position.coords;
const { longitude } = position.coords;
const coords = [latitude, longitude];
this.#map = L.map('map').setView(coords, 13);
L.tileLayer('http://{s}.google.com/vt/lyrs=m&x={x}&y={y}&z={z}', {
maxZoom: 20,
subdomains: ['mt0', 'mt1', 'mt2', 'mt3'],
}).addTo(this.#map);
// Handling click on map
this.#map.on('click', this._showForm.bind(this)); // Click vào 1 điểm sẽ trả về 1 Event
}
_showForm(mapE) {
this.#mapEvent = mapE;
console.log(mapE);
form.classList.remove('hidden');
inputDistance.focus(); // Đặt con trỏ vào form input này
}
_toggleElevationField() {
inputElevation.closest('.form__row').classList.toggle('form__row--hidden');
inputCadence.closest('.form__row').classList.toggle('form__row--hidden');
}
_newWorkout(e) {
const validInput = (...inputs) => inputs.every(inp => Number.isFinite(inp));
const allPositive = (...inputs) => inputs.every(inp => inp > 0);
e.preventDefault();
// Get data from form
const type = inputType.value;
const distance = +inputDistance.value;
const duration = +inputDuration.value;
const { lat, lng } = this.#mapEvent.latlng; // lấy thông tin toạ độ trong event đó
let workout;
// If activity is running, add running Object
if (type === 'running') {
const cadance = +inputCadence.value;
// Check if data is valid
if (!validInput(distance, duration, cadance) ||
!allPositive(distance, duration))
return alert('input has to be positive number!');
workout = new Running([lat, lng], distance, duration, cadance);
}
// If activity is cycling, add running Object
if (type === 'cycling') {
const elevation = +inputElevation.value;
// Check if data is valid
if (!validInput(distance, duration, elevation) ||
!allPositive(distance, duration))
return alert('input has to be positive number!');
workout = new Cycling([lat, lng], distance, duration, elevation);
}
// Add new Object to workout array
this.#workouts.push(workout);
console.log(workout);
// Render workout on map and marker
this._renderWorkoutMarker(workout);
// Render workout on list
this._renderWorkout(workout);
// Hide form + Clear input fields
inputDistance.value = inputCadence.value = inputDuration.value = inputElevation.value = '';
}
_renderWorkoutMarker(workout) {
L.marker(workout.coords).addTo(this.#map) // add marker
.bindPopup( // tạo popup vào Marker này
L.popup({ // Phần popup option
maxWidth: 250, // các option này tìm trong docs của Leaflet
minWidth: 100,
autoClose: false,
closeOnClick: false,
className: `${workout.type}-popup`,
})
)
.setPopupContent('workout') // Thay đổi nội dung cho popup
.openPopup();
}
_renderWorkout(workout) {
const html = `
<li class="workout workout--${workout.type}" data-id="${workout.id}">
<h2 class="workout__title">${workout.description}</h2>
<div class="workout__details">
<span class="workout__icon">${workout.type === 'running' ? '🏃♂️' : '🚴♀️'}</span>
<span class="workout__value">${workout.distance}</span>
<span class="workout__unit">km</span>
</div>
<div class="workout__details">
<span class="workout__icon">⏱</span>
<span class="workout__value">${workout.duration}</span>
<span class="workout__unit">min</span>
</div>
`
if (workout.type == 'running')
html += `
<div class="workout__details">
<span class="workout__icon">⚡️</span>
<span class="workout__value">${workout.pace.toFixed(1)}</span>
<span class="workout__unit">min/km</span>
</div>
<div class="workout__details">
<span class="workout__icon">🦶🏼</span>
<span class="workout__value">${workout.cadance}</span >
<span class="workout__unit">spm</span>
</div >
</li >
`;
if (workout.type == 'running')
html += `
<div class="workout__details">
<span class="workout__icon">⚡️</span>
<span class="workout__value">${workout.speed.toFixed(1)}</span>
<span class="workout__unit">km/h</span>
</div>
<div class="workout__details">
<span class="workout__icon">⛰</span>
<span class="workout__value">${workout.elevationGain}</span>
<span class="workout__unit">m</span>
</div>
</li>
`;
form.insertAdjacentHTML('afterend', html);
}
}
const app = new App();


), chứ gặp cái code nó làm xấu rồi minify thì vui lắm
