Próbuję uchwycić przycisk Wyślij mój formularz, a jeśli formularz zostanie przesłany, strona odświeża się i pokazuję kilka ukrytych pól. Chciałbym uchwycić, czy formularz został przesłany wcześniej, czy nie, a jeśli został przesłany ponownie, chciałbym odkryć ukryte pola. Próbowałem użyć zmiennej globalnej, aby to osiągnąć, jednak nie mogłem sprawić, by działała poprawnie.
Oto, czego próbowałem:
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
}
});
Jakieś sugestie, co jest nie tak z tym kodem?
preventDefault
nasubmit
wydarzeniu (zamiast tego, zclick
którego korzystasz).Odpowiedzi:
Ponieważ protokół HTTP jest bezstanowy, za każdym razem, gdy ładujesz stronę, użyje początkowych wartości tego, co ustawisz w JavaScript. Nie możesz ustawić zmiennej globalnej w JS i po prostu pozostawić tę wartość po ponownym załadowaniu strony.
Istnieje kilka sposobów na przechowywanie wartości w innym miejscu, aby można ją było inicjalizować podczas ładowania przy użyciu JavaScript
Ciąg zapytania
Podczas przesyłania formularza za pomocą
GET
metody adres URL jest aktualizowany za pomocą ciągu zapytania (?parameter=value&something=42
). Możesz to wykorzystać, ustawiając pole wejściowe w formularzu na określoną wartość. To byłby najprostszy przykład:<form method="GET"> <input type="hidden" name="clicked" value="true" /> <input type="submit" /> </form>
Podczas początkowego ładowania strony nie jest ustawiany żaden ciąg zapytania. Po przesłaniu tego formularza kombinacja
name
ivalue
dane wejściowe są przekazywane w ciągu zapytania jakoclicked=true
. Kiedy więc strona załaduje się ponownie z tym ciągiem zapytania, możesz sprawdzić, czy przycisk został kliknięty.Aby odczytać te dane, możesz użyć następującego skryptu podczas ładowania strony:
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');
( Źródło )
Możliwość korzystania z tego zależy od tego, jak obecnie działa Twój formularz, jeśli już używasz POST, może to być problematyczne.
Ponadto w przypadku większych zestawów danych jest to mniej niż optymalne. Przekazywanie ciągu znaków nie jest trudne, ale w przypadku tablic i obiektów danych prawdopodobnie powinieneś używać pamięci WWW lub plików cookie. Chociaż szczegóły różnią się nieco w różnych przeglądarkach, praktyczny limit długości identyfikatora URI wynosi około 2000 znaków
Pamięć internetowa
Wraz z wprowadzeniem HTML5 otrzymaliśmy również Web Storage, który umożliwia zapisywanie informacji w przeglądarce podczas ładowania strony. Jest to,
localStorage
które może zapisywać dane przez dłuższy czas (o ile użytkownik nie wyczyści ich ręcznie) isessionStorage
które zapisuje dane tylko podczas bieżącej sesji przeglądania. Ta ostatnia jest przydatna w tym przypadku, ponieważ nie chcesz, aby „kliknięto” było ustawione na prawdę, gdy użytkownik wróci później.Tutaj ustawiłem pamięć na zdarzenie kliknięcia przycisku, ale możesz również powiązać go z przesłaniem formularza lub cokolwiek innego.
$('input[type="submit"][value="Search"]').click(function() { sessionStorage.setItem('clicked', 'true'); });
Następnie po załadowaniu strony możesz sprawdzić, czy jest ustawiona za pomocą tego:
var clicked = sessionStorage.getItem('clicked');
Mimo że ta wartość jest zapisywana tylko podczas tej sesji przeglądania, może być konieczne zresetowanie jej wcześniej. Aby to zrobić, użyj:
sessionStorage.removeItem('clicked');
Jeśli chcesz zapisać obiekt lub tablicę JS, powinieneś przekonwertować to na łańcuch. Zgodnie ze specyfikacją powinno być możliwe zapisywanie innych typów danych, ale nie jest to jeszcze poprawnie zaimplementowane w przeglądarkach.
//set localStorage.setItem('myObject', JSON.stringify(myObject)); //get var myObject = JSON.parse(localStorage.getItem('myObject'));
Obsługa przeglądarek jest całkiem niezła, więc korzystanie z niej powinno być bezpieczne, chyba że musisz obsługiwać naprawdę stare / niejasne przeglądarki. Web Storage to przyszłość.
Ciasteczka
Alternatywą dla Web Storage jest zapisywanie danych w pliku cookie. Pliki cookie służą głównie do odczytu danych po stronie serwera, ale mogą być również używane wyłącznie do danych po stronie klienta.
Używasz już jQuery, co sprawia, że ustawianie plików cookie jest dość łatwe. Ponownie używam
click
zdarzenia tutaj, ale można go używać wszędzie.$('input[type="submit"][value="Search"]').click(function() { $.cookie('clicked', 'true', {expires: 1}); // expires in 1 day });
Następnie podczas ładowania strony możesz odczytać plik cookie w następujący sposób:
var clicked = $.cookie('clicked');
Ponieważ pliki cookie utrzymują się między sesjami w Twoim przypadku, będziesz musiał je wyłączyć, gdy tylko zrobisz z nimi wszystko, co musisz. Nie chciałbyś, aby użytkownik wrócił dzień później i nadal był
clicked
ustawiony na true.if(clicked === "true") { //doYourStuff(); $.cookie('clicked', null); }
(sposób ustawiania / odczytywania plików cookie inny niż jQuery można znaleźć tutaj )
Osobiście nie użyłbym pliku cookie do czegoś prostego, jak zapamiętywanie stanu kliknięcia, ale jeśli ciąg zapytania nie jest opcją i musisz obsługiwać naprawdę stare przeglądarki, które nie obsługują sessionStorage, to zadziała. Powinieneś to zaimplementować najpierw ze sprawdzeniem sessionStorage i tylko jeśli to się nie powiedzie, użyj metody cookie.
nazwa.okna
Chociaż wydaje mi się, że to hack, który prawdopodobnie powstał przed localStorage / sessionStorage, możesz przechowywać informacje we
window.name
właściwości:window.name = "my value"
Może przechowywać tylko ciągi znaków, więc jeśli chcesz zapisać obiekt, musisz go zdefiniować, tak jak w powyższym
localStorage
przykładzie:window.name = JSON.stringify({ clicked: true });
Główna różnica polega na tym, że te informacje są zachowywane nie tylko w przypadku odświeżania stron, ale także w różnych domenach. Jest jednak ograniczone do bieżącej karty, w której się znajdujesz.
Oznacza to, że możesz zapisać pewne informacje na swojej stronie i tak długo, jak użytkownik pozostaje na tej karcie, możesz uzyskać dostęp do tych samych informacji, nawet jeśli przeglądał inną witrynę iz powrotem. Generalnie odradzałbym używanie tego, chyba że musisz faktycznie przechowywać informacje z wielu domen podczas jednej sesji przeglądania.
źródło
window.name
). Może po prostu zrobić dokładnie to, czego potrzebujesz, bez używania plików cookie / localStorage.Spróbuj wykorzystać
$.holdReady()
,history
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 src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <form method="POST"> <input type="text" name="name" value="" /> <input type="submit" value="Search" /> <input type="hidden" /> <input type="hidden" /> </form>
źródło
Używanie
localeStorage
lubsessionStorage
wydaje się być najlepszym rozwiązaniem.Zamiast zapisać
clicked
zmienną w zasięgu globalnym, zapisz ją w ten sposób: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 } });
źródło
Możesz spróbować tego:
$("input[type='submit'][value='Search']").click(function(){ form.act.value='detailSearch'; clicked = true; return true; });
źródło