2016-07-04 27 views
5

Sto sviluppando una piccola funzione per il mio sito in cui un modulo di accesso viene mostrato automaticamente nella barra di navigazione quando il sito è aperto, ma solo se un alcuni cookie non sono stati impostati. Quindi, dopo 10 secondi, il modulo scomparirà.nasconde il modulo di accesso dopo 10 secondi se il cookie non è impostato e nessun input è selezionato

Si suppone anche che rimanga aperto se l'utente ha selezionato uno degli ingressi modulo O se uno degli ingressi contiene contenuto. (#user-pest o #pass-pest).

La maggior parte funziona come dovrebbe, tuttavia, anche quando uno degli ingressi è selezionato o contiene contenuti, una volta trascorsi 10 secondi, il modulo scomparirà dalla pagina.

che segue è la JavaScript (e jQuery) il codice che sto usando (aggiornamento).

$(document).ready(function(){ 
    // hide sign in form 

    function hideForm(){ // function for updating elements 
     $("#darknet-login-nav").css("display", "none"); 
     $(".index-outer").css("height", "100px"); 
     $(".index-inner").css("width", "438px"); 
     $(".index-inner").css("top", "-10px"); 
     $("#darknet-mast").css("font-size", "97px"); 
    } 

    function hideFormSet(){ // function used for updating elements and setting cookie 
     hideForm(); 
     document.cookie = "signinNav=set"; 
    } 

    var checkDisplayed = getCookie("signinNav"); // get cookie contents 
    if(checkDisplayed == "set"){ 
     hideForm(); // if cookie is set, hide the form 
    } else { // if it isn't 
     var hideInterval = setInterval(hideFormSet, 10000); // after 10 seconds, call hideFormSet function 
     if($("#user-pest").is(':focus') || $("#pass-pest").is(':focus')){ 
      clearInterval(hideInterval); // if one of the inputs are focused on, stop the interval 
     } else { 
      hideInterval; // if they aren't focused, start the interval 
     } 
    } 
}); 

e questo è il mio markup semplificato.

<div class="darknet-nav-login-form" id="darknet-login-nav"> 
    <form action="" method="post"> 
     <input type="text" name="username" id="user-pest" placeholder="Username" autocomplete="off"><br> 
     <input type="password" name="password" id="pass-pest" placeholder="Password" autocomplete="off"><br> 
    </form> 
</div> 

Sono ancora molto nuovo in JavaScript, quindi qualsiasi suggerimento e correzione sarà molto apprezzato.

MODIFICA: si prega di controllare il mio sopra codice aggiornato.

Anche quando gli ingressi sono focalizzati, l'intervallo continuerà comunque, anziché arrestarsi.

Grazie

+0

modi per migliorare la manutenibilità, è necessario convertire il CSS-metodo di 5 chiamate a una funzione che si chiama in modo che non si dispone di duplicare lo stesso codice. – Esko

+0

@Esko come lo farei? –

+1

'function myFunction() {$ (" # darknet-login-nav "). Css (" display "," none "); $ (". Index-outer"). Css ("height", "100px"); } 'e poi myFunction(); quando vuoi chiamarlo – Esko

risposta

3

Se capisco correttamente il tuo obiettivo, vuoi anche nascondere il modulo 10 secondi dopo che gli input hanno perso lo stato attivo. In tal caso è più facile associare gli eventi focusin/focusout per riavviare il timeout, altrimenti quando si lascia un input poco prima dell'intervallo dell'intervallo viene nascosto molto prima del timeout.

var inputs = $('#user-pest, #pass-pest'), 
    hideTimeout, 
    checkFocus = function(){ 
     var hide = !inputs.is(':focus'); 
     if(hide===!!hideTimeout)return; 
     if(hide) 
      hideTimeout = setTimeout(hideFormSet, 10000); 
     else 
      hideTimeout = clearTimeout(hideTimeout); 
     }; 

inputs.focusin(checkFocus).focusout(checkFocus); 
checkFocus(); 

Sidenote, jQuery is metodo verifica se uno degli elementi della matrice jq corrisponde al selettore, così invece di un separato e/o, si può fare: $('#user-pest, #pass-pest').is(':focus')

example Fiddle

Sidenote2, il rilegamento (re) si verificherà due volte perché un input perde lo stato attivo prima che il successivo acquisisca la messa a fuoco. Questo non è un problema in sé, ma se il modulo contiene solo quei 2 input, l'uso di eventi bubbling per controllare lo stato attivo del modulo potrebbe essere un piccolo passo ulteriormente ottimizzato: inputs.parent().focusin(checkFocus).focusout(checkFocus);

+0

ci dovrebbero essere due '!' qui: 'nascondi === !! hideTimeout'? –

+0

Thnakyou! Funziona perfettamente :-) –

+0

Sì, il '!!' è intenzionale per la verità hideTimeout.Forza hideTimeout ad essere un valore booleano. per esempio. '!! undefined === false', quindi' !! 0' dove '!! anynumber === true' (e felice che abbia aiutato :)) –

3

avete bisogno di un & & in questa linea.

if(!$("#user-pest").is(':focus') || !$("#pass-pest").is(':focus')){ 

ciò che si aveva prima era

if(user-pest is not focused OR pass-pest is not focused) 

Un utente non può mettere a fuoco tutti e due in una sola volta, quindi questo sarà sempre valutata come vera e nascondere sarà impostata su true. Utilizzare il seguente:

if(!$("#user-pest").is(':focus') && !$("#pass-pest").is(':focus')){ 

In alternativa si potrebbe anche utilizzare il seguente

if($("#user-pest").is(':focus') || $("#pass-pest").is(':focus')){ 
    var hide = false; 
} else { 
    var hide = true; 
} 

Come sottolineato nel tuo commento c'è anche un altro problema, che ho perso la prima volta.

La variabile nascosta è impostata sul caricamento della pagina, cosa che avviene all'istante e molto probabilmente non avresti avuto il tempo di mettere a fuoco uno degli oggetti. Dovresti spostare il codice che controlla se è focalizzato all'interno del callback di timeout.

Vedere this jsFiddle per il codice completo di un esempio funzionante. Fondamentalmente il tuo timeout dovrebbe verificare se gli input sono focalizzati durante l'esecuzione, non sul caricamento della pagina, come si vede nel seguente frammento.

setTimeout(function() { 
    if (!$("#user-pest").is(':focus') && !$("#pass-pest").is(':focus')) { 
    $("#darknet-login-nav").css("display", "none"); 
    $(".index-outer").css("height", "100px"); 
    $(".index-inner").css("width", "438px"); 
    $(".index-inner").css("top", "-10px"); 
    $("#darknet-mast").css("font-size", "97px"); 
    document.cookie = "signinNav=set"; // set the cookie so the form doesn't appear when they come back later 
    } 
}, 2000); 
+0

Hmm .. Non farà la stessa cosa? Perché se nessuno di essi viene selezionato contemporaneamente, lo nasconderà sempre. Ma, capisco cosa intendi –

+0

Ah, ho appena visto la modifica. Capisco ora :) controllerà per vedere se funziona. Grazie –

+0

Siamo spiacenti, si nasconde ancora, anche se è selezionato .. Qualcos'altro che puoi vedere? –

1

Ecco una soluzione che garantisce che gli input siano ogni vuoto e che non sono focalizzati. Il comportamento oltre il timeout iniziale di 10 secondi non è stato specificato, quindi ho lasciato l'intervallo attivo: il comportamento hide verrà richiamato ogni volta che si verifica il timeout e vengono soddisfatte le condizioni per nascondere l'intestazione.

Se si desidera renderlo un timer "one-shot", semplicemente clearInterval nella funzione intervalHandler.

window.addEventListener('load', onDocLoaded, false); 
 

 
var intervalHandle; 
 

 
function onDocLoaded(evt) 
 
{ 
 
\t intervalHandle = setInterval(intervalHandler, 2000); 
 
} 
 

 
function hideHeader() 
 
{ 
 
\t document.getElementById('darknet-login-nav').classList.add('hidden'); 
 
} 
 

 
// returns true/false 
 
// true if the header should be hidden, false otherwise. 
 
// Things that will prevent the header from being hidden area 
 
// 0) content in the #user-pest input 
 
// 1) content in the #pass-pest input 
 
// 2) focus of either #user-pest or #pass-pest elements 
 
function shouldHideHeader() 
 
{ 
 
\t if (document.getElementById('user-pest').value != '') 
 
\t \t return false; 
 
\t \t 
 
\t if (document.getElementById('pass-pest').value != '') 
 
\t \t return false; 
 
\t \t 
 
\t if (document.activeElement == document.getElementById('user-pest')) 
 
\t \t return false; 
 
\t \t 
 
\t if (document.activeElement == document.getElementById('pass-pest')) 
 
\t \t return false; 
 
\t \t 
 
\t return true; 
 
} 
 

 

 
function intervalHandler() 
 
{ 
 
\t if (shouldHideHeader()) 
 
\t \t hideHeader(); 
 
}
.darknet-nav-login-form 
 
{ 
 
\t height: 42px; 
 
} 
 
.hidden 
 
{ 
 
\t height: 0px; 
 
\t overflow: hidden; 
 
\t transition: height 2s; 
 
}
<div class="darknet-nav-login-form" id="darknet-login-nav"> 
 
\t \t <form action="" method="post"> 
 
\t \t \t <input type="text" name="username" id="user-pest" placeholder="Username" autocomplete="off"/><br> 
 
\t \t \t <input type="password" name="password" id="pass-pest" placeholder="Password" autocomplete="off"/><br> 
 
\t \t </form> 
 
\t </div>