Javascript-форум (https://javascript.ru/forum/)
-   jQuery (https://javascript.ru/forum/jquery/)
-   -   Исполнять скрипт только для текущего элемента (https://javascript.ru/forum/jquery/54206-ispolnyat-skript-tolko-dlya-tekushhego-ehlementa.html)

snovapavel 08.03.2015 23:13

Исполнять скрипт только для текущего элемента
 
Здравствуйте, друзья!

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

А так же не понимаю как сделать проверку на полосу прокрутки. Ведь если её нет - зачем раздвигать блок.

Прошу помощи.

Ссылка на проект: http://jsfiddle.net/n995Lmdj/

Скрипт:

$(document).ready(function() {

    var t;

    $('.container').hover(function() {

        clearTimeout(t);

        $('.container').animate({width: "200px"},{queue:false,duration:200}).css('overflow-x', 'auto');

		}, function() {

        t = setTimeout(function() {$('.container').animate({width: "150px"},{queue:false,duration:200}).css('overflow-x', 'auto');},

        500);

	});

});


Буду невероятно признателен за помощь!

рони 09.03.2015 00:07

Цитата:

Сообщение от snovapavel
только для текущего блока

$(this).animate

рони 09.03.2015 00:09

Цитата:

Сообщение от snovapavel
как сделать проверку на полосу прокрутки

http://learn.javascript.ru/metrics#scrollwidth-height

рони 09.03.2015 00:19

snovapavel,
http://jsfiddle.net/n995Lmdj/2/

dd_smol 09.03.2015 00:47

Не совсем понимаю, что вы хотите сделать. Попробуйте что-то в этом роде.
$(function() {
	$('.container').each(function() {
		$(this).css({'overflow-x': 'auto'});
		
		if ( this.scrollWidth > 150 ) {
			$(this).on('mouseover', function(e) {
					$(this).animate({'width': 200}, 200);
				})
				.on('mouseout', function(e) {
					$(this).delay(500).animate({'width': 150}, 200);
				});
		}
	});
});

snovapavel 09.03.2015 08:58

Благодарю вас
 
Цитата:

Сообщение от рони (Сообщение 360191)

Я внёс необходимые изменения, но теперь блок вообще не возвращается назад почему-то...

Вот ссылка: http://jsfiddle.net/n995Lmdj/4/

Что я пытаюсь реализовать:

1. Чтобы блок раздвигался на всю ширину находящегося в нём контента, но не более 600px (вопрос к мастерам, как приписать сюда это условие
width: this.scrollWidth
?).

2. Чтобы если я быстро наведу и уберу мышку с блока, он бы не прыгал туда-сюда 10 раз пока не отпрыгает все наведения (именно для этого я и прописал это свойство
queue:false
).

3. Проверка на время, нужна для того, чтобы пока мышка находится над блоком он не закрывался, а закрывался только через полсекунды после того - как я уберу её. И опять же, блок не дёргается туда-сюда если я уберу и верну мышь обратно на блок (как в меню например).

4.
.css('overflow-x', 'auto')
необходимо для того, чтобы не дёргались полосы прокрутки, то пропадая, то появляясь вновь. Поэтому и пришлось их прописывать вообще везде.

Буду признателен, вам за помощь!

laimas 09.03.2015 10:12

Чтобы блок раздвигался на всю ширину находящегося в нём контента, но не более 600

$(e).animate({'width': $(e).innerWidth()}, 200);


он бы не прыгал туда-сюда 10 раз пока не отпрыгает все

mouseover - mouseenter
mouseout - mouseleave

рони 09.03.2015 10:17

Цитата:

Сообщение от snovapavel
Чтобы блок раздвигался на всю ширину находящегося в нём контента, но не более 600px

width: this.scrollWidth > 600 ? 600 : this.scrollWidth
Цитата:

Сообщение от snovapavel
он бы не прыгал туда-сюда

stop() и
Цитата:

Сообщение от laimas
mouseover - mouseenter
mouseout - mouseleave

4 вопрос ??? что именно хотите

snovapavel 09.03.2015 10:31

Цитата:

Сообщение от рони
4 вопрос ??? что именно хотите

Чтобы не дёргались полосы прокрутки, пока происходит увеличение блока они пропадают из виду, если не прописать .css('overflow-x', 'auto')
на движение туда и обратно.

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

Огромное спасибо!

laimas 09.03.2015 11:08

$('.container').mouseenter(function() {
 ....
$(this).stop().animate({width: this.scrollWidth > 600 ? 600 : this.scrollWidth}, 200).css('overflow-x', 'auto');
....


PS. Кстати, если это по классу, а значит не один объект, то нужно остановить текущую анимацию у всех объектов.

рони 09.03.2015 12:12

snovapavel,
<!DOCTYPE HTML>

<html>

<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type="text/css">
   .w {
  display: block;
  width: 150px;
}

.container {
  margin: 0 0 50px 0;
  padding: 0;
  background-color: red;
  position: relative;
   overflow-x:  scroll;
  z-index: 9999;
}
  </style>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
  <script>
$(function() {
    $(".container").filter(function() {
        var scroll = 150 < this.scrollWidth;
        $(this).css("overflow-x", function(b, c) {
            return scroll ? "scroll" : "auto"
        });
        return scroll
    }).mouseover(function() {
        $(this).stop(true).animate({
            width: 600 < this.scrollWidth ? 600 : this.scrollWidth
        }, 200).css("overflow-x", "scroll")
    }).mouseleave(function() {
        $(this).stop(true,true).delay(900).queue(function() {
            $(this).animate({
                width: 150
            }, 200).dequeue().css("overflow-x", "scroll")
        })
    })
});
 </script>
</head>

<body>  <div class="w">

    <pre class="container">Просто длинный текст. Просто длинный текст. Просто длинный текст. Просто длинный текст.
Просто длинный текст. Просто длинный текст. Просто длинный текст. Просто длинный текст.

Просто длинный текст. Просто длинный текст. Просто длинный текст. Просто длинный текст.</pre>

    <pre class="container">Текст. Текст. Текст. Текст. Текст. Текст. Текст. Текст. Текст.

Текст. Текст. Текст. Текст. Текст.</pre>

    <pre class="container">Текст.</pre>

</div>
</body>

</html>

snovapavel 09.03.2015 12:17

laimas,

Большое спасибо, теперь всё работает как надо.

Вот код который получился:

$(document).ready(function() {

    var t;

    $('.container').hover(function() {

        clearTimeout(t);

        $(this).stop().animate({width: this.scrollWidth > 600 ? 600 : this.scrollWidth}, 200).css('overflow-x', 'auto');

		}, function() {

        t = setTimeout(function() {$('.container').animate({width: "150px"},{queue:false,duration:200}).css('overflow-x', 'auto');},

        500);

	});

});


Но осталась одна проблема, если навести мышку на верхний блок и передвинуть мышку на соседний, то не закроются оба пока мышку не уберёшь, а ведь предыдущий должен закрываться...

Опытным путём удалось выяснить, что дело вот в этом отрезке кода:

}, function() {

        t = setTimeout(function() {$('.container').animate({width: "150px"},{queue:false,duration:200}).css('overflow-x', 'auto');},

        500);


подскажите как исправить.

Вот проект на jsfiddle http://jsfiddle.net/n995Lmdj/5/

Всем большое спасибо!

рони 09.03.2015 12:21

snovapavel,
чем 11 пост не устраивает?

snovapavel 09.03.2015 12:35

рони,

Всё отлично, (немного опередили меня).

Осталась только одна маленькая проблема, - задержка перед скрытием блока половина секунды. Я прописал свойство .delay(500) вот сюда:

.mouseleave(function() {
        $(this).stop(true).delay(500).animate({
            width: 150
        }, 200).css("overflow-x", "scroll")


Но теперь, пропадает полоса прокрутки при сворачивании блока...

Простите меня бестолкового. Как это исправить?

рони 09.03.2015 13:22

snovapavel,
смотрите пост 11 снова

snovapavel 09.03.2015 15:23

рони,

Дорогой друг!

Я признателен вам за помощь, но в какой-то момент времени мы свернули не туда и теперь вернулись все те проблемы, от которых я два дня старательно уходил.

Преимущества моего сниппета:

- Реагирует даже на мгновенный проход мышкой над блоком, даже независимо от того, в фокусе окно браузера или нет;
- При проходе над блоком - блок раскрывается полностью, отсчитывает секунду, и только потом закрывается. Если провести мышкой над блоком через 0.9 секунды, он опять отсчитает секунду и только потом закроется. Дёргаться он при этом не будет.
- Очень хорошо реагирует на мышь, ловит её проход над собой даже за доли секунды.
- Не болтается туда-сюда если быстро водить.

Недостатки моего сниппета:

- Раскрываются все блоки на странице сразу (это именно-то, что нужно было решить).
- Раскрывались все блоки на странице, независимо от наличия полосы прокрутки (вы это решили).

Мой сниппет:

$(document).ready(function() {

    var t;

    $('.container').hover(function() {

        clearTimeout(t);

        $('.container').animate({width: "200px"},{queue:false,duration:200}).css('overflow-x', 'auto');

		}, function() {

        t = setTimeout(function() {$('.container').animate({width: "150px"},{queue:false,duration:200}).css('overflow-x', 'auto');},

        500);

	});

});


Откуда я взял пример который доработал: ссылка

Я вас очень прошу, доработать именно его, так как хочется наконец сделать адекватное и удобное меню, работающее идеально.

Огромное спасибо за оказанную помощь!

рони 09.03.2015 15:49

snovapavel,
посмотрите пост 11 и скажите что не так

laimas 09.03.2015 17:11

Но осталась одна проблема, если навести мышку на верхний блок и передвинуть мышку на соседний, то не закроются оба пока мышку не уберёшь, а ведь предыдущий должен закрываться...

Опытным путём удалось выяснить, что дело вот в этом отрезке кода:


Я писал, что перед запуском анимации текущего блока, если нужно, то можно остановить анимацию у всех блоков $('.container').stop(). Зачем вам таймер и hover? Зачем queue:false, если по умолчанию все назначенные анимации и не добавляются в очередь?

snovapavel 10.03.2015 12:23

рони,

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

А так, я вынужден признать свою ошибку. Я написал отвратительный код... Простите.

Спасибо вам за работу, друзья!

рони 10.03.2015 13:22

Цитата:

Сообщение от snovapavel
Дорогой друг, вы можете прикрутить сюда таймер, чтобы при наведении мышкой, всегда заново начинался отсчёт половины секунды до скрытия и блок не сворачивался? Тогда можно будет избавиться от скакания.

не понимаю что у вас скачет в 11 посте


Часовой пояс GMT +3, время: 20:50.