Okładka artykułu Tworzymy własny komunikat o wykorzystaniu plików cookies — Dostosowujemy stronę do europejskiego ustawodastwa
Poradniki

Tworzymy własny komunikat o wykorzystaniu plików cookies

Dostosowujemy stronę do europejskiego ustawodastwa

Zdjęcie autora Hubert Tulibacki
0

21. marca tego roku, na właścicieli witryn internetowych nałożony został nowy obowiązek. Chodzi o informowanie użytkowników, że na witrynie wykorzystywane są pliki cookies. Informacja ta musi zostać przekazana w sposób jednoznaczny, łatwy i zrozumiały, co wedle wielu opinii wyklucza dodanie odpowiedniej informacji w stopce strony (bardzo łatwo mogłaby przemknąć niezauważona).

Stworzymy więc własny komunikat, który będzie można łatwo wdrożyć na każdej stronie, a także dostosować do jej obecnego wyglądu.

Jednym z moich głównych założeń było to, aby kod był niezależny od jakiegokolwiek frameworka Java Script, a także nie nadpisywał żadnej z wcześniej utworzonych zmiennych. Zaczniemy więc od utworzenia kontenera dla naszego komunikatu, a także przycisku, którym będziemy ten kontener zamykać. Całość umieszczamy w samo-wykonującej się funkcji (aby nie tworzyć nowych zmiennych globalnych). Całość umieszczamy albo w osobnym pliku .js, którym linkujemy w dokumencie zaraz przed zamknięciem znacznika <body>, albo umieszczamy w tym samym miejscu wewnątrz tagu <script>.

(function() {
    var container = document.createElement('div'),
        link = document.createElement('a');

    return true;
})();

Kolejnym krokiem jest dodanie atrybutów: id, aby łatwo nam było wskazać ten element w arkuszu stylów oraz class w odpowiedzi na apel do administratorów stron WWW, aby umożliwić łatwe blokowanie tego komunikatu przez świadomych użytkowników. Dodajemy też treść samego komunikatu. Na końcu osadzamy kontener zaraz przed zamknięciem elementu <body>.

(function() {
    var container = document.createElement('div'),
        link = document.createElement('a');

    container.setAttribute('id', 'cookieinfo');
    container.setAttribute('class', 'cookie-alert');
    container.innerHTML = '<h6>Ta strona wykorzystuje pliki cookie</h6><p>Używamy informacji zapisanych za pomocą plików cookies w celu zapewnienia maksymalnej wygody w korzystaniu z naszego serwisu. Mogą też korzystać z nich współpracujące z nami firmy badawcze oraz reklamowe. Jeżeli wyrażasz zgodę na zapisywanie informacji zawartej w cookies kliknij na &bdquo;x&rdquo; w prawym górnym rogu tej informacji. Jeśli nie wyrażasz zgody, ustawienia dotyczące plików cookies możesz zmienić w swojej przeglądarce.</p>';

    document.body.appendChild(container);

    return true;
})();

Teraz, kiedy skrypt dodaje nam kod HTML do dokumentu, możemy nadać mu odpowiedni wygląd. Każdy może zrobić to wedle swojego uznania. Ja zdecydowałem się na umieszczenie komunikatu na dole ekranu, przylegle do dolnej krawędzi okna przeglądarki, ale można zrobić to też na przykład na górze dokumentu.

#cookieinfo * {
    margin: 0px;
    padding: 0px;
}

#cookieinfo {
    position: fixed;
    font-size: 12px;
    font-family: Arial, Verdana, sans-serif;
    left: 0px;
    bottom: 0px;
    right: 0px;
    background-color: #323334;
    padding: 20px;
    box-shadow: 0px -1px 3px rgba(0, 0, 0, 0.5);
    z-index: 1000;
}

#cookieinfo h6 {
    font-size: 16px;
    font-weight: bold;
    color: #cdd7da;
    text-shadow: 0px 1px 1px rgba(0, 0, 0, 1);
    margin-bottom: 7px;
}

#cookieinfo p {
    font-size: 12px;
    color: #afb4bc;
    line-height: 1.5em;
    text-shadow: 0px 1px 1px rgba(0, 0, 0, 1);
}

#cookieinfo a {
    display: block;
    position: absolute;
    right: 10px;
    top: 10px;
    width: 22px;
    height: 22px;
    border-radius: 11px;
    line-height: 22px;
    font-size: 12px;
    color: #ffffff;
    text-align: center;
    text-decoration: none;
    background-color: #ff6000;
    box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.75);
}

#cookieinfo a:hover {
    background-color: #ff7925;
}

Postanowiłem zresetować marginesy wszystkich elementów znajdujących się wewnątrz #cookieinfo, ponieważ nie chciałem, aby kod ze strony miał na nie jakikolwiek wpływ. Teraz możemy przyjść do tworzenia przycisku zamykającego komunikat. Odpowiedni styl w regułach CSS już napisałem. Przycisk o wyglądzie białego znaku „x” wewnątrz czerwonego koła, będzie znajdował się w prawym górnym rogu komunikatu. Pora go stworzyć i umieścić wewnątrz kontenera.

link.setAttribute('href', '#');
link.setAttribute('title', 'Zamknij');
link.innerHTML = 'x';

container.appendChild(link);

Teraz, gdy mamy już stworzony przycisk, musimy sprawić, by po jego kliknięciu, okienko zamykało się. Tworzymy do tego celu funkcję, która wykona się. gdy użytkownik będzie chciał zamknąć okno, a następnie przypisujemy ją do przycisku.

function clickHandler(e) {
    if (e.preventDefault) {
        e.preventDefault();
    } else {
        e.returnValue = false;
    }

    document.body.removeChild(container);
}

if (link.addEventListener) {
    link.addEventListener('click', clickHandler);
} else {
    link.attachEvent('onclick', clickHandler);
}

Instrukcja warunkowa, zarówno ta wewnątrz funkcji jak i poza nią niezbędna jest do obsługi Internet Explorera starszego niż 9, który nie obsługuje metod preventDefault oraz addEventListener. Pierwsza z nich służy do anulowania domyślnego zdarzenia (w przypadku odnośników jest to po prostu przejście pod adres wskazany w atrybucie href), a druga ma za zadanie przypisania zdarzenia do elementu. My po kliknięciu chcemy po prostu usunąć komunikat, stąd instrukcja document.body.removeChild(container);.

Gotowy działający kod powinien wyglądać tak:

(function() {
    var container = document.createElement('div'),
        link = document.createElement('a');

    container.setAttribute('id', 'cookieinfo');
    container.setAttribute('class', 'cookie-alert');
    container.innerHTML = '<h6>Ta strona wykorzystuje pliki cookie</h6><p>Używamy informacji zapisanych za pomocą plików cookies w celu zapewnienia maksymalnej wygody w korzystaniu z naszego serwisu. Mogą też korzystać z nich współpracujące z nami firmy badawcze oraz reklamowe. Jeżeli wyrażasz zgodę na zapisywanie informacji zawartej w cookies kliknij na &bdquo;x&rdquo; w prawym górnym rogu tej informacji. Jeśli nie wyrażasz zgody, ustawienia dotyczące plików cookies możesz zmienić w swojej przeglądarce.</p>';

    link.setAttribute('href', '#');
    link.setAttribute('title', 'Zamknij');
    link.innerHTML = 'x';

    function clickHandler(e) {
        if (e.preventDefault) {
            e.preventDefault();
        } else {
            e.returnValue = false;
        }

        document.body.removeChild(container);
    }

    if (link.addEventListener) {
        link.addEventListener('click', clickHandler);
    } else {
        link.attachEvent('onclick', clickHandler);
    }

    container.appendChild(link);
    document.body.appendChild(container);

    return true;
})();

Niech wiadomość wyświetla się tylko raz

Ponieważ wyświetlanie tego komunikatu odwiedzającego za każdym razem, byłoby dla niego zbyt uciążliwie, będziemy wyświetlać go tylko po pierwszym wejściu na stronę. Aby ustalić, czy użytkownikowi komunikat został już wyświetlony, użyjemy plików cookies. JavaScript posiada obsługę tych plików, ale nie ma żadnego eleganckiego API do zarządzania nimi. Stąd, zawsze korzystam z malutkiej biblioteki o nazwie Cookie Monster, która nam to API tworzy. Teraz jedyne co musimy zrobić, to sprawdzić, czy „ciastko” zostało już utworzone. Jeśli tak się stało – kończymy działanie funkcji. W przeciwnym wypadku, wykonujemy ją, a na samym końcu ustawiamy cookie.

(function() {
    //copyright JGA 2013 under MIT License
    var monster={set:function(e,t,n,r){var i=new Date,s="",o=typeof t,u="";r=r||"/",n&&(i.setTime(i.getTime()+n*24*60*60*1e3),s="; expires="+i.toGMTString());if(o==="object"&&o!=="undefined"){if(!("JSON"in window))throw"Bummer, your browser doesn't support JSON parsing.";u=JSON.stringify({v:t})}else u=escape(t);document.cookie=e+"="+u+s+"; path="+r},get:function(e){var t=e+"=",n=document.cookie.split(";"),r="",i="",s={};for(var o=0;o<n.length;o++){var u=n[o];while(u.charAt(0)==" ")u=u.substring(1,u.length);if(u.indexOf(t)===0){r=u.substring(t.length,u.length),i=r.substring(0,1);if(i=="{"){s=JSON.parse(r);if("v"in s)return s.v}return r=="undefined"?undefined:unescape(r)}}return null},remove:function(e){this.set(e,"",-1)},increment:function(e,t){var n=this.get(e)||0;this.set(e,parseInt(n,10)+1,t)},decrement:function(e,t){var n=this.get(e)||0;this.set(e,parseInt(n,10)-1,t)}};

    if (monster.get('cookieinfo') === 'true') {
        return false;
    }

    var container = document.createElement('div'),
        link = document.createElement('a');

    container.setAttribute('id', 'cookieinfo');
    container.setAttribute('class', 'cookie-alert');
    container.innerHTML = '<h6>Ta strona wykorzystuje pliki cookie</h6><p>Używamy informacji zapisanych za pomocą plików cookies w celu zapewnienia maksymalnej wygody w korzystaniu z naszego serwisu. Mogą też korzystać z nich współpracujące z nami firmy badawcze oraz reklamowe. Jeżeli wyrażasz zgodę na zapisywanie informacji zawartej w cookies kliknij na &bdquo;x&rdquo; w prawym górnym rogu tej informacji. Jeśli nie wyrażasz zgody, ustawienia dotyczące plików cookies możesz zmienić w swojej przeglądarce.</p>';

    link.setAttribute('href', '#');
    link.setAttribute('title', 'Zamknij');
    link.innerHTML = 'x';

    function clickHandler(e) {
        if (e.preventDefault) {
            e.preventDefault();
        } else {
            e.returnValue = false;
        }

        emile('cookieinfo', 'opacity: 0', {duration: 300, after: function() {
            document.body.removeChild(container);
        }});
    }

    if (link.addEventListener) {
        link.addEventListener('click', clickHandler);
    } else {
        link.attachEvent('onclick', clickHandler);
    }

    container.appendChild(link);
    document.body.appendChild(container);

    monster.set('cookieinfo', 'true', 365);

    return true;
})();

Podczas ustawiania ciastka (w metodzie monster.set) podajemy jego nazwę, wartość (którą będziemy potem sprawdzać) oraz liczbę dni, w jakich informacja zachowuje ważność po jej ustawieniu.

Trochę stylu

Na sam koniec mały bonus. Powiedzmy, że nie chcemy, aby nasz komunikat znikał tak nagle. Chcemy, by znikał powoli. Zacznijmy od ustawienia domyślnej wartości opacity na 1, żeby zaznaczyć punkt wyjściowy naszej animacji. Następnie za pomocą interwału, redukujemy wartość opacity do momentu, aż element przestanie być widoczny. Kod ten wstawiamy zamiast linijki document.body.removeChild(container);:

container.setAttribute('style', 'opacity: 1');

var interval = window.setInterval(function() {
    container.style.opacity -= 0.01;

    if (container.style.opacity 

Jak widać, wykonanie animacji polegającej na zmianie na zmianie wartości liczbowej atrybutów CSS, takich jak przeźroczystość, nie jest wcale takie trudne. Jeśli zastanawiacie się, gdzie jest podany czas trwania animacji, to już spieszę z odpowiedzią: w tym wypadku czas trwania animacji obliczamy mnożąc liczbę klatek (w naszym wypadku 100, ponieważ zmniejszamy wartość przeźroczystości o 0.01) razy długość trwania jednej klatki (w naszym wypadku 4 milisekundy, jest to druga wartość przekazana do metody window.setInterval). Jak łatwo policzyć, animacja trwać będzie około 400 milisekund.

Kompletny kod powinien wyglądać następująco:

(function() {
    //copyright JGA 2013 under MIT License
    var monster={set:function(e,t,n,r){var i=new Date,s="",o=typeof t,u="";r=r||"/",n&&(i.setTime(i.getTime()+n*24*60*60*1e3),s="; expires="+i.toGMTString());if(o==="object"&&o!=="undefined"){if(!("JSON"in window))throw"Bummer, your browser doesn't support JSON parsing.";u=JSON.stringify({v:t})}else u=escape(t);document.cookie=e+"="+u+s+"; path="+r},get:function(e){var t=e+"=",n=document.cookie.split(";"),r="",i="",s={};for(var o=0;o<n.length;o++){var u=n[o];while(u.charAt(0)==" ")u=u.substring(1,u.length);if(u.indexOf(t)===0){r=u.substring(t.length,u.length),i=r.substring(0,1);if(i=="{"){s=JSON.parse(r);if("v"in s)return s.v}return r=="undefined"?undefined:unescape(r)}}return null},remove:function(e){this.set(e,"",-1)},increment:function(e,t){var n=this.get(e)||0;this.set(e,parseInt(n,10)+1,t)},decrement:function(e,t){var n=this.get(e)||0;this.set(e,parseInt(n,10)-1,t)}};

    if (monster.get('cookieinfo') === 'true') {
        return false;
    }

    var container = document.createElement('div'),
        link = document.createElement('a');

    container.setAttribute('id', 'cookieinfo');
    container.setAttribute('class', 'cookie-alert');
    container.innerHTML = '<h6>Ta strona wykorzystuje pliki cookie</h6><p>Używamy informacji zapisanych za pomocą plików cookies w celu zapewnienia maksymalnej wygody w korzystaniu z naszego serwisu. Mogą też korzystać z nich współpracujące z nami firmy badawcze oraz reklamowe. Jeżeli wyrażasz zgodę na zapisywanie informacji zawartej w cookies kliknij na &bdquo;x&rdquo; w prawym górnym rogu tej informacji. Jeśli nie wyrażasz zgody, ustawienia dotyczące plików cookies możesz zmienić w swojej przeglądarce.</p>';

    link.setAttribute('href', '#');
    link.setAttribute('title', 'Zamknij');
    link.innerHTML = 'x';

    function clickHandler(e) {
        if (e.preventDefault) {
            e.preventDefault();
        } else {
            e.returnValue = false;
        }

        container.setAttribute('style', 'opacity: 1');

        var interval = window.setInterval(function() {
            container.style.opacity -= 0.01;

            if (container.style.opacity <= 0.02) {
                document.body.removeChild(container);
                window.clearInterval(interval);
            }
        }, 4);
    }

    if (link.addEventListener) {
        link.addEventListener('click', clickHandler);
    } else {
        link.attachEvent('onclick', clickHandler);
    }

    container.appendChild(link);
    document.body.appendChild(container);

    monster.set('cookieinfo', 'true', 365);

    return true;
})();

Na zakończenie

Oczywiście nic nie stoi na przeszkodzie, aby tworzyć własne animacje oraz wygląd komunikatu. Ten mój, ze względu na zastosowanie przeźroczystości w CSS nie za bardzo nadaje się do przeglądarek Internet Explorer starszych, niż wersja 9. Sam kod JavaScript pisany jest za to z myślą o każdej przeglądarce. W treści przekazywanej do container.innerHTML możecie umieścić dowolną informację, w tym kod HTML.

Osobiście uważam, że taki sposób informowania o plikach cookie jest nieco inwazyjny. Ale niestety, póki jakiś sąd albo urząd nie zdefiniuje dokładnie, jak taka informacja ma wyglądać, warto dmuchać na zimne. Miejmy nadzieję, że takie komunikaty wkrótce przestaną być potrzebne.

Pobierz Zobacz demo

Aktualizacja

Skrypt został nieznacznie zmieniony, ponieważ biblioteka Fx używana do animacji, w sposób magiczny postanowiła przestać działać wraz z najnowszą aktualizacją przeglądarki Firefox (dziękuję za informację o tym w komentarzach).

W związku z licznymi prośbami stworzyłem trochę zmodyfikowaną wersję, na stałe znikającą dopiero po kliknięciu w x, a nie po pierwszym wyświetleniu strony. Można ją znaleźć pod tym adresem.

To może Cię zainteresować