IIIu6ko
@IIIu6ko

Как упростить такой код?

<div class="faq__question-container">
	<div class="faq__question">
		<img class="faq__icon faq__icon--women" src="imgs/dropdown/dropdown__women.png" alt="">
		<span class="faq__question-text">Женщине</span>
	</div>
	<div class="faq__answer">
		<p class="faq__answer-text">Избавление от ненужных  стереотипов и комплексов, обретение уверенности в себе, раскрепощение и повышение уровня сексуальности.</p>
	</div>
</div>

<div class="faq__question-container">
	<div class="faq__question">
		<img class="faq__icon faq__icon--man" src="imgs/dropdown/dropdown__man.png" alt="">
		<span class="faq__question-text">Женщине</span>
	</div>
	<div class="faq__answer">
		<p class="faq__answer-text">Избавление от ненужных  стереотипов и комплексов, обретение уверенности в себе, раскрепощение и повышение уровня сексуальности.</p>
	</div>
</div>

<div class="faq__question-container">
	<div class="faq__question">
		<img class="faq__icon faq__icon--manwomen" src="imgs/dropdown/dropdown__manwomen.png" alt="">
		<span class="faq__question-text">Женщине</span>
	</div>
	<div class="faq__answer">
		<p class="faq__answer-text">Избавление от ненужных  стереотипов и комплексов, обретение уверенности в себе, раскрепощение и повышение уровня сексуальности.</p>
	</div>
</div>


$('.faq__question').click(function() {
	$(this).siblings('.faq__answer').slideToggle();

	if($(this).find('.faq__icon').attr('src') == 'imgs/dropdown/dropdown__women.png') {
		iconwomen = $(this).find('.faq__icon').attr('src');
		$(this).find('.faq__icon').attr('src', 'imgs/dropdown/dropdown__open.png');
	} 
	else if($(this).find('.faq__icon').attr('src') == 'imgs/dropdown/dropdown__man.png') {
		iconman = $(this).find('.faq__icon').attr('src');
		$(this).find('.faq__icon').attr('src', 'imgs/dropdown/dropdown__open.png');
	}
	else if($(this).find('.faq__icon').attr('src') == 'imgs/dropdown/dropdown__manwomen.png') {
		iconmanwomen = $(this).find('.faq__icon').attr('src');
		$(this).find('.faq__icon').attr('src', 'imgs/dropdown/dropdown__open.png');
	}
	else {
		if($(this).find('.faq__icon').attr('class') == 'faq__icon faq__icon--women') {
			$(this).find('.faq__icon').attr('src', iconwomen);
		}
		else if ($(this).find('.faq__icon').attr('class') == 'faq__icon faq__icon--man') {
			$(this).find('.faq__icon').attr('src', iconman);
		}
		else if ($(this).find('.faq__icon').attr('class') == 'faq__icon faq__icon--manwomen') {
			$(this).find('.faq__icon').attr('src', iconmanwomen);
		}
	}
});


30fe7b7b2faa4a0eb80aef054cb8d47d.png

На какой-нибудь jsfiddle выложить не могу из-за того, что вся суть в png'шных иконках.

Есть 3 таба, которые разворачиваются по клику. В каждом табе есть своя иконка.. При клике на каждый, иконка меняется на плюс в красном круге. Необходимо чтобы можно было открыть и закрыть каждый таб и не потерять изначальную иконку, то есть изначальное значение src. Чтобы такое провернуть я додумался только на привязку к классу..
Как вы понимаете js я знаю на низком уровне, т.ч. если будут ответы, то пожалуйста объясните как и что работает.
  • Вопрос задан
  • 222 просмотра
Решения вопроса 2
Negwereth
@Negwereth
lvivcss.com.ua
Мой ответ будет содержать две части - в первой я поясню как оптимизировать конкретно ваш код, а во второй покажу как такое надо делать правильно.

Часть первая.

Первым делом сохраним элемент, к которому вы обращаетесь больше всего, в отдельную переменную:

$('.faq__question').click(function() {
  $(this).siblings('.faq__answer').slideToggle();
  const icon = $(this).find('.faq__icon');
  const iconSrc = icon.attr('src');

  if (iconSrc == 'imgs/dropdown/dropdown__women.png') {
    iconwomen = iconSrc;
    icon.attr('src', 'imgs/dropdown/dropdown__open.png');
  } else if(iconSrc == 'imgs/dropdown/dropdown__man.png') {
    iconman = iconSrc;
    icon.attr('src', 'imgs/dropdown/dropdown__open.png');
  } else if(iconSrc == 'imgs/dropdown/dropdown__manwomen.png') {
    iconmanwomen = iconSrc;
    icon.attr('src', 'imgs/dropdown/dropdown__open.png');
  } else {
    if (icon.attr('class') == 'faq__icon faq__icon--women') {
      icon.attr('src', iconwomen);
    } else if (icon.attr('class') == 'faq__icon faq__icon--man') {
      icon.attr('src', iconman);
    } else if (icon.attr('class') == 'faq__icon faq__icon--manwomen') {
      icon.attr('src', iconmanwomen);
    }
  }
});


Далее надо разобраться с условиями, они у вас не оптимальны. Выходит, что если иконка не подходит по критерию, вы опять же перебором ставите ссылку назад. Вот здесь чуть яснее, когда именно какое действие надо делать:

var iconman, iconwomen, iconmanwomen;
var icons = ['imgs/dropdown/dropdown__women.png', 'imgs/dropdown/dropdown__man.png', 'imgs/dropdown/dropdown__manwomen.png'];

$('.faq__question').click(function() {
  $(this).siblings('.faq__answer').slideToggle();
  const icon = $(this).find('.faq__icon');
  const iconSrc = icon.attr('src');

  if (icons.includes(iconSrc)) {
    if (iconSrc == 'imgs/dropdown/dropdown__women.png') {
      iconwomen = iconSrc;
      icon.attr('src', 'imgs/dropdown/dropdown__open.png');
    } else if(iconSrc == 'imgs/dropdown/dropdown__man.png') {
      iconman = iconSrc;
      icon.attr('src', 'imgs/dropdown/dropdown__open.png');
    } else if(iconSrc == 'imgs/dropdown/dropdown__manwomen.png') {
      iconmanwomen = iconSrc;
      icon.attr('src', 'imgs/dropdown/dropdown__open.png');
    }
  } else {
    if (icon.attr('class') == 'faq__icon faq__icon--women') {
      icon.attr('src', iconwomen);
    } else if (icon.attr('class') == 'faq__icon faq__icon--man') {
      icon.attr('src', iconman);
    } else if (icon.attr('class') == 'faq__icon faq__icon--manwomen') {
      icon.attr('src', iconmanwomen);
    }
  }
});

Теперь можно вынести повторяемый код:

var iconman, iconwomen, iconmanwomen;
var icons = ['imgs/dropdown/dropdown__women.png', 'imgs/dropdown/dropdown__man.png', 'imgs/dropdown/dropdown__manwomen.png'];

$('.faq__question').click(function() {
  $(this).siblings('.faq__answer').slideToggle();
  const icon = $(this).find('.faq__icon');
  const iconSrc = icon.attr('src');

  if (icons.includes(iconSrc)) {
    if (iconSrc == 'imgs/dropdown/dropdown__women.png') {
      iconwomen = iconSrc;
    } else if(iconSrc == 'imgs/dropdown/dropdown__man.png') {
      iconman = iconSrc;
    } else if(iconSrc == 'imgs/dropdown/dropdown__manwomen.png') {
      iconmanwomen = iconSrc;
    }
    icon.attr('src', 'imgs/dropdown/dropdown__open.png');
  } else {
    let iconOldSrc;
    if (icon.attr('class') == 'faq__icon faq__icon--women') {
      iconOldSrc = iconwomen;
    } else if (icon.attr('class') == 'faq__icon faq__icon--man') {
      iconOldSrc = iconman;
    } else if (icon.attr('class') == 'faq__icon faq__icon--manwomen') {
      iconOldSrc = iconmanwomen);
    }
    icon.attr('src', iconOldSrc);
  }
});


Теперь код стал чище и, за счёт работы с переменными, будет проще находить проблемы. Но всё-равно этот код неоптимален с точки зрения логики. Намного проще хранить состояние в самом объекте:

$('.faq__question').click(function() {
  $(this).siblings('.faq__answer').slideToggle();
  const icon = $(this).find('.faq__icon');
  const iconSrc = icon.attr('src');
  const dataIconSrc = icon.attr('data-src');

  if (!dataIconSrc) {
    icon.attr('data-src', iconSrc);
    icon.attr('src', 'imgs/dropdown/dropdown__open.png');
  } else {
    icon.attr('src', dataIconSrc);
    icon.attr('data-src', null);
  }
});


Теперь если аттрибут `data-src` имеет значение, значит таб открыт.

Часть вторая.

А вообще такие задачи решаются с помощью CSS. Иконку лучше делать блоком с фоновым изображением:

.icon.man {
  background-image: "imgs/dropdown/dropdown__man.png";
}
.icon.woman {
  background-image: "imgs/dropdown/dropdown__woman.png";
}
.icon.manwoman {
  background-image: "imgs/dropdown/dropdown__manwoman.png";
}
.icon.open {
  background-image: "imgs/dropdown/dropdown__open.png";
}

И тогда скрипт будет выглядеть как-то так (я подозреваю, я просто именно с jQuery не люблю работать):
$('.faq__question').click(function() {
  $(this).siblings('.faq__answer').slideToggle();

  $(this).find('.faq__icon').toggleClass("open");
});
Ответ написан
Exploding
@Exploding
wtf?
Ну на скорую руку я бы все картинки запихнул в css и в итоге это полотно сократилось бы примерно до такого кода:
<div class="faq__question custom-woomen" data-tgl="custom-woomen">Женщине</div>
<div class="faq__answer">....</div>

$(".faq__question").on("click", function(){
  $(this).toggleClass($(this).data("tgl")+" open-class");
});


Или же скорее всего потом подумав снес js код, css оставил и получилось бы такое:
<details>
    <summary>Женщине</summary>
    <p>Избавление от ненужных  стереотипов и комплексов, обретение уверенности в себе, раскрепощение и повышение уровня сексуальности.</p>
</details>


и в css типа такого:
details > summary{
   background: url('кастомная-тетка-дядька.png') left center no-repeat;
}

details[open] > summary{
   background: url('иконка-плюсик-а-ля-open.png') left center no-repeat;
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы