Красивые всплывающие подсказки с помощью jQuery

Внимательные пользователи моего сайта Share42.com заметили, что на нем с определенной поры появились красивые всплывающие подсказки, и меня попросили рассказать, как такое сделать. Поэтому я хочу поделиться с вами моим очередным небольшим jQuery-скриптом, который поможет украсить ваш веб-ресурс.

Красивые всплывающие подсказки с помощью jQuery

Идею я подсмотрел на сайте электронного бухгалтера «Эльба«. Там приятный и удобный интерфейс, и мне очень понравились всплывающие подсказки, которые присутствуют повсюду.

Я хотел было просто взять из исходников сайта код скрипта, который реализует это дело, но не тут-то было. Там у них столько разных скриптов, собранных в одну кучу (не знаю, как это правильно называется на профессиональном языке), что выудить оттуда что-то конкретное мне было затруднительно.

Поэтому я взял и написал свой скрипт, который делает примерно то же самое. Я знаю, что есть уже множество готовых решений, но мне интереснее самому написать скрипт с нуля, чтобы в очередной раз попрактиковаться с jQuery.

Демонстрация

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

Установка

Код скрипта выглядит следующим образом:

(function($){
$(function() {

	$('span.jQtooltip').each(function() {
		var el = $(this);
		var title = el.attr('title');
		if (title && title != '') {
			el.attr('title', '').append('<div>' + title + '</div>');
			var width = el.find('div').width();
			var height = el.find('div').height();
			el.hover(
				function() {
					el.find('div')
						.clearQueue()
						.delay(200)
						.animate({width: width + 20, height: height + 20}, 200).show(200)
						.animate({width: width, height: height}, 200);
				},
				function() {
					el.find('div')
						.animate({width: width + 20, height: height + 20}, 150)
						.animate({width: 'hide', height: 'hide'}, 150);
				}
			).mouseleave(function() {
				if (el.children().is(':hidden')) el.find('div').clearQueue();
			});
		}
	})

})
})(jQuery)

Сохраните его в файл с расширением .js, например, scripts.js и подключите к сайту перед тегом </head>, не забыв одновременно подключить и фреймворк jQuery, если это еще не сделано. Т.е. в html-код сайта добавляется такой код:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<script type="text/javascript" src="http://ПУТЬ_ДО_ФАЙЛА_НА_ВАШЕМ_САЙТЕ/scripts.js"></script>

Далее нужно добавить в CSS-файл вашего сайта следующие стили:

.jQtooltip {
	position: relative;
	cursor: help;
	border-bottom: 1px dotted;
}
.jQtooltip div {
	display: none;
	position: absolute;
	bottom: -1px;
	left: -1px;
	z-index: 1000;
	width: 190px;
	padding: 8px 12px;
	text-align: left;
	font-size: 12px;
	line-height: 16px;
	color: #000;
	box-shadow: 0 1px 3px #C4C4C4;
	border: 1px solid #DBB779;
	background: #FFF6BD;
	border-radius: 2px;
}

Теперь осталось поместить необходимый текст в тег <span> с классом jQtooltip и атрибутом title, т.е. вот так:

<span class="jQtooltip" title="текст всплывающей подсказки">текст</span>

Если вы желаете, чтобы вместо текста был квадратик, как в примере, тогда в CSS-файл нужно добавить еще такие стили:

.jQtooltip.mini {
	display: inline-block;
	vertical-align: bottom;
	font-size: 11px;
	width: 14px;
	line-height: 13px;
	text-align: center;
	margin-left: 2px;
	top: -2px;
	color: #9A4D18;
	border: 1px solid #FAD28F;
	background: #FFF6BD;
	border-radius: 2px;
}

А html-код в этом случае будет таким:

<span class="jQtooltip mini" title="текст всплывающей подсказки">!</span>

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

Вот, собственно, и все.

P.S. Не сомневаюсь, что скрипт можно сделать и более грамотным, но меня, в принципе, устраивает и то, что получилось.

* * *

Ищите, где разместить свой сайт в Украине? Выбирайте хостинг, проверенный временем — X-HOST. Вы получите качественный и надежный хостинг по выгодным тарифам.

Комментарии (144)

  1. 16 апреля 2012 г. в 19:08

    вот так у меня админке отражается

  2. 16 апреля 2012 г. в 19:10
    <script src='https://sites.google.com/site/vseoblogger/jquery-1.7.1.js' type='text/javascript'/>
    <script src='https://sites.google.com/site/vseoblogger/script.js' type='text/javascript'/>

    Ну и ну, никак не отражается скрипт

    1. 16 апреля 2012 г. в 19:28 / ответ на коммент Марина

      Где-то на сайте sites.google.com нужно открыть доступ к этому файлу всем. Как это сделать, я не знаю.

      1. 16 апреля 2012 г. в 19:34 / ответ на коммент Dimox

        Спасибо, буду «рыть» :)))

      2. 16 апреля 2012 г. в 19:41 / ответ на коммент Dimox

        Дим, открыла доступ и все проявилось! Спасибо Вам!
        Но еще не совсем понятно к каким файлам открыт доступ и кто и что может с ними делать.
        Справка гугла пока молчит.
        Кстати по вашим советам там завела блог, чтоб заливать туда файлы.

      3. 19 апреля 2012 г. в 15:18 / ответ на коммент Dimox

        https://accounts.google.com
        На этой странице создают сайт
        затем в приложения заливают файлы и скрипты
        а настройки сайта у меня были «недоступно никому» только автору сайта
        Когда сделала открытый доступ для всех в интернете, то все скрипты заработали
        Еще раз вам спасибо!

  3. Олег
    28 апреля 2012 г. в 15:49

    Благодарю. Применил.

  4. 19 июня 2012 г. в 12:50

    Спасибо! Я в восторге от этих подсказок. Применил, как дополнение для полей формы.
    Использую атрибут placeholder, чтобы в полях отображалось: «Введите имя», «Введите email» (неохота подписывать это вне поля — слишком много места, перегрузка для взгляда ИМХО). Но он не поддерживается старыми браузерами.
    Так что подсказки в конце поля ввода — отличная подстраховка!
    Где же я был, когда меня не было на Вашем блоге?! :o)

  5. Aleksov
    22 июля 2012 г. в 19:01

    Доброе время суток!
    Подскажите, как установить задержку перед срабатыванием сценария скрипта таким образом, что-бы подсказка появлялась только после удержания курсора над заданным объектом заданный промежуток времени, а если удержание курсора было меньше заданного промежутка времени, скрипт не выполнялся?

    1. 22 июля 2012 г. в 19:24 / ответ на коммент Aleksov

      После этой строки:

      .clearQueue()

      добавьте такую:

      .delay(1000)

      1000 — это 1 секунда.

      1. Aleksov
        22 июля 2012 г. в 19:30 / ответ на коммент Dimox

        Всё-равно появляется. Идея такова, чтобы при кратковременном нахождении курсора над заданным объектом, подсказка не всплывала вообще, а сейчас она это делает просто секундой позже.

        1. 22 июля 2012 г. в 19:42 / ответ на коммент Aleksov

          Точно. Тогда, к сожалению, не знаю, как сделать. Самому было бы очень интересно узнать решение.

        2. 22 июля 2012 г. в 19:48 / ответ на коммент Aleksov

          Нашел решение. Вот весь код скрипта:

          $('span.jQtooltip').each(function() {
          	var title = $(this).attr('title');
          	if (title && title != '') {
          		$(this).attr('title', '').append('<div>' + title + '</div>');
          		var width = $(this).find('div').width();
          		var height = $(this).find('div').height();
          		$(this).hover(
          			function() {
          				$(this).find('div')
          					.clearQueue()
          					.delay(1000)
          					.animate({width: width + 20, height: height + 20}, 200).show(200)
          					.animate({width: width, height: height}, 200);
          			},
          			function() {
          				$(this).find('div')
          					.animate({width: width + 20, height: height + 20}, 150)
          					.animate({width: 'hide', height: 'hide'}, 150);
          			}
          		).mouseleave(function() {
          			if ($(this).children().is(':hidden')) $(this).find('div').clearQueue();
          		});
          	}
          })
          
          1. Aleksov
            22 июля 2012 г. в 19:51 / ответ на коммент Dimox

            Большое спасибо! Это реально облегчило мне жизнь!

            1. 22 июля 2012 г. в 19:56 / ответ на коммент Aleksov

              Отлично, пожалуйста!

              1. Aleksov
                23 июля 2012 г. в 22:52 / ответ на коммент Dimox

                Ещё один вопрос, пробовал $(‘title’).each(function() тобиш ловить всё что содержит title=»» однако такой фокус не проходит, как поступить правильно?

                1. 24 июля 2012 г. в 10:53 / ответ на коммент Aleksov

                  Вот так правильно:

                  $('*[title]').each(function() {
                  	
                  });
                  
                  1. Aleksov
                    2 августа 2012 г. в 17:47 / ответ на коммент Dimox

                    Доброе время суток!
                    попробовал

                    $('*[title]')

                    -получилось что все тултипы одновременно и постоянно открыты, стоит навести на них курсор, они прячутся. Как пофиксить?

                    1. 2 августа 2012 г. в 20:27 / ответ на коммент Aleksov

                      Не видя живого примера, ничего не могу сказать.

                      1. Aleksov
                        2 августа 2012 г. в 23:17 / ответ на коммент Dimox

                        ок! вот http://test.i-stereo.ru «живой» пример.
                        Код:

                        (function($){$(function(){$('*[title]').each(function(){var title=$(this).attr('title');
                        if(title && title !=''){$(this).attr('title','').append('<div id="easyTooltip">'+ title+'</div>');
                        var width=$(this).find('div').width();var height=$(this).find('div').height();$(this).hover(
                        function(){$(this).find('div').clearQueue().delay(3000).animate({width:width+20,height:height+20},200).show(200).animate({width:width,height:height},200)},
                        function(){$(this).find('div').animate({width:width+20,height:height+20},1000).animate({width:'hide',height:'hide'},150)})
                        .mouseleave(function(){if($(this).children().is(':hidden'))$(this).find('div').clearQueue();});}})})})(jQuery)
                      2. Aleksov
                        2 августа 2012 г. в 23:19 / ответ на коммент Dimox

                        вот css:

                        #easyTooltip{padding:5px;border:2px #ffae00 solid;background:#fada5b;border-radius: 5px;-webkit-border-radius: 5px;-moz-border-radius: 5px;color:#000;font:12px Tahoma;filter:alpha(opacity=95);-moz-opacity: 0.95;-khtml-opacity: 0.95;opacity: 0.95;}
                        

                        Большое.. Нет! Огромное спасибо за участие и помощ!

  6. Kox
    29 сентября 2012 г. в 19:38

    А как сделать что бы подсказка чуть быстрее выскакивала ??

    1. 30 сентября 2012 г. в 10:52 / ответ на коммент Kox

      Уменьшите оба числа 200 в строке:

      .animate({width: width + 20, height: height + 20}, 200).show(200)
  7. Firebreather
    21 февраля 2013 г. в 00:16

    Отличная находка! :) Взял себе на вооружение…

    Заметил небольшой баг — если на странице есть скрытые контейнеры (неактивные вкладки, к примеру), в которых есть тултипы, то нормально анимация работает только на активной вкладке при загрузке страницы, а на всех остальных вкладках тултипы половинятся по высоте…

    Вылечилось добавлением минимальной анимационной высоты в CSS-класс: .jQtooltip div

    height: 14px;

    Спасибо большое за скрипт!

    1. Firebreather
      21 февраля 2013 г. в 02:55 / ответ на коммент Firebreather

      Э-э, нет, если в тултипе текста много, тогда высота не увеличивается(( В общем, это неоднозначное решение…

    2. 21 февраля 2013 г. в 11:50 / ответ на коммент Firebreather

      Да, я тоже столкнулся с этим багом. Пока не знаю, как устранить.

  8. Firebreather
    22 февраля 2013 г. в 01:25

    Пока решил сделать разделение по подсказкам — у «мини» они однострочные, а у ссылок — многострочные :)
    Для этого добавил ещё один CSS:

    .jQtooltip.mini div { height: 14px; }

    Так работает без косяков))

  9. Максим
    9 апреля 2013 г. в 15:41

    сейчас всплытие подсказки происходит слева направо, а как сделать наоборот?

    1. 9 апреля 2013 г. в 16:18 / ответ на коммент Максим

      Насколько я знаю, никак.

      1. Максим
        9 апреля 2013 г. в 18:08 / ответ на коммент Dimox

        плохо

  10. Андрей
    21 мая 2013 г. в 15:11

    Вопрос что я делаю не правильно? Решил сделать на вашем примере подсказку для изображений
    В скрипте

    'span.jQtooltip'

    изменил на

    'img.jQtooltip'

    В html пишу

    <img class="jQtooltip" title="asdasdasd"

    Но подсказка не работает. Вопрос что я сделал не так?

    1. Для изображения не сделать, потому что это непарный тег.

  11. alik
    2 октября 2013 г. в 02:14

    когда говоришь добавить в CSS имеешь в виду style.css?? там целая папка css.
    и этот спан куда приклеить тоже в сss???

    1. Спасибо автору за очень полезную статью. Она нужная и достаточно понятная… Скажите, пожалуйста, у Вас есть скайп? Просто мне эти знания очень нужны, но я не имею права на ошибку… Если есть такая возможность, я прошу Вашей помощи онлайн… Еще раз спасибо за знания…

  12. Алексей
    1 января 2014 г. в 17:28

    Здравствуйте. У Вас в скрипте используются class и в табличке стилей соответственно, как поменять class на id? В таблице понятно как а в скипте как?

    1. 1 января 2014 г. в 17:49 / ответ на коммент Алексей

      Вместо span.jQtooltip сделайте #jQtooltip. Но в этом случае скрипт сработает только для первой подсказки на странице.

  13. Алексей
    2 января 2014 г. в 13:55

    Вместо span.jQtooltip сделайте #jQtooltip. Но в этом случае скрипт сработает только для первой подсказки на странице.

    А если сделать span#jQtooltip то всё работает

  14. Владимир
    26 января 2014 г. в 00:41

    Здравствуйте!
    Очередное прекрасное творение. :) Долго искал разные варианты, но Ваш просто отличный. Единственная проблема у меня возникла, похоже не срабатывает .jQtooltip div. Т.е. окно с текстом выглядит явно не таким, как должно быть по описанию в css. Не могу понять, как такое может быть. .jQtooltip { работает, а .jQtooltip div.
    В чем может быть проблема?

    1. 26 января 2014 г. в 10:57 / ответ на коммент Владимир

      Покажите живой пример. Без него можно только гадать.

      1. Владимир
        26 января 2014 г. в 13:47 / ответ на коммент Dimox

        Вот пример: http://www.vseoglazah.ru/eye-diseases/hypermetropia/ Там прямо в начале, к примеру, слово «аккомодации».
        Вчера несколько часов пытался разобраться, но так и не понял. Такое ощущение, что не срабатывает скрипт, т.к. если я его убираю, то ничего не меняется. Проблема в том, что всплывающий текст в div не оборачивается.
        В tips.js поместил Ваш код. В CSS всё добавил, но почему то не работает.
        jQuery подключил:

        <script type="text/javascript" src="http://yandex.st/jquery/1.7.1/jquery.min.js" charset="UTF-8"></script>

        Много вариантов перебрал, Ваш больше всего понравился, но почему то не срабатывает. :(

        1. 26 января 2014 г. в 16:16 / ответ на коммент Владимир

          Неправильно запускаете скрипт, оттого и не работает. Правильно так:

          (function($){
          $(function() {
          
          тут код скрипта
          
          })
          })(jQuery)
          

          Моя ошибка, забыл указать это в статье.

          1. Владимир
            26 января 2014 г. в 17:52 / ответ на коммент Dimox

            Вот же я тормоз :) Спасибо большое! Теперь всё отлично. Спасибо Вам за отличный сайт и Вашу дружелюбность. :)

  15. Владимир
    26 января 2014 г. в 18:21

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

    1. 26 января 2014 г. в 18:25 / ответ на коммент Владимир

      Нужно убрать overflow: hidden; у родительского div’а, тогда не будет обрезаться. Смещать влево я не знаю, как.

  16. Александр
    21 марта 2014 г. в 02:20

    Здравствуйте, скажите пожалуйста как заменить вопросительный знак на восклицательный или какой-то другой или вообще убрать его? Просто я реализовал такие подсказки для выведения тайтлов из ссылок и вопросительный знак там ни к чему, помогите пожалуйста, обыскал весь код скрипта и интернет, не нашел ничего такого и не могу понять как поменять или убрать… Примерно думаю что это с el.find как то связано… Помогите пожалуйста!

    1. Не знаю, где вы там нашли вопросительный знак, его нет ни в статье, ни в примере.

      1. Александр
        21 марта 2014 г. в 10:41 / ответ на коммент Dimox

        С вопросительным знаком становится указатель мыши при наведении, можно ли убрать эту замену курсора или поменять на обычный или лучше вид курсора как при наведении на ссылку? Буду очень благодарен если поможете! Вчера весь интернет перерыл, но так и не нашел как это сделать…

        1. Нужно было сразу сказать, что речь про курсор. Удалите из стилей эту строчку:

          cursor: help;
          1. Александр
            21 марта 2014 г. в 10:54 / ответ на коммент Dimox

            Спасибо большое и за скрипт и за помощь!!! Все отлично работает! Почему то в ксс и не смотрел(тормоз =)), думал что это в коде скрипта… Еще раз спасибо!

  17. Михаил
    16 мая 2014 г. в 14:48

    Здравствуйте! Что то мучаюсь который час, никак не добьюсь результата. Сильно не пинайте за код, я всего лишь «любитель», и делаю для себя…
    В общем, вот часть кода —

    <table style="margin-bottom:3px;" width="597px" class="table2" >
    <tbody>
    <tr onclick="show(1,18);">
    
    <td style="color:#036; background-color:#e4edfc;" colspan="2">1. Заголовок</td>
    
    </tr>
    <tr id="id1" style="display:none">
    <td><span class="jQtooltip" title="Вспывающая подсказка, описание и т.д.</span></td>
    <td>еще одна ячейка</td>
    </tr>
    <tr id="id2" style="display:none">
    td><span class="jQtooltip" title="Вспывающая подсказка, описание и т.д.</span></td>
    <td>еще одна ячейка</td>
    </tr>
    ...........
    

    Таблица на основе этого скрипта — http://neverlex.com/cat/programming/price-list-with-javascript/
    Проблема. При наведении курсора, .jQtooltip div срабатывает вниз, в небольшом по высоте блоке, а текст соответственно сползает далеко за пределы дива по высоте.
    Склоняюсь к мысли, что что то конфликтует..

    1. Михаил
      16 мая 2014 г. в 15:09 / ответ на коммент Михаил

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

      <table style="margin-bottom:3px;" width="597px" class="table2" >  
      <tbody>  
      <tr onclick="show(1,18);">  
        
      <td style="color:#036; background-color:#e4edfc;" colspan="2">1. Заголовок</td>  
        
      </tr>  
      <tr id="id1" style="display:none">  
      <td><span class="jQtooltip" title="Вспывающая подсказка, описание и т.д."</span>Текст</td>  
      <td>еще одна ячейка</td>  
      </tr>  
      <tr id="id2" style="display:none">  
      td><span class="jQtooltip" title="Вспывающая подсказка, описание и т.д."</span>Текст</td>  
      <td>еще одна ячейка</td>  
      </tr>  
      ...........  
      1. Покажите лучше живой пример. Этот код мне ни о чем не говорит.

        1. Михаил
          16 мая 2014 г. в 18:46 / ответ на коммент Dimox

          Тестовый пример, в прайсе первый раздел, и первый подпункт с применением подсказки http://fr54382.tw1.ru/price.html Проблему нашел..
          Проблема с высотой у .jQtooltip div, если проставлять в пикселях — открывает, но пиксели под каждый объем текста не просчитаешь. Так же если отменить у строки с идентификатором id1 свойство display:none; — элемент подсказки работает как надо, но не скрывается строка.

          1. Вот в том и дело, что корректно будет работать, только если подсказка находится не в скрытом элементе.

            1. Михаил
              16 мая 2014 г. в 20:11 / ответ на коммент Dimox

              Сейчас прочитал на 2 странице комментарии — оказывается я не первый кто с этим столкнулся. Жаль. Хм.. т.е. получается строка наследует все свойства на вложенные элементы, этим самым вызывая этот баг?

              1. Суть в том, что для div’а со подсказкой, перед тем, как он отобразиться, определяется его высота. Но, когда элемент с подсказкой находится в элементе, у которого свойство display: none, в этом случае у div’а со подсказкой высота определяется неправильно, из-за чего и возникает такой баг.

              2. Alex
                30 января 2017 г. в 20:25 / ответ на коммент Михаил

                предлагаю вынести див в body и рассчитывать смещение top по высоте текущего элемента.

  18. atatat
    2 мая 2016 г. в 15:56

    Не срабатывает для элементов, которые были добавлены позже. Например по клику.

    1. atatat
      2 мая 2016 г. в 16:03 / ответ на коммент atatat

      Предлагаю, как-то так

      $(document).on({
              mouseenter: function () {
                $(this).find('div')
                  .clearQueue()
                  .delay(200)
                  .animate({width: width + 20, height: height + 20}, 200).show(200)
                  .animate({width: width, height: height}, 200);
              },
              mouseleave: function () {
                $(this).find('div')
                  .animate({width: width + 20, height: height + 20}, 150)
                  .animate({width: 'hide', height: 'hide'}, 150);
                  if ($(this).children().is(':hidden')) el.find('div').clearQueue();
              }
            }, ".tooltip");
  19. 26 июня 2017 г. в 15:49

    Может быть, кому-то и не нравятся подсказки как всплывающие окна, но всё же меня они прельщают тем, что информация бывает полезной. Иногда смотришь, но не находишь в нужном месте искомое, а тут вылетает подсказка, на которую невольно обращаешь внимание, и понимаешь, что там то, что надо. Поэтому не стоит их игнорировать, лучше их воплощать в реальность.

  20. Rem
    2 декабря 2017 г. в 04:07

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

Ваш комментарий

Жирный текст

Ссылка

Цитата

Внутристрочный код

CSS-код

HTML-код

JavaScript-код

PHP-код