У меня есть 2 кнопки с идентификаторами «видео-кнопка» и «фото-кнопка». При нажатии каждой кнопки мне нужно выполнить набор действий для изменения css или удаления/добавления класса для определенных элементов HTML. По сути, для каждого элемента мне нужно переключить их начальное состояние обратно и принудительно. Подробности смотрите в коде:
$('#videos-button').on('click',function(){
$("#ib-row").css({'display':'none'});
$("#ib-pagination").css({'display':'none'});
$("#ib-video-carousel-pagination").css({'display':'block'});
$("#ib-video-carousel").css({'display':'block'});
$("#photos-button").removeClass('image-block-media-button-selected');
$("#videos-button").addClass('image-block-media-button-selected');
});
$('#photos-button').on('click',function(){
$("#ib-row").css({'display':'block'});
$("#ib-pagination").css({'display':'block'});
$("#ib-video-carousel-pagination").css({'display':'none'});
$("#ib-video-carousel").css({'display':'none'});
$("#videos-button").removeClass('image-block-media-button-selected');
$("#photos-button").addClass('image-block-media-button-selected');
});
Как я могу реорганизовать его более элегантным способом, без дублирования?
одним из способов рефакторинга было бы создание функции, которая принимает кнопку видео или кнопку фотографии в качестве входных данных и возвращает объект (карту) идентификаторов и соответствующих классов. то есть функция (назовем ее получитькласскарту), возвращающая
{ '#id-row' : 'display: none', ... }
когда i/p - кнопка видео и
{ '#id-row' : 'display: block', ... }
когда i/p является фото-кнопкой. Затем переместите логику применения классов, т.е.
function applyStyles(id) {
const styleIdMap = getClassMap(id);
$("#ib-row").css(styleIdMap["#ib-row"]);
$("#ib-pagination").css(styleIdMap["#ib-pagination"]);
...
}
Таким образом, в логике нет повторений.
Вы можете попробовать это:
const ibRowAndPagination = ['#ib-row', '#ib-pagination'];
const ibVideoCarouselAndPagination = ['#ib-video-carousel-pagination', '#ib-video-carousel'];
const photosAndVideosButtons = ['#photos-button', '#videos-button'];
const photosAndVideosButtonsToggleClass = () => photosAndVideosButtons.forEach(el => $(el).toggleClass('image-block-media-button-selected'));
$('#videos-button').on('click', function() {
ibRowAndPagination.forEach(el => $(el).css({'display':'none'}));
ibVideoCarouselAndPagination.forEach(el => $(el).css({'display':'block'}));
photosAndVideosButtonsToggleClass();
});
$('#photos-button').on('click', function() {
ibRowAndPagination.forEach(el => $(el).css({'display':'block'}));
ibVideoCarouselAndPagination.forEach(el => $(el).css({'display':'none'}));
photosAndVideosButtonsToggleClass();
});
Существуют ли какие-либо другие возможности для всех этих элементов, для которых задан свой CSS, кроме комбинаций, показанных в этих двух обработчиках? Например, если у
#ib-row
естьdisplay: block
, всегда ли у#ib-pagination
будетdisplay: block
, у#ib-video-carousel
будетdisplay: none
, а у#photos-button
будет выбранный класс?