Запоминаем положение интерфейса средствами JavaScript

Очень важным моментом в интерфейсе сайта является сохранение его текущего положения, для того, чтобы после перезагрузки страницы, пользователю не пришлось заново повторять свои действия с настройкой интерфейса сайта под себя. Идеальным средством для хранения состояния пользовательского интерфейса является cookies. Всем известно как работать с куки с помощью серверных (backend) языков,  но зачастую проще это делать напрямую из JavaScript. Конечно можно передавать данные интерфейса серверной части, а там уже сохранять их хоть в БД. Но как правило, если вы не разрабатывайте новый интерфейс для gmail, нет необходимости делать это для 5-6 параметров.

JavaScript и Cookies.

В JavaScript есть стандартные методы для работы с document.cookie, именно так происходит обращение к куки в JavaScript. Например функция для установки куки будет выглядеть следующим образом

function setCookie(c_name,value,expiredays)
 {
        var exdate=new Date();
        exdate.setDate(exdate.getDate()+expiredays);
        document.cookie=c_name+ "=" +escape(value)+
        ((expiredays==null) ? "" : ";expires="+exdate.toUTCString());
 }

Как вы видите не очень удобно, поэтому я и предпочитаю пользоваться JQuery плагинами, если конечно фреймворк в проекте уже присутствует, если нет, то подключать JQuery, только из-за работы с куки не рационально.  В принципе взяв готовые функции для document.cookie или написав их самостоятельно, можно свести неудобства и количество кода к минимуму.

Плагины cookies для JQuery.

Если в вашем сайте уже используется JQuery, то наиболее простой способ наладить работу с cookies, это использовать плагин. Плагинов довольно много я обычно использую ezCookie. В плагине содержатся стандартные методы для работы с cookies — установка, чтение, удаление. На странице проекта есть детальное описание всех методов. Плагин ezCookie отличается от многих подобных автоматическим распознаванием значения установленной cookie, и, если это JSON данные, то функция автоматически возвращает JSON объект. Такой режим работы позволяет устанавливать subcookie, то есть множества пар имя:значение для одного cookie (для одной cookie переменной).

Сохранение положения интерфейса.

Давайте напишем небольшой пример, который позволит понять схему сохранения простых позиций интерфейса. Пусть у нас будет 5 разноцветных квадратов, которые по клику на кнопку «закрыть» закрываются, и текст на кнопке меняется на «открыть». И при нажатии на кнопку «открыть» соответственно квадрат снова становится видимым.

Для этого воспользуемся стандартной JQuery функцией toggle (переключатель), которая в качестве аргументов принимает 2 функции, одна из которых срабатывает на четном щелчке мыши, другая на нечетном. Чтобы сохранить положение квадратов, мы в первой toggle функции будем устанавливать значение cookie в 0, а на второй функции в 1, ноль означает, что квадрат скрыт, а единица соответственно, что квадрат виден.

Здесь я использую функцию ezCookie $.setSubCookie, чтобы не увеличивать количество записей cookie. Так как структурно записи для каждого квадрата у нас равны, то все проще хранить в одной cookie с именем «ui_save». В качестве дополнительных параметров метод $.setSubCookie позволяет установить время жизни cookies, но в данном случае используется время жизни по умолчанию.

Итак позицию интерфейса в зависимости от действий пользователя мы записали, теперь нам необходимо сделать так, чтобы после загрузки страницы интерфейс возвращался в записанное состояние. Для этого мы сначала считаем нашу куку функцией $.cookie(«ui_save»), эта функция автоматически определяет какое значение установлено в куке и если это JSON, то она возвращает JSON объект, что в нашем случае и происходит. Далее для каждого квадрата мы проверяем значение и если оно равно нулю то вызываем событие click, которое установит нужное положение квадрата.

	$(document).ready(function(){
		$(".close").toggle(
			function(){
				$(this).prev().slideUp(); //скрываем квадрат
				$(this).html("Открыть");
				var class_name = $(this).prev().attr("class");
//устанавливаем значение куки для конкретного квадрата в положение закрыть
				$.setSubCookie("ui_save", class_name, 0);
			},
			function(){
				$(this).prev().slideDown(); //разворачиваем квадрат
				$(this).html("Закрыть");
				var class_name = $(this).prev().attr("class");
//устанавливаем значение куки для конкретного квадрата в положение открыт
				$.setSubCookie("ui_save", class_name, 1);
			}
		);

		//Устанавливаем необходимую позицию интерфейса
		var ck = $.cookie("ui_save");
		for(key in ck){
			if(ck[key] == 0){
//вызываем событие "закрыть"
				$("." + key).next().trigger('click');
			}
		}

	});

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

10 thoughts on “Запоминаем положение интерфейса средствами JavaScript

  1. куки будут посылаться серверу с каждым запросом. лучше использовать localStorage и иже с ним

    • Согласен, но localStorage, еще не утвержден, и есть проблема поддержки всех браузеров, если только хаки писать.

  2. люди что я делаю не так? я скачал плагин jquery.ezCookie_0.8.0.js , кинул его в папку js весь код скопировал, вставил и в результате вместо слова открыть и закрыть какие то иероглифы,также я например закрываю 1 и 4 квадрат, обновляю страницу и все квадраты стоят как в первоначальном виде, что делать?

  3. Подскажите пожалуйста как сделать так, чтобы при нажатии на ссылку или кнопку открывалась в новой вкладке страница из списка урлов. И по порядку с задержкой в 5 секунд открытая страница перенаправлялась на следующую из списка.
    часа три уже пишу никак не получится, сам не справлюсь никак.. =(
    За ранее большое спасибо. мм если если поможете добавлю ваш урл в список =)

  4. Вопрос: почему у меня при щелчке (сделал все что написано) она закрывается и открывается резко без медленного открытия. Что делать?

  5. Здравствуйте, подскажите пожалуйста, что здесь мешает сохранить позицию и как это исправить

    // li > a.sf-with-ul’).parent(‘li’).addClass(‘sf-ul’);

    et_search_bar();
    et_footer_improvements(‘#footer .footer-widget’);


    (function($)
    {
    $.fn.et_switcher = function(options)
    {
    var defaults =
    {
    slides: ‘>div’,
    activeClass: ‘active’,
    linksNav: »,
    findParent: true, //use parent elements in defining lengths
    lengthElement: ‘li’, //parent element, used only if findParent is set to true
    useArrows: false,
    arrowLeft: ‘prevlink’,
    arrowRight: ‘nextlink’,
    auto: false,
    autoSpeed: 5000
    };

    var options = $.extend(defaults, options);

    return this.each(function()
    {
    var slidesContainer = jQuery(this);
    slidesContainer.find(options.slides).hide().end().find(options.slides).filter(‘:first’).css(‘display’,’block’);

    if (options.linksNav != ») {
    var linkSwitcher = jQuery(options.linksNav);

    linkSwitcher.click(function(){
    var targetElement;

    if (options.findParent) targetElement = jQuery(this).parent();
    else targetElement = jQuery(this);

    if (targetElement.hasClass(‘active’)) return false;

    targetElement.siblings().removeClass(‘active’).end().addClass(‘active’);

    var ordernum = targetElement.prevAll(options.lengthElement).length;

    slidesContainer.find(options.slides).filter(‘:visible’).hide().end().end().find(options.slides).filter(‘:eq(‘+ordernum+’)’).stop().fadeIn(700);
    return false;
    });
    };

    jQuery(‘#’+options.arrowRight+’, #’+options.arrowLeft).click(function(){

    var slideActive = slidesContainer.find(options.slides).filter(«:visible»),
    nextSlide = slideActive.next(),
    prevSlide = slideActive.prev();

    if (jQuery(this).attr(«id») == options.arrowRight) {
    if (nextSlide.length) {
    var ordernum = nextSlide.prevAll().length;
    } else { var ordernum = 0; }
    };

    if (jQuery(this).attr(«id») == options.arrowLeft) {
    if (prevSlide.length) {
    var ordernum = prevSlide.prevAll().length;
    } else { var ordernum = slidesContainer.find(options.slides).length-1; }
    };

    slidesContainer.find(options.slides).filter(‘:visible’).hide().end().end().find(options.slides).filter(‘:eq(‘+ordernum+’)’).stop().fadeIn(700);

    if (typeof interval != ‘undefined’) {
    clearInterval(interval);
    auto_rotate();
    };

    return false;
    });

    if (options.auto) {
    auto_rotate();
    };

    function auto_rotate(){
    interval = setInterval(function(){
    var slideActive = slidesContainer.find(options.slides).filter(«:visible»),
    nextSlide = slideActive.next();

    if (nextSlide.length) {
    var ordernum = nextSlide.prevAll().length;
    } else { var ordernum = 0; }

    if (options.linksNav === »)
    jQuery(‘#’+options.arrowRight).trigger(«click»);
    else
    linkSwitcher.filter(‘:eq(‘+ordernum+’)’).trigger(«click»);
    },options.autoSpeed);
    };
    });
    }
    })(jQuery);

    var $featuredArea = jQuery(‘#featured’),
    $all_tabs = jQuery(‘#all_tabs’);

    if ($featuredArea.length) {
    $featuredArea.et_switcher({
    useArrows: true ,
    auto: true,
    autoSpeed: 5000
    });
    };

    if ($all_tabs.length) {
    $all_tabs.et_switcher({
    linksNav: ‘ul#tab_controls li a’
    });
    };

    function et_footer_improvements($selector){
    var $footer_widget = jQuery($selector);

    if (!($footer_widget.length == 0)) {
    $footer_widget.each(function (index, domEle) {
    if ((index+1)%4 == 0) jQuery(domEle).addClass(«last»).after(«»);
    });
    };
    };

    function et_search_bar(){
    var $searchform = jQuery(‘#cat-nav div#search-form’),
    $searchinput = $searchform.find(«input#searchinput»),
    searchvalue = $searchinput.val();

    $searchinput.focus(function(){
    if (jQuery(this).val() === searchvalue) jQuery(this).val(«»);
    }).blur(function(){
    if (jQuery(this).val() === «») jQuery(this).val(searchvalue);
    });
    };
    $(document).ready(function(){
    $(«.close»).toggle(
    function(){
    $(this).prev().slideUp();
    $(this).html(«Открыть»);
    var class_name = $(this).prev().attr(«class»);
    $.setSubCookie(«ui_save», class_name, 0);
    },
    function(){
    $(this).prev().slideDown();
    $(this).html(«Закрыть»);
    var class_name = $(this).prev().attr(«class»);
    $.setSubCookie(«ui_save», class_name, 1);
    }
    );

    //Устанавливаем необходимую позиции интерфейса
    var ck = $.cookie(«ui_save»);
    for(key in ck){
    if(ck[key] == 0){
    $(«.» + key).next().trigger(‘click’);
    }
    }

    });

    //]]>

  6. [CDATA[
    jQuery.noConflict();

    jQuery(‘ul.superfish, #page-menu ul.nav’).superfish({
    delay: 200, // one second delay on mouseout
    animation: {opacity:’show’,height:’show’}, // fade-in and slide-down animation
    speed: ‘fast’, // faster animation speed
    autoArrows: true, // disable generation of arrow mark-up
    dropShadows: false // disable drop shadows
    });

    jQuery(‘ul.nav > li > a.sf-with-ul’).parent(‘li’).addClass(‘sf-ul’);

Comments are closed.