Как динамически менять favicon и title на сайте?

Ребята, у меня крутая новость – по факту новость не новость, но можно делать свои сайты более интерактивными за счет favicon. Да-да я предлагаю менять иконку или обновлять в зависимости событий на сайте.

К сожалению, к своему блогу я эту штуку применять не хочу, да и нет событий, при которых можно было бы такое провернуть (пока что), но я расскажу и покажу как это работает в примерах с кодом и на отдельных страницах – интересно? тогда читай дальше!

Чаще всего вебсайты, а особенно веб-приложения с часто обновляемым контентом просто обязаны найти какой-то хороший способ, который привлечет внимание пользователей.

Представим такую картинку – на сайте есть к примеру чат и вот пришло сообщение. Да, оно отобразится, но можно в этот момент заменить иконку на другую, которая покажет пользователю что что-то изменилось на сайте.

Отличный пример работы с иконками реализован на сайте trello – кто не знает, что это, рекомендую разобраться в этом сервисе.

Trello динамическая иконка

Так же мне очень нравится, когда к примеру, в Facebook появляется что-то новенькое, они сразу же дают об этом знать за счет количества новенького в уведомлениях. Раньше я этого не замечал, но вот как заметил появилось желание реализовать такое динамическое изменение favicon и title на сайте.

Но мы это сделаем по очереди.

Меняем динамически заголовок title

В общем я подумал нужно действовать, и исходя с того как это делается в Angular, а именно настройка title там реализуется вообще максимально просто, я сейчас приведу код, который меняет title также как это делается в Facebook или Twitter.

Динамический заголовок FaceBook

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

Вот код:

let count = 0;
let title = document.title; // получаем заголовок (глобально)

function changeTitle() { // делаем простенькую функцию которая будет менять заголовок
  count++; // каждый цикл увеличиваем цифру которую выводим
  if(count >= 20) { // чтобы цифра не была слишком большой делаем проверку (как на Facebook)
   let newTitle = '(20+) ' + title;
   document.title = newTitle; // применяем заголовок
  } else {
   let newTitle = '(' + count + ') ' + title;
   document.title = newTitle;
  }
}
  function newUpdate() {
update = setInterval(changeTitle, 1000); // c этой функцией апдейтим каждую секунду title (может служить как проверка)
  }
  
  let docBody  = document.getElementsByTagName('body')[0];
  docBody.onload = newUpdate;

И вот это весь код, круто ведь? Реально если сильно заморочиться можно уменьшить код до нескольких строк, но, если есть в этом какой-то смысл. А вот и сам пример который можно покликать и увидеть, как это работает наглядно.

Делаем динамический favicon

Правда тут уже как в trello можно применять хоть 10 разных иконок при разных ситуациях, но меня интересует пока только два варианта, это стандарт ну и, если вдруг что-то пришло или поменялось на сайте.

Все остальное можно доделать по желанию, и я покажу как:

let iconNew = '../assets/img/favicon-dot.gif'; // иконка на которую будем менять свою стандартную иконку

function changeFavicon() {
   document.getElementById('favicon').href = iconNew; // применяем свою новую на сайт
}

function newUpdate() { // с этой функцией мы обновим ее через три секунды на сайте
   update = setInterval(changeFavicon, 3000);
   setTimeout(function( ) { clearInterval( update ); }, 3100);
}

var docBody  = document.getElementsByTagName('body')[0];
docBody.onload = newUpdate; // инициализация всего после загрузки body

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

Вставляем цифры в Favicon (динамический Favicon c цифрами)

Вот этот вариант отображения у меня засел изначально в голове, причем я цель была реализовать на чистом JavaScript, но первые мои личные попытки завершались неудачей. Потому я решил найти что-то готовое и нашел favico.js от некого Miroslav Magda.

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

Там в той ссылочке ты найдешь всю документацию, которая прилагается к библиотеке. В общем давай смотреть код, что у меня получилось:

let favicon = new Favico({
       position  :'down', // выведем все в нижней части иконки
       animation :'popFade', // плавное появление
       bgColor   :'#dd2c00', // красный бекграунд
       textColor :'#fff0e2' // светлый текст
});

let num = 0; // глобально определяем цифру
function generateNum() {
   return num++; // плюсуем каждый раз плюсуем 1
}

function showFaviconBadge() {
    let num = generateNum();  // берем сгенерированную цифру
    favicon.badge(num); // вставляем его в нашу библиотечную функцию
}

function newUpdate() {
    update = setInterval(showFaviconBadge, 2000); // обновляем каждые 2 секунды
}

let docBody  = document.getElementsByTagName('body')[0];
docBody.onload = newUpdate; // запускаем при инициализации

Вот пример, в котором можно посмотреть, как это работает, а я вот еще раз скажу, что мне очень понравилась библиотека.

Работает она по следующему принципу:

  1. Берет наш favicon который у нас установлен на сайте;
  2. Дорисовует через canvas то что мы хотим отобразить;
  3. Конвертирует в base64
  4. И выводит на сайте

В целом это максимально просто, причем я так заметил, чтобы реализовать анимацию эта библиотека генерирует несколько картинок, а после по очереди вставляет в нашу favicon. Получается такой эффект анимации.

После чего я решил немного схитрить, и просто глянул как работает код favico.js – не забывая про свою цель написать что-то похожее на JavaScript без библиотек я все-таки реализовал то что хотел, пусть вышло не так идеально, как это сделано с помощью библиотеки, но получилось вполне не плохо учитывая, что потратил на это я примерно 2-2.5 часа.

Пишем динамический Favicon собственноручно на JavaScript

Для создания такой вещи нужно использовать canvas. Canvas – позволяет создавать двухмерные изображения при помощи скриптов и обычно это на JavaScript.

Следующее что нужно понимать при работе с canvas:

  • Все картинки начинаются с лева с верху, дальше двигаемся в право и вниз, тем самым ставим туда изображение куда нам нужно.
  • Он же используется в WebGL – а значит можно писать всякие крутые анимации и даже игры.
  • Если нужно работать с графикой на JavaScript, то это всегда к canvas.

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

 function plus() {
    let span = document.getElementById('number'); // находим цифру
    number = parseInt(span.textContent); // изначально она в string потому конвертируем в int
    number = number + 1; // добавляем 1
    span.innerHTML = number; // вставляем обратно
}


function apply() {
    let canvas = document.createElement("canvas"); // создаем canvas елемент
    let context = canvas.getContext("2d"); // получаем контекст холста (canvas)
    let image = document.createElement('img'); // создаем тег img
    image.src = document.querySelectorAll( 'link[rel="icon"], link[rel="shortcut icon"]' )[0].href; // получаем текущую фавиконку
    let mark = document.querySelectorAll( "span" ); // получаем ту цифру которую будем вставлять в favicon
    image.onload = function(){
        canvas.height = 16; // задаем размеры холста
        canvas.width = 16;
        context = canvas.getContext('2d');
        context.drawImage(image, 0, 0); // вставляем нашу иконку в канвас
        context.fillStyle = "red"; // задаем цвет
        context.beginPath();
        context.arc(12,12,4,0, Math.PI * 2); // рисуем кружочек и ставим туда где хотим его видеть
        context.fill();

        context.font = '8px Arial'; // определяем стили текста и задаем его позицию
        context.textAlign = "center";
        context.textBaseline = "middle";
        context.fillStyle = "#FFFFFF";
        context.fillText(mark[0].innerHTML,12, 13); // вставляем его в картинку

        let oldicons = document.querySelectorAll( 'link[rel="icon"], link[rel="shortcut icon"]' ); // удаляем все favicon на странице
        for(let i = 0; i < oldicons.length; i++) {
            oldicons[i].parentNode.removeChild( oldicons[i] );
        }

        let newicon = document.createElement( "link" ); // вставляем новый favicon
        newicon.setAttribute( "rel", "icon" );
        newicon.setAttribute( "href", canvas.toDataURL('image/png'));
        document.querySelector( "head" ).appendChild( newicon );
    };
}

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

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

Раз в неделю мы отправляем дайджест с самыми популярными статьями.

Оставьте комментарий