Сохранять переменные между загрузками страниц

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

Вот что я попробовал:

  var clicked = false;

  $(document).ready(function() {

    $("input[type='submit'][value='Search']").attr("onclick", "form.act.value='detailSearch'; clicked = true;  return true;");

    if (clicked == true) {
      // show hidden fields
    } else {
      // don't show hidden fields
    }
  });

Любые предложения о том, что не так с этим кодом?

4 ответа

Решение

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

Есть несколько способов сохранить значение в другом месте, чтобы можно было инициализировать его при загрузке с помощью JavaScript.


Строка запроса

При отправке формы с использованием GET метод, URL обновляется строкой запроса (?parameter=value&something=42). Вы можете использовать это, установив в поле ввода в форме определенное значение. Это был бы самый простой пример:

<form method="GET">
    <input type="hidden" name="clicked" value="true" />
    <input type="submit" />
</form>

При начальной загрузке страницы строка запроса не устанавливается. Когда вы отправляете эту форму, name а также value Комбинация входных данных передается в строке запроса как clicked=true, Поэтому, когда страница снова загружается с этой строкой запроса, вы можете проверить, была ли нажата кнопка.

Чтобы прочитать эти данные, вы можете использовать следующий скрипт при загрузке страницы:

function getParameterByName(name) {
    name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
    var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
        results = regex.exec(location.search);
    return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}

var clicked = getParameterByName('clicked');

( Источник)

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

Кроме того, для больших наборов данных это не оптимально. Передача строки не имеет большого значения, но для массивов и объектов данных вам, вероятно, следует использовать веб-хранилище или файлы cookie. Хотя детализация в разных браузерах немного отличается, практическое ограничение длины URI составляет около 2000 символов.


Веб-хранилище

С введением HTML5 мы также получили веб-хранилище, которое позволяет сохранять информацию в браузере при загрузке страниц. Есть localStorage который может сохранять данные в течение более длительного периода (пока пользователь не удаляет их вручную) и sessionStorage который сохраняет данные только во время текущего сеанса просмотра. Последнее полезно для вас, потому что вы не хотите, чтобы "clicked" был установлен в true, когда пользователь вернется позже.

Здесь я установил хранилище для события нажатия кнопки, но вы также можете привязать его к форме отправки или что-то еще.

$('input[type="submit"][value="Search"]').click(function() {
    sessionStorage.setItem('clicked', 'true');
});

Затем, когда вы загружаете страницу, вы можете проверить, установлена ​​ли она, используя это:

var clicked = sessionStorage.getItem('clicked');

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

sessionStorage.removeItem('clicked');

Если вы хотите сохранить объект или массив JS, вы должны преобразовать его в строку. Согласно спецификации должно быть возможно сохранить другие типы данных, но это пока не правильно реализовано во всех браузерах.

//set
localStorage.setItem('myObject', JSON.stringify(myObject));

//get
var myObject = JSON.parse(localStorage.getItem('myObject'));

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


Печенье

Альтернативой веб-хранилищу является сохранение данных в файле cookie. Cookies в основном предназначены для чтения данных на стороне сервера, но могут использоваться и для чисто клиентских данных.

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

$('input[type="submit"][value="Search"]').click(function() {
    $.cookie('clicked', 'true', {expires: 1}); // expires in 1 day
});

Затем при загрузке страницы вы можете прочитать файл cookie следующим образом:

var clicked = $.cookie('clicked');

Поскольку в вашем случае файлы cookie сохраняются между сеансами, вам нужно будет их сбросить, как только вы сделаете с ними все, что вам нужно. Вы не хотели бы, чтобы пользователь вернулся через день и все еще имел clicked установите в true.

if(clicked === "true") {
    //doYourStuff();
    $.cookie('clicked', null);
}

(не-jQuery способ установить / прочитать куки можно найти прямо здесь)

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


window.name

Хотя это кажется мне хаком, который, вероятно, произошел до появления localStorage / sessionStorage, вы можете хранить информацию в window.name имущество:

window.name = "my value"

Он может хранить только строки, поэтому, если вы хотите сохранить объект, вам нужно будет его преобразовать в строку, как указано выше. localStorage пример:

window.name = JSON.stringify({ clicked: true });

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

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

Попробуйте использовать $.holdReady(), history

<script src="jquery.js" type="text/javascript"></script>
</head>
<body>
<form method="POST">
    <input type="text" name="name" value="" />
    <input type="submit" value="Search" />
    <input type="hidden" />
    <input type="hidden" />
</form>
<script type="text/javascript">
function show() {
  return $("form input[type=hidden]")
          .replaceWith(function(i, el) {
            return "<input type=text>"
          });
}

$.holdReady(true);
    if (history.state !== null && history.state.clicked === true) {
       // show hidden fields
       // if `history.state.clicked === true` ,
       // replace `input type=hidden` with `input type=text`
       show();
       console.log(history);

    } else {
        // don't show hidden fields
        console.log(history);
    }
$.holdReady(false);

  $(document).ready(function() {

    $("input[type=submit][value=Search]")
    .on("click", function(e) {
        e.preventDefault();
        if (history.state === null) {
          // do stuff
          history.pushState({"clicked":true});
          // replace `input type=hidden` with `input type=text`
          show();
          console.log(history);
        } else {
          // do other stuff
        };
    });

  });
</script>
</body>

С помощью localeStorage или же sessionStorage кажется, лучшая ставка.

Способ сохранения clicked Переменная в области действия globle хранит это так:

if(localeStorage.getItem("clicked") === null)
    localeStorage.setItem("clicked", "FALSE"); // for the first time

$(document).ready(function() {

    $("input[type='submit'][value='Search']").attr("onclick", "form.act.value='detailSearch';return true;");

    var clicked = localeStorage.getItem("clicked") == "FALSE" ? "TRUE" : "FALSE";

    localeStorage.setItem("clicked", clicked);

    if (clicked == "TRUE") {
      // show hidden fields
    } else {
      // don't show hidden fields
    }

});

Вы можете попробовать это:

 $("input[type='submit'][value='Search']").click(function(){
     form.act.value='detailSearch'; 
     clicked = true;  
     return true;
});
Другие вопросы по тегам