Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 07.10.2017, 16:55
Аспирант
Отправить личное сообщение для Булат Азат улы Посмотреть профиль Найти все сообщения от Булат Азат улы
 
Регистрация: 07.09.2016
Сообщений: 83

Использование $(this) в функциях
Здравствуйте. Делаю слайды (ещё придется создать тут одну тему про плавность смены картин). Сделал широоокий блок со всеми фотографиями в один ряд, и перемещаю этот блок с помощью свойства transform:translateX(). И выборку блока и изменение этого свойства нужно выполнить множество раз. Поэтому, я решил создать функцию и использовать его множество раз:
function slaidPoz(poz){
	$(this).prev(".slaidlarBlok").find(".slaidContainer").css("transform", "translateX("+poz+"px)");
}
// и дальше несколько функций типа этого:
$(".kuchuUn").click(function(){
	if(transPoz <= -(slRasBlok.length * slRasBlokWidth - slRasBlokWidth)){ // позиция translateX
		transPoz = 0;
		//slaidPoz(transPoz);
		$(this).prevAll(".slaidlarBlok").find(".slaidContainer").css("transform", "translateX("+transPoz+"px)");
	}else{
		transPoz = transPoz - slRasBlokWidth;
		//slaidPoz(transPoz);
		$(this).prev(".slaidlarBlok").find(".slaidContainer").css("transform", "translateX("+transPoz+"px)");
	}
});

Как видите, вызов функции мне пришлось заблокировать и написать команды вручную. Дубликат (ниже по коду еще несколько раз так), не красиво.
И как я понимаю, причина того, что код не работает, в очень простом: $(this) в объявлении функции неизвестен.
Помогите пожалуйста, как правильно решить эту проблему?
Ответить с цитированием
  #2 (permalink)  
Старый 07.10.2017, 17:47
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,071

Булат Азат улы,
основные способы и примеры тут
bind и $.proxy
Ответить с цитированием
  #3 (permalink)  
Старый 07.10.2017, 17:57
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,071

Булат Азат улы,
slaidPoz.bind(this)(transPoz);

или
$.proxy(slaidPoz, this)(transPoz)
Ответить с цитированием
  #4 (permalink)  
Старый 07.10.2017, 18:21
Аспирант
Отправить личное сообщение для Булат Азат улы Посмотреть профиль Найти все сообщения от Булат Азат улы
 
Регистрация: 07.09.2016
Сообщений: 83

рони,
Спасибо большое!!!
Ответить с цитированием
  #5 (permalink)  
Старый 08.10.2017, 13:53
Аспирант
Отправить личное сообщение для Булат Азат улы Посмотреть профиль Найти все сообщения от Булат Азат улы
 
Регистрация: 07.09.2016
Сообщений: 83

Извините, я, кажется, не полностью понял смысл .bind() и $.proxy(). Или, может, они могут выполняться только при помощи "this"?
Дело в том, что я написал функцию:
function slaidPoz(transPoz){
	return function(){
		var transBlok = $(".slaidContainer");
		if(transPoz <= -(slRasBlok.length * slRasBlokWidth - slRasBlokWidth)){
			transPoz = 0;
			transBlok.css("transform", "translateX("+transPoz+"px)");
		}else{
			transPoz = transPoz - slRasBlokWidth;
			transBlok.css("transform", "translateX("+transPoz+"px)");
		}
	}
}

Нужно запустить эту функцию несколько раз. Один раз - точно в таком виде, в каком он и написан (по выборке):
setInterval(slaidPoz(transPoz), 6000);

И несколько раз запустить с относительного места (с помощью "this").

То есть, на странице могут быть несколько слайдов, и функция с интервалом (смена изображений) должна работать на всех слайдах. А вот при клике на кнопки вперед/назад, должна запускаться та же функция, только для определенного слайда, с помощью "this".
Вот код HTML:
<div class="slaidlar">
	<div class="slaidlarBlok">
		<div class="slaidContainer"><div class="slaidRasemBlok"><img src="img/slaid/1.jpg"><p>Слайд 1</p></div><div class="slaidRasemBlok"><img src="img/slaid/2.jpg"><p>Слайд 2</p></div><div class="slaidRasemBlok"><img src="img/slaid/3.jpg"><p>Слайд 3</p></div></div>
	</div>
	<img class="next" src="img/arrow-next.png">
	<img class="prev" src="img/arrow-prev.png">
</div>

Получается, в функции переменную transBlok нужно заменить на это:
//это:
$(".slaidContainer");
// на это:
$(this).prevAll(".slaidlarBlok").find(".slaidContainer");

Что-то мне подсказывает, что это можно сделать с помощью .bind() и $.proxy(), но не могу добиться работоспособности своих поделок.
Ответить с цитированием
  #6 (permalink)  
Старый 08.10.2017, 14:29
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,071

Булат Азат улы,
на всякий случай https://javascript.ru/forum/dom-wind...tml#post430374

и лучше никогда не использовать setInterval, достаточно setTimeout или requestAnimationFrame
Ответить с цитированием
  #7 (permalink)  
Старый 08.10.2017, 15:53
Аспирант
Отправить личное сообщение для Булат Азат улы Посмотреть профиль Найти все сообщения от Булат Азат улы
 
Регистрация: 07.09.2016
Сообщений: 83

рони,
Посмотрел я слайды, ссылку которой вы дали - многое понял, немногое - не понял А не понял потому, что почему-то мой "постоянно посещаемый" сайт не работает. Не мог понять некоторые неизвестные мне функции типа "loop". Но всё же, там ведь нет примера выборки, которая нужна мне.
И на счёт совета не использовать "setInterval" - по-моему же, как я знаю, "setTimeout" запускае функцию только один раз? А тут нужно, чтобы запускался бесконечно, через опр. время. Или я не прав? И, если можно, не могли бы вкратце объяснить, почему не использовать setInterval? Он очень "тяжёлый"?
Вот мой код слайдов... Размеры задавать не нужно - каков размер изображения - таков и размер слайда. Неплохо же?
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Слайд</title>
<style type="text/css">
body {
	min-height: 300px;
	background-color: #E4E4E4;
}
#topBlok {
	width: 500px;
	margin: 0 auto;
	padding: 20px 0;
	background-color: #FFFFFF;
}

h1 {
	margin: 10px;
	font-size: 24px;
	font-weight: bold;
	text-align: center;
}

.slaidlar {
	margin: 0 auto;
	padding: 0;
	position: relative;
	
}

.slaidlarBlok {
	position: relative;
	overflow: hidden;
}

.slaidContainer {
	transition: 0.5s;
}

.slaidRasemBlok {
	display: inline-block;
}

.slaidRasemBlok p {
	width: 100%;
	height: 32px;
	box-sizing: border-box;
	margin: 0;
	padding: 5px 10px;
	position: absolute;
	bottom: 2px;
	font-size: 20px;
	color: #FFFFFF;
	background-color: rgba(20,20,20,0.7);
	border-top: 1px solid #000000;
}

.kuchuUn, .kuchuSul {
	position: absolute;
	top: calc(50% - 21px);
}

.kuchuUn:hover, .kuchuSul:hover {
	cursor: pointer;
}

.kuchuUn {
	right: -24px;
}

.kuchuSul {
	left: -24px;
}
</style>

<script src="https://code.jquery.com/jquery-3.2.1.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function(){
	var slRasBlok = $(".slaidRasemBlok");
	var slRasBlokWidth = slRasBlok.width();
	var transPoz = 0;
	$(".slaidlar").width(slRasBlokWidth);
	$(".slaidRasemBlok p").width(slRasBlokWidth);
	$(".slaidContainer").width(slRasBlok.length * slRasBlokWidth);
	function slaidPoz1(poz1){
		$(this).prevAll(".slaidlarBlok").find(".slaidContainer").css("transform", "translateX("+poz1+"px)");
	}
	function slaidPoz(transPoz){
		return function(){
			var transBlok = $(".slaidContainer");
			if(transPoz <= -(slRasBlok.length * slRasBlokWidth - slRasBlokWidth)){
				transPoz = 0;
				transBlok.css("transform", "translateX("+transPoz+"px)");
			}else{
				transPoz = transPoz - slRasBlokWidth;
				transBlok.css("transform", "translateX("+transPoz+"px)");
			}
		}
	}
	setInterval(slaidPoz(transPoz), 6000);
	//$(".kuchuUn").click(slaidPoz(transPoz));
	
	$(".kuchuUn").click(function(){
		if(transPoz <= -(slRasBlok.length * slRasBlokWidth - slRasBlokWidth)){
			transPoz = 0;
			slaidPoz1.bind(this)(transPoz);
		}else{
			transPoz = transPoz - slRasBlokWidth;
			slaidPoz1.bind(this)(transPoz);
		}
	});
	$(".slaidContainer").click(function(){
		if(transPoz <= -(slRasBlok.length * slRasBlokWidth - slRasBlokWidth)){
			transPoz = 0;
			$(this).css("transform", "translateX("+transPoz+"px)");
		}else{
			transPoz = transPoz - slRasBlokWidth;
			$(this).css("transform", "translateX("+transPoz+"px)");
		}
	});
	$(".kuchuSul").click(function(){
		if(transPoz >= 0){
			transPoz = -(slRasBlok.length * slRasBlokWidth - slRasBlokWidth);
			slaidPoz1.bind(this)(transPoz);
		}else{
			transPoz = transPoz + slRasBlokWidth;
			slaidPoz1.bind(this)(transPoz);
		}
	});
});
</script>
</head>
<body>
	<div id="topBlok">
		<h1>Слайды</h1>
		<div class="slaidlar">
			<div class="slaidlarBlok">
				<div class="slaidContainer"><div class="slaidRasemBlok"><img src="img/slaidlar/1.jpg" style="background-color: #FF0000;" width="500" height="200"><p>Слайд 1</p></div><div class="slaidRasemBlok"><img src="img/slaidlar/2.jpg" style="background-color: #00FF00;" width="500" height="200"><p>Слайд 2</p></div><div class="slaidRasemBlok"><img src="img/slaidlar/3.jpg" style="background-color: #0000FF;" width="500" height="200"><p>Слайд 3</p></div></div>
			</div>
			<img class="kuchuUn" src="img/arrow-next.png" width="24" height="43">
			<img class="kuchuSul" src="img/arrow-prev.png" width="24" height="43">
		</div>
	</div>
</body>
</html>

Последний раз редактировалось Булат Азат улы, 08.10.2017 в 16:06.
Ответить с цитированием
  #8 (permalink)  
Старый 08.10.2017, 17:24
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,071

Сообщение от Булат Азат улы
Он очень "тяжёлый"?
без него проще и надёжнее
Ответить с цитированием
  #9 (permalink)  
Старый 08.10.2017, 17:26
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,071

Булат Азат улы,
замена setinterval
рекурсивный-settimeout
Ответить с цитированием
  #10 (permalink)  
Старый 08.10.2017, 22:04
Аспирант
Отправить личное сообщение для Булат Азат улы Посмотреть профиль Найти все сообщения от Булат Азат улы
 
Регистрация: 07.09.2016
Сообщений: 83

рони,
setInterval заменил, написал код вот так (думаю, правильно - всё нормально работает):
(function slaidTime() {
	setTimeout(function(){
		var transBlok = $(".slaidContainer");
		if(transPoz <= -(slRasBlok.length * slRasBlokWidth - slRasBlokWidth)){
			transPoz = 0;
			transBlok.css("transform", "translateX("+transPoz+"px)");
		}else{
			transPoz = transPoz - slRasBlokWidth;
			transBlok.css("transform", "translateX("+transPoz+"px)");
		}
		slaidTime();
	}, 6000);
}).call(this);


Спасибо за подсказку об setInterval. Почитав, я поня, что при работе он забивает память, так как "историю" не чистит.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
JavaScript. Уровень 3в. Серверное программирование на Node.js maxy666 Node.JS 8 10.08.2014 00:36
$(this) в теле плагина prison47 jQuery 32 03.03.2013 23:50
Использование $(this) внутри функции Dorian_bs Общие вопросы Javascript 6 21.11.2011 11:10
$(this) выборка Kuklavod jQuery 4 01.11.2011 20:15
Использование одной переменной в нескольких функциях (Sandr) Общие вопросы Javascript 10 10.07.2011 13:42