Универсальная всплывающая подсказка на CSS и jQuery

Оригинальные светильники на траве в темном садуПро всплывающие подсказки написано много, еще больше их создано. Сегодня с помощью CSS и JavaScript можно не только изменить стандартный вид подсказок на свой вкус, придать им различные эффекты, но и дополнительно разместить больший объем информации, необходимой пользователю сайта или блога. Ведь для веб-мастера, всплывающая подсказка давно уже не просто появляющийся текст-пояснение, а красиво оформленный, дополнительный контент, который может включать в себя изображения, ссылки и видеоролики.
  И я, в очередной раз не оставил эту тему без внимания. Изначально я хотел просто обновить ранее написанную статью, в которой выложил пример создания простой подсказки с использованием jQuery, но после внедрения улучшений, у меня получилась более дополненная и универсальная подсказка, которая заслужила на отдельный материал.
  Итак, с учетом всех ранее изложенных пожеланий к предыдущей статье, данная версия всплывающей подсказки обладает более универсальными свойствами:
  - функционал подсказки не требует дополнительных плагинов, только jQuery-скрипт;
  - внешний вид, как и прежде, задается через CSS;
  - текст может быть взят из title или дополнительного блока;
  - внутри подсказки можно расположить, кроме текста, также ссылки и изображения;
  - в окне подсказки можно выделить, скопировать текст или перейти по расположенной в нем ссылке - оно не скроется пока курсор находится на нем;
  - подсказки обладают неограниченным уровнем вложенности, т.е. можно создавать подсказку в подсказке в неограниченном количестве;
  - клик-подсказку можно закрыть при клике на любую область сайта, по самому элементу-триггеру или нажатием на кнопку закрытия(крестик).


DEMO
  Как показано на ДЕМО-странице, доступно два типа подсказок - появляющиеся при наведении курсора и по клику на элемент. Относительно кодов - некоторые важные моменты изложены ниже, а архив с исходниками вы как всегда можете скачать по прямой ссылке в конце статьи.

HTML структура

  HTML-структура простая и мало чем отличается от ранней версии, в некотором смысле даже проще, благодаря CSS и работе скрипта. Вариантов реализации, как всегда несколько:

Появление при наведении

1. Простой. При отсутствии дополнительно созданных элементов, текст подсказки будет взят из имеющегося описания в теге TITLE, при этом вид стандартной подсказки изменится на тот, который задан с помощью CSS, а стандартная подсказка, отображаемая браузером по умолчанию, видна не будет:
<a class="hovertip" href="#" title="Текст подсказки">SomeLink</a>
.hovertip - универсальный класс для создания всплывающей подсказки при наведении курсора на элемент, его можно присвоить как ссылке, так и любому блочному элементу;
Чтобы придать слову с подсказкой особый вид и выделить его из общего текста можно заключить его в тег <B>, присвоив ему один из имеющихся классов:
.hoverbuttontip - вид кнопки,
.hoverwikitip - вид Вики подсказки с счетчиком;
<div class='hovertip' title="Текст подсказки">
<b class='hoverbuttontip'>HoverButtonTip</b>
</div>
2. Сложный. Блок с подсказкой располагается непосредственно после вызывающего элемента:
<a class="hovertip" href="#" title="Стандартное описание">SomeLink</a>
<span class='tipbubble'><!--Текст отображаемой подсказки--></span>
.tipbubble - универсальный класс для создания элемента с текстом или другими элементами подсказки.
- если блок с этим классом располагается непосредственно после элемента с классом .hovertip, то содержимое подсказки для .hovertip будет взято из блока .tipbubble, при этом описание из тега TITLE будет игнорироваться и стандартная подсказка отображаться не будет.

Появление по клику

Если блок .tipbubble расположен самостоятельно, то будет создана клик-подсказка, т.е. скрипт автоматически создаст элемент вызывающий подсказку - он будет иметь вид кнопки(кружочка) со знаком вопроса внутри, а в словесном пузыре будут показаны текст и другие элементы из блока с классом .tipbubble:
<span class='tipbubble'>
<!--Текст и другие элементы подсказки-->
</span>
Чтобы изменить вид кнопки, в блок .tipbubble можно самостоятельно добавить тег <EM>, и вписать любое слово, которое заменит знак вопроса в кнопке.
Чтобы изменить вид этого элемента, к тегу <EM> можно добавить дополнительный класс, стили для которых уже прописаны в CSS файле:
.wikitip - вид Вики-подсказки с счетчиком;
<span class='tipbubble'>
<em class='wikitip'>WikiTip<;/em>
<!--Текст и другие элементы подсказки-->
</span>

Дизайн и описание CSS

  Выкладывать код CSS в статье не буду, все в полном объеме есть в архиве с исходниками, замечу только что он очень прост и разделен на две части. Первая определяет положение и доступный функционал окна подсказки, а также ее элементов, вторая - отвечает за оформление. В исходнике подсказка представлена в двух вариантах дизайна - темном и светлом.
  В архиве находятся 4 файла CSS:
  - UniversalToolTipFull.css - полный стиль;
  - UniversalToolTip-Position.css - часть с описанием свойств положения подсказки (первая часть);
- части с описанием дизайна:
  - UtoolTipDising-dark.css - темный;
  - UtoolTipDising-light.css - светлый;
  Часть отвечающая за оформление расположена после пометки
/*Dising*/

Скрипт jQuery

  Скрипт получился чуть больше прежнего варианта, так как добавился некоторый необходимый функционал к отображению подсказки при наведении курсора и скрытию по клику, о чем написано в начале статьи. Функция вычисления положения и показа подсказки практически осталась без изменений. Подсказка как и прежде будет показана только на видимой части экрана.
$(function(){
 $('.tipbubble')
  .wrap('<div class="tip" />'); //обернем блок с подсказкой в дополнительную оболочку

 $('.tip').each(function(){
  var TIPBLOCK = $(this),
   TIPBUBBLE = TIPBLOCK.find('>.tipbubble'), //переменная блока подсказки
   EXCLUDE = TIPBLOCK.prev().hasClass('hovertip'), //переменная элемента определяющего тип показа подсказки (по клику или наведению)
   TIPTRIGGER = TIPBLOCK.find('em'); //переменная элементе вызывающего подсказку

  //проверяем существует ли элемент вызова подсказки
  //в случаи отсутствия дабавим его автоматически

  TIPBLOCK
   .before(function(){
   if (EXCLUDE){
    return '';
   }
   else if ( TIPTRIGGER.length != 0 ){
    return TIPTRIGGER.addClass('qtip');
   }else{
    return '<em class="qtip">?</em>';
   }
  })
  .prev('.qtip')
  .click(showTip);

  //добавим кнопку закрытия подсказки - крестик
  TIPBUBBLE
   .append(function(){
   if (!EXCLUDE){
    return '<b class="close">X</b>';
   }else{
    return '';
   }
  })
  .on('click', ".close", function(){
    $(this)
    .parent('.tipbubble')
    .fadeOut(100)
    .queue(function(next){
      $(this)
      .removeClass('left-tip-pos right-tip-pos upper-pos')
      next();
    });
  })
  .click(function(e){
    e.stopPropagation();
  });
});

 $('.hovertip').each(function(){
   var HOVERTRIG = $(this),
  TITLE = HOVERTRIG.attr('title'), //извлечем текст из тега title
  TXT = HOVEiTRIG.next('.tip'); //определим блок с подсказкой, следующий за вызывающим элементом блок

  //убираем стандартную подсказку
  //проводим проверку на наличие блока подсказки
  //если такого нет, то добавляем автоматически с тiстом из тега title

  HOVERTRIG
  .removeAttr("title")
  .after(function(){
   if (TXT.length != 0 ){
    return '';
   }else{
    return '<div class="tip"><span class="tipbubble">' + TITLE + '</span></div>';
   }
  })
  .hover(
    showTip,
   function(){
    $(this)
    .next()
    .find('>.tipbubble')
    .delay(500)
    .fadeOut(100);
  })
  .next()
  .find('>.tipbubble')
  .hover(
   function(){
    $(this)
    .stop(true)
    .fadeIn(100);
  },
   function(){
    $(this)
    .stop()
    .delay(500)
    .fadeOut(100)
   })
   .click(function(e){
    e.stopPropagation();
   });
 });
 //скрытие подсказки, кликом на любую область сайта
 $('html,body').click(function(){
   $('.tipbubble')
    .hide()
    .removeClass('left-tip-pos right-tip-pos upper-pos');
 });

 //функция определения положения подсказки,
 //чтобы она всегда находилась на видимой части сайта,

 function showTip(e){
    var PIP = $(this),
    TIP = $(this).next().find('>.tipbubble'),
    TipW = TIP.outerWidth(),
    TipH = TIP.outerHeight(),
    PipW = PIP.outerWidth(),
    PipH = PIP.outerHeight(),
    CurW = $(this).offset().left - $(window).scrollLeft()
    CurH = $(this).offset().top - $(window).scrollTop(),
    LastCoord = $(window).width() - CurW - PipW;

  if (LastCoord >= TipW+20){
    TIP.removeClass('left-tip-pos').addClass('right-tip-pos').css({ right : -PipW });
  } else {
    TIP.removeClass('right-tip-pos').addClass('left-tip-pos').css({ right : PipW });
  }
  if (CurH > TipH+20){
    TIP.addClass('upper-pos');
  } else {
    TIP.removeClass('upper-pos');
  }
    TIP.stop(true).fadeToggle(100);
  e.stopPropagation();
 }
});

  Перед добавлением скрипта не забываем подключить к сайту библиотеку jQuery.
  На этом пожалуй все, архив с исходными кодами данной всплывающей подсказки можно скачать здесь:
СКАЧАТЬ ZIP
  Комментарии и конструктивная критика приветствуется.

©http://magentawave.com

12 комментариев:

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

    ОтветитьУдалить
    Ответы
    1. А вот с этого места по подробнее, только если можно не в этом посте. Лучше здесь -
      http://www.magentawave.com/2012/04/how-make-money-with-blogger.html думаю будет в тему...
      Может дело не в Blogger? Он в таком ранее не замечен.

      Удалить
  2. Большое Вам спасибо за этот скрипт. Я никак не могла найти всплывающих подсказок, где можно было бы добавить ссылку внутрь. Ваш способ сработал, ура!!!

    ОтветитьУдалить
    Ответы
    1. Пожалуйста, рад что разработка пригодилась.

      Удалить
  3. Анонимный14.08.2016, 18:28

    Добрый день!

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

    ОтветитьУдалить
    Ответы
    1. Да, так можно сделать, в ближайшее время постараюсь доработать скрипт и добавить эту функцию, давно уже думал об этом. Спасибо что оценили)

      Удалить
  4. Анонимный05.03.2017, 22:04

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

    ОтветитьУдалить
    Ответы
    1. Как понять "сверху"? Опишите что нужно подробнее, пожалуйста.

      Удалить
  5. Все замечательно, но почему в архиве нет ссылки на эту страницу????

    ОтветитьУдалить
    Ответы
    1. Значит она там не нужна, в карте (меню слева) ссылка сюда есть и этого достаточно.

      Удалить
  6. А можно ли вызывать подсказку из другого javascript страницы?

    ОтветитьУдалить
    Ответы
    1. Не совсем понятно что именно вы имеете в виду. А можно уточнить данный вопрос?

      Удалить

Следующее Предыдущее

BestProject