2013-08-16 17 views
5

Natknąłem się na ten dziwny kod na stronie internetowej, nad którą pracuję i nie rozumiem, jak i dlaczego zachodzi moje zachowanie.Co się stanie, jeśli spróbujesz przekierować przed przesłaniem formularza?

<input type="submit" value="Save" onclick="document.location.href='http://www.google.com'" /> 

(Zmieniono href, w rzeczywistości wskazywał ten sam URL co akcja formularza).

Ponieważ zdarzenie onclick jest wywoływane przed przesłaniem formularza, oczekiwałbym, że ten kod przekieruje stronę do witryny Google.com, a tym samym przestanie wykonywać tę stronę i nigdy nie prześle formularza. Ewentualnie przekieruj do Google.com, ale nadal możesz przesłać formularz.

Ale zdaje się, że przekierowanie jest całkowicie ignorowane, a formularz jest mimo wszystko przesyłany. Dlaczego tak się stało?
Potwierdziłem, że zdarzenie onclick jest w porządku; Przeniosłem przekierowanie do funkcji i wywołałem funkcję w onclick. Funkcja została przed wywołaniem nazwana dobrze, ale przekierowanie wydawało się być ignorowane.

+1

Zobacz [Zapobiegaj domyślnym jQuery Wyślij formularz] (http://stackoverflow.com/q/6462143/11683) i [event.preventDefault() vs. return false] (http://stackoverflow.com/q/ 1357118/11683). – GSerg

+0

Wiem, że zwracanie wartości false uniemożliwi przesłanie, w takim przypadku nastąpi przekierowanie. Ale dlaczego przekierowanie nie występuje w tym przypadku? Co to powstrzymuje? – GendoIkari

+0

Czy możesz powtórzyć to w [jsfiddle] (http://jsfiddle.net/), a także powiedzieć nam, z której przeglądarki korzystasz? –

Odpowiedz

4

Właśnie przetestowany to zachowanie w różnych przeglądarkach, wszystkie przeglądarki dał takie same wyniki, oto moja konkluzja:

<!-- submit button inside form --> 
<form method="post"> 
    <input type="submit" value="submit" /> <!-- onclick = submitted to same page --> 
    <input type="submit" value="submitNredirect" onclick="document.location.href='http://www.google.com';" /> <!-- onclick = submitted to same page, ignored redirect --> 
</form> 
<!-- submit button without form --> 
<input type="submit" value="submit" /> <!-- onclick = no submit or redirect occur --> 
<input type="submit" value="submitNredirect" onclick="document.location.href='http://www.google.com';" /> <!-- onclick = redirect --> 

Jak wiadomo, JavaScript jest liniowy, to wykonuje linię kodu, który nastąpi wcześniej. Powiedzmy, że mamy taką postać:

<form id="myform" method="post" onsubmit="alert('onsubmit');"> 
    <input id="mybtn" type="submit" value="submit" onclick="alert('onclick');" /> 
</form> 
<script> 
    $(document).ready(function() { 
     $('#mybtn').bind('click', function() { 
      alert('bind click'); 
     }); 
     $('#myform').bind('submit', function() { 
      alert('bind submit'); 
     }); 
     // onclick > bind click > onsubmit > bind submit 
    }); 
</script> 

Na kliknięcie przycisku, zdarzenia związane z przyciskiem następuje pierwszy (zdarzenia „click”), to wydarzenia związane z formą występuje obok (zdarzenia „Wyślij”). Wynik jest następujący:

  1. alert: onclick
  2. Alert: wiążą kliknij
  3. Alert: onsubmit
  4. Alert: wiążą złożyć
  5. składania forma

Jeśli uwzględni dowolny kod przekierowania w którejkolwiek z funkcji, przekierowanie zostanie zignorowane, a przesłanie wystąpi, wierzę, że javascript nadpisuje kod document.location.href z procesem "post-post", "przesłanie formularza" jest jak ukryta/ukryta linia kodu na końcu skryptu, jeśli w pewnym momencie nie zostanie wykonana return false;, ta niejawna/ukryta linia zostanie wykonana.

Nie jestem ekspertem, ale zrozumiałem to po kilku testach. Proszę popraw mnie jeżeli się mylę.

EDYCJA: A co, jeśli uwzględnimy w każdej funkcji document.location.href?tak:

<form id="myform" method="post" onsubmit="document.location.href='http://www.onsumbit.com';"> 
    <input id="mybtn" type="submit" value="submit" onclick="document.location.href='http://www.onclick.com';" /> 
</form> 
<script> 
    $(document).ready(function() { 
     $('#mybtn').bind('click', function() { 
      document.location.href='http://www.bindclick.com'; 
      return false; 
     }); 
     $('#myform').bind('submit', function() { 
      document.location.href='http://www.bindsumbit.com'; 
     }); 
    }); 
</script> 

Stan wartości ciąg zmian „href” w następujący sposób (ale wykonuje przekierowanie na końcu skryptu):

  1. document.location.href = „http://www.onclick.com” ;
  2. document.location.href = 'http://www.bindclick.com';
  3. document.location.href = 'http://www.onsubmit.com';
  4. document.location.href = 'http://www.bindsubmit.com';
  5. document.location.href = '/'; // złożenie formularza
  6. javascript, należy przekierować na podstawie "href" wartość ciągu

ale mamy return false; po # 2, co oznacza, że ​​nie będzie przekierować do "http://www.bindclick.com"

+0

Dobrze. GendoIkari nie pytał o użycie jQuery ... –

+0

@LoSauer Wiem, używam jQuery tylko do testowania, ponieważ pytanie nie dotyczy kodów, chodzi o to, jak zachowuje się javascript – evilReiko

+0

Rozumiem. Ale to ma niewiele wspólnego z JavaScriptem lub jego "liniowością". Chodzi o to, w jaki sposób moduły obsługi, a więc i bulgoczące zdarzenia dla danych wejściowych [type = submit], są skonfigurowane w konkretnej implementacji przeglądarki. Jedną z opcji jest nadpisywanie tych procedur obsługi ... –

0
<form action="http://www.yahoo.com" method="get"> 
<input type="submit" value="Save" onclick="document.location.href='http://www.google.com'" /> 
</form> 

Kliknij przycisk Zapisz i znalazłem się w zależności od przeglądarki Nastąpi przekierowanie do Yahoo (chrom) chyba dodać return false do zdarzenia onclick. W IE 10 zostajesz przekierowany do Google.

Myślę, że ktoś, kto zakodował przeglądarki, będzie musiał odpowiedzieć na to pytanie.

0

Co obserwujesz jest domyślne i dziedziczone zachowanie procedur obsługi dla HTMLInputElement, chyba że zostanie zastąpione.

Rozwiązanie:

Użyj HTML5 button type-submit Element zamiast, który wszystkich nowoczesnych przeglądarkach powinny być w stanie obsłużyć poprawnie.

<form action="/" method="post" onsubmit="alert('submit event')"> 
    <input type="text" name="someinput" value="100"> 
    <button type="submit" onclick="alert('button onclick handled before form-submit')">submit</button> 
</form> 

Objaśnienie:

Nie zapewnienie konkretnej przeglądarki, ale być może używasz WebKit, który miał problem ze zdarzeniem hierarchii beforeonsubmit/onclick.

Na stronie kodowej projektu można wyszukać kod implementujący różne HTMLElement.
Na przykład wyszukiwanie onsubmit doprowadzi do Webkit onsubmit-event bubbling test.

Jedną z opcji obejścia tego problemu z bulgotaniem zdarzeń jest użycie button i przekształcenie go w "przesłanie" poprzez znalezienie jego załączającego formularza i przesłanie go za pomocą funkcji (HTMLFormElement-instance).submit().

Innym jest zmiana procedury obsługi formularza, która powinna być tym, czego szukasz.

<form action="/" method="post" accept-charset="utf-8" id="myform3" 
    onsubmit="event.stopPropagation(); event.cancelBubble = true;"> 
    A form with the default Browser submit-handler overwritten: 
    <br> 
    <input type="text" name="someinput" value="100"> 
    <input type="submit" name="commit" value="Submit" 
    onclick="alert('will alert first and submit later using the browser default submit handler.');"> 
</form> 

Wszystkie przypadki zostały przedstawione w tej publikacji: fiddle.

Pozdrawiam!

0

Myślę, że to kwestia dyskusyjna,

Odpowiem w perspektywie zachowań,

Domyślna metoda formie jest GET więc na naciśnięcie przycisku przesłać formularz będzie uzyskać dane. Źródło Old Post

Ale jeśli masz e.preventDefault() dołączone do document.location.href = „http://www.google.com”

Teraz, jeśli link jest index.html strona Indeks lokalny zostanie wywołany w odniesieniu do adresu strony internetowej, ponieważ usunąłeś pierwotny link, nie można ocenić, dlaczego pierwotnie zostały one użyte !!! ???

mogę powiedzieć w swoim pytaniu uruchomić ten kod,

<form onsubmit="javascript:alert('Form Submit called '+ this.method);"> 
    <input type=submit value=Submit onclick="javascript:document.location.href='http://www.google.com';alert('Button Submit');" /> 
</form> 

to będzie jasne wezwanie przepływu. ponieważ document.location.href nigdy nie jest zmieniany używając tego ..

użyj tego kodu po zmianie href alert(document.location.href); da ci to położenie, które nie zostanie zmienione.

Być może uniemożliwić domyślne zachowanie może się zmienić, ale to nie jest część kodu ..

Mam nadzieję, że to będzie uczynić to bardziej jasne.

Powiązane problemy