Показать сообщение отдельно
  #18 (permalink)  
Старый 04.05.2020, 22:57
Аватар для Malleys
Профессор
Отправить личное сообщение для Malleys Посмотреть профиль Найти все сообщения от Malleys
 
Регистрация: 20.12.2009
Сообщений: 1,714

Сообщение от Безнадежный программист
Хорошо, я попыталась исправить и это, спасибо, но что дальше?
Совершенно правильный вопрос! Вы написали пару сотен тысяч обработчиков событии для решения трёх проблем, а код совершенно запутанный и непонятный! В такой запутанности нет ничего необычного — jQuery не предназначен для работы с состоянием, в вашем примере можно сделать «одну хитрость» — для jQuery оставить простенькие задачи типа переключить имя класса у элемента или добавить строчку в таблицу, а анимацию элементов делать на CSS. Такой подход отодвигает проблемы до тех пор пока вы опять не начнёте управлять состоянием.

Я вам рекомендую использовать текстовый редактор с подсветкой синтаксиса, чтобы вы видели хотя бы синтаксические ошибки. Например, Visual Studio Code — https://code.visualstudio.com/

Если у вас нет возможности установить, или вы не хотите ничего устанавливать, то вы можете использовать CodeSandBox — редактор, который работает без установки, вы пишете код и сразу видите результат — https://codesandbox.io/

Давайте начнём с того, что конструкции вида...
$(".colors").hover(function () {
	if ($(this).css("background-color") != tr_clr)
		$(this).css("background-color", "#1F233C")
}, function () {
	if ($(this).css("background-color") != tr_clr)
		$(this).css("background-color", "white")
});

могут быть заменены на соответствующий CSS, в конце концов вы именно CSS и меняете...
.colors {
	background-color: white;
}
.colors:hover {
	background-color: #1F233C;
}

Также ваш скрипт, который добавляет этот функционал, находится внутри обработчика события click, а это значит, что у вас при каждом нажатии добавляется всё больше и больше обработчиков событии mouseover и mouseout (именно так сделан hover в jQuery) на строчки таблицы. Притом у первых строк получается больше всего обработчиков, т. к. на только что добавленную строчку добавляется 1 обработчик и на каждую предыдущую добавленную строчку также добавляется по обработчику.

Однако стоит учитывать, что у вас в коде определяются по два обработчика на строчку — один для цвета текста, а другой для цвета фона строчки, т. е. общее число удваивается. Для событии mouseover и mouseout — число ещё удваивается. Так что если 332 раза нажать на ваш список, то к 332-ум созданным строчкам добавится 2 * 2 * (1 + 2 + ... + 331 + 332) = 221112 обработчиков событии!



Также анимация появления должна делаться на CSS эффективным способом при помощи @keyframes.

Также вместо...
var t = $(this)[0].innerText;
можно написать...
var t = this.innerText;
Но jQuery-писатели без jQuery-обёрток уже не могут, поэтому напишут так...
var t = $(this).text();


После очистки кода от мусора, вскрылись ваши истинные помыслы — вы хотите вставить нажатый текст из списка в таблицу...
jQuery("#moto_models li").click(function () {
	var t = $(this).text();
	$("#moto_table").append("<tr><td>" + t + "</td></tr>");
});


Также стоит учитывать, что элементы списка не фокусируемые, а следовательно доступность для нажатия ограничена. Вам стоит заменить текст на кнопки. Кнопки для того и существуют, чтобы на них нажимать!

Насчёт отмены hover — зачем вам изобретать костыли, когда есть CSS, и именно его вы меняете через JS, что практически сложно затем отлаживать. Почему бы сразу не писать CSS?

Сообщение от Безнадежный программист
JS для меня очень и очень слабо раскрыт, так что о jQuery даже страшно говорить.
jQuery заставляет писать сложный, запутанный код... Вы сами убедились в этом, когда попытались написать простенькое переключение вспышки или возвратить исходное состояние кнопки... В поисковой системе можно найти сотни статей «Вам не нужен jQuery», если только вы не китайский коммунист, который любит решать простые проблемы чрезвычайно сложными и не очевидным образом.

Вот некие исправления в коде, и только два обработчика событии...
<!DOCTYPE html>
<html>
<head>
	<title> Практическая работа № 16 (1) </title>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.0/jquery.min.js"></script>
	<style>
		ol li:nth-child(4) { color: blue; }
		ol li button {
			all: unset;
			border: 4px solid transparent;
		}
		tr > th, tr > td {
			background-color: white; color: black;
			animation: 1s appear;
			border: 1px solid #888;
			padding: 1em;
			transition: 300ms;
		}
		tr > th:hover, tr > td:hover {
			background-color: #1F233C; color: white;
		}
		tr > td.highlight {
			background: gold; color: black;
		}
		#moto_table {
			animation: 1.5s appear;
			border-collapse: collapse;
			cursor: default;
		}
		@keyframes appear { from { opacity: 0; } }
		.button {
			border: 0; border-radius: 0.5em;
			padding: 1em; margin: 1em;
			background-color: #f1f1f5;
			font: inherit;
		}
		.button:hover {
			background-color: #32375d;
			color: white;
		}
	</style>
</head>
<body>
	<ol id="moto_models">
		<li><button>Харлей Дэвидсон</button></li>
		<li><button>Кроссовый мотоцикл</button></li>
		<li><button>Гоночный мотоцикл</button></li>
		<li><button>Концептуальный мотоцикл</button></li>
	</ol>

	<button class="button">Отправить заявку</button>

	<table id="moto_table" class="color_table">
		<tr><th>Таблица</th></tr>
	</table>

	<script>
		var activeElement;
		$("#moto_models").on("click", "button", function (event) {
			$("#moto_table").append("<tr><td>" + $(this).text() + "</td></tr>");

			if(this == activeElement) {
				$(this).css("border-color", "transparent");
				activeElement = null;
			} else {
				$(activeElement).css("border-color", "transparent");
				$(this).css("border-color", event.shiftKey ? "#c00" : "#333");
				activeElement = this;
			}
		});
		$("#moto_table").on("click", "td", function() {
			$(this).toggleClass("highlight");
		});
	</script>
</body>
</html>


Вызов $("#moto_models") вернёт вам не ссылку на элемент или список узлов DOM, а некий jQuery-объект. Это означает, что jQuery-объект содержит совершенно другие методы, чем обычная ссылка на элемент или список список узлов DOM.

Тем не менее, эти ссылки всё время вылазят наружу в реальных проектах. Как бы jQuery не старался уйти от них, вам всё равно постоянно приходится оперировать ими, пусть даже просто оборачивая эти ссылки в $(). Как у вас было...
var t = $(this)[0].innerText;
Это не ваша проблема — это плохой дизайн.

Так что же делать дальше? Не учите jQuery, учите современную web-разработку — список тем, которую нужно знать: https://andreasbm.github.io/web-skills/
Ответить с цитированием