2016-08-04 29 views
5

Ich habe einen sozialen Stream, den ich mit setInterval aktualisieren möchte. SetInterval muss gestoppt werden, wenn jemand einen Kommentar oder eine Antwort hinterlässt, ansonsten löscht es den Inhalt der Textarea, da es innerhalb des zu aktualisierenden Inhalts geschachtelt ist.Wie setze ichinterval auf ready, stoppe auf textarea focus, starte dann auf textarea focusout?

Ich versuche, diesen Code, modifiziert, von einer anderen Antwort zu verwenden, aber es scheitert darin, dass es den Timer nach dem ersten Zyklus des setInterval-Timers nicht stoppt.

HTML ...

<div id="social_stream_content"> 
    <textarea id="comments" rows="4" cols="50" placeholder="Set focus to stop timer"></textarea> 
</div> 

JS ...

function auto_load(){ 
       data = '<textarea id="comments" rows="4" cols="50" placeholder="Set focus to stop timer..."></textarea>'; 
     $("#social_stream_content").html(data); 
     alert("auto_load invoked"); 
} 

var myInterval; 
var interval_delay = 10000; 
var is_interval_running = false; //Optional 

$(document).ready(function(){ 
    auto_load(); //Call auto_load() function when document is Ready 

    //Refresh auto_load() function after 10000 milliseconds 
    myInterval = setInterval(interval_function, interval_delay); 

    $('textarea').focus(function() { 
     console.log('focus'); 
     clearInterval(myInterval); // Clearing interval on window blur 
     is_interval_running = false; //Optional 
    }).focusout(function() { 
     console.log('focusout'); 
     clearInterval(myInterval); // Clearing interval if for some reason it has not been cleared yet 
     if (!is_interval_running) //Optional 
      myInterval = setInterval(interval_function, interval_delay); 
    }); 
}); 

interval_function = function() { 
    is_interval_running = true; //Optional 
    // Code running while textarea is NOT in focus 
    auto_load(); 
} 

Edit: Ich habe den Code aktualisiert, alles umfassen, wie auf JSfiddle getestet. Der Timer wird angehalten, wenn Sie nach dem Schließen des Alerts im Dokument ready sofort den Fokus auf die Kommentartextarea setzen.

Nachdem der Fokus entfernt wurde und der erste Zyklus des Intervall-Timers abgeschlossen ist, stoppt der Timer nicht erneut. Das Fokusereignis scheint zu stoppen.

Liegt das daran, dass der Kommentartextarea innerhalb des Inhaltsbereichs verschachtelt ist, der aktualisiert wird? Ich ziehe mir die Haare aus. Wenn ich die Verschachtelung entferne, funktioniert es wie erwartet.

Mein Vorbehalt ist, dass die Kommentartextareas immer aus offensichtlichen Gründen innerhalb des Content-Div des sozialen Streams verschachtelt werden.

Also, um die Frage weiter zu aktualisieren: Gibt es eine Möglichkeit, den Intervall-Timer auf Textfeld Fokus mit jquery zu stoppen, während das fokussierte Element im Update-Element verschachtelt ist? Warum hört das Fokusereignis nach dem Abschluss des ersten Intervalls auf zu feuern?

Edit: Der komplette JS-Code, funktionierend, mit der Lösung von Jeremy Klukan integriert, für alle, die die gleiche Art von Projekt machen.

ARBEITS JS:

function auto_load(){ 
    data = '<textarea id="comments" rows="4" cols="50" placeholder="Set focus to stop timer..."></textarea>'; 
    $("#social_stream_content").html(data); 
    alert("auto_load invoked"); 
} 

var myInterval; 
var interval_delay = 10000; 
var is_interval_running = false; //Optional 

$(document).ready(function(){ 
    auto_load(); //Call auto_load() function when document is Ready 

    //Refresh auto_load() function after 10000 milliseconds 
    myInterval = setInterval(interval_function, interval_delay); 

    $('body').on('focus', '#social_stream_content textarea', function (event) { 
     console.log('focus'); 
     clearInterval(myInterval); // Clearing interval on window blur 
     is_interval_running = false; //Optional 
    }).on('focusout', '#social_stream_content textarea', function(event) { 
     console.log('focusout'); 
     clearInterval(myInterval); // Clearing interval if for some reason it has not been cleared yet 
     if (!is_interval_running) //Optional 
      myInterval = setInterval(interval_function, interval_delay); 
    }); 
}); 

interval_function = function() { 
    is_interval_running = true; //Optional 
    // Code running while textarea is NOT in focus 
    auto_load(); 
} 
+0

Der Link zu der JSfiddle, die ich getestet habe mit ... https://jsfiddle.net/a60nj1pf/ –

Antwort

1

Das Fokusereignis hört auf zu arbeiten, denn wenn Ihre Intervallfunktion ausgelöst wird, ersetzt es den Inhalt des DIV, der es enthält, so dass TEXTAREA nicht mehr existiert.

Tun Sie dies statt:

$('body').on('focus', '#social_stream_content textarea', function (event) { 
 
    // Focus handler 
 
}).on('focusout', '#social_stream_content textarea', function(event) { 
 
    // Focusout handler 
 
});

Dies erfassen alle Fokus und focusout Ereignisse, die die Wähler „#social_stream_content Textarea“ entsprechen, ohne zu jedem Objekt direkt zu befestigen.

+0

Danke für das Speichern @ Jeremy Klukan! Das funktioniert perfekt. –

3

können Sie Fokus erkennen und Unschärfe für eine textarea mit addEventListener (Ereignisse: Fokus und Blur).

Sie können eine setInterval() mit clearInterval() durch eine intervalID beenden.

Unten ein einfaches Arbeitsbeispiel, das den Principal (in Vanilla JavaScript) zeigt.

Grundsätzlich gilt:

  • Wenn Seitenlade Timer startet.
  • Wenn Benutzer Fokus textarea Timer stoppt.
  • Wenn Benutzer Unschärfe textarea Timer startet erneut.

Dokumentation:

WindowTimers.clearInterval()

WindowTimers.setInterval()

Sie auch von Interesse Document.activeElement finden.

window.app = { 
 
    timerRef: null, 
 
    timerStart: function() { 
 
    this.timerRef = setInterval(function() { 
 
     //alert("Hello"); 
 
     console.log('refresh stream'); 
 
    }, 2000); 
 
    }, 
 
    timerStop:function(){ 
 
     clearInterval(this.timerRef); 
 
    }, 
 
    txtAreaListenFocus: function() { 
 
    var txtArea = document.getElementById('txtArea'); 
 
    txtArea.addEventListener('focus', function(event) { 
 
     this.timerStop(); 
 
     console.log('focus'); 
 
    }.bind(this)); 
 
    }, 
 
    txtAreaListenBlur: function() { 
 
    var txtArea = document.getElementById('txtArea'); 
 
    txtArea.addEventListener('blur', function(event) { 
 
     this.timerStart(); 
 
     console.log('blur'); 
 
    }.bind(this)); 
 
    }, 
 
    start: function() { 
 
    this.timerStart(); 
 
    this.txtAreaListenFocus(); 
 
    this.txtAreaListenBlur(); 
 
    } 
 

 
}; 
 

 
window.app.start();
<textarea id="txtArea" rows="4" cols="50"> 
 
    Some content here 
 
</textarea>


JQuery Version unten. Sie verwenden können .focusout() und .focusin():

$(document).ready(function(){ 
 
window.app = { 
 
    timerRef: null, 
 
    timerStart: function() { 
 
    this.timerRef = setInterval(function() { 
 
     //alert("Hello"); 
 
     console.log('refresh stream'); 
 
    }, 2000); 
 
    }, 
 
    timerStop:function(){ 
 
     clearInterval(this.timerRef); 
 
    }, 
 
    txtAreaListenFocus: function() { 
 
    $('#txtArea').focusin(function(event) { 
 
     this.timerStop(); 
 
     console.log('focus'); 
 
    }.bind(this)); 
 
    }, 
 
    txtAreaListenBlur: function() { 
 
    $('#txtArea').focusout(function(event) { 
 
     this.timerStart(); 
 
     console.log('blur'); 
 
    }.bind(this)); 
 
    }, 
 
    start: function() { 
 
    this.timerStart(); 
 
    this.txtAreaListenFocus(); 
 
    this.txtAreaListenBlur(); 
 
    } 
 

 
}; 
 

 
window.app.start(); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<textarea id="txtArea" rows="4" cols="50"> 
 
    Some content here 
 
</textarea>


In Bezug auf die speziell Ihren Code in Frage, habe ich unten in dem Arbeitsbeispiel beheben.

$(document).ready(function() { 
 
    var myInterval; 
 
    var interval_delay = 1000; 
 
    var is_interval_running = false; //Optional 
 
    var interval_function = function() { 
 
is_interval_running = true; //Optional 
 
console.log('refresh stream'); 
 
// Code running while comment textarea is not in focus 
 
//auto_load(); 
 
    }; 
 

 
    //auto_load(); //Call auto_load() function when DOM is Ready 
 

 
    //Refresh auto_load() function after 1000 milliseconds 
 
    myInterval = setInterval(interval_function, interval_delay); 
 

 
    $('#textarea').focus(function() { 
 
clearInterval(myInterval); // Clearing interval on window blur 
 
is_interval_running = false; //Optional 
 
    }).focusout(function() { 
 
clearInterval(myInterval); // Clearing interval if for some reason it has not been cleared yet 
 
if (!is_interval_running) //Optional 
 
    myInterval = setInterval(interval_function, interval_delay); 
 
    }); 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<textarea id="textarea" rows="4" cols="50"> 
 
    Some content here 
 
</textarea>

+0

Obwohl diese Antwort funktioniert, war ich auf der Suche nach einer Jquery-Lösung. Ich habe meine Frage aktualisiert, um klarer zu sein. Ich verstehe nicht, warum mein ursprünglicher Code den Timer nicht stoppt. –

+0

@EthanAaronVandal Ich habe meine Antwort mit einer jQuery-Version des Codes hinzugefügt. Wenn Sie meine Antwort nützlich gefunden haben, vergessen Sie bitte nicht, zu stimulieren oder meine Antwort mit dem "Pfeil" oder "Tick" Symbol auf der linken Seite :) Danke für Ihre Mitarbeit :) – GibboK

+1

@EthanAaronVandal Ich habe auch meine bearbeiten Antwort einschließlich einer möglichen Lösung für Ihren Code. Ich habe die Funktion 'auto_load' aus Ihrem Code auskommentiert, da die Funktion nicht in Ihrem Beispiel enthalten war. Außerdem habe ich die Zeit der Verzögerung geändert, damit Sie das Skript schnell testen können. Ich hoffe, Sie fanden es nützlich :) – GibboK

0

Mein fix: D

HTML:

<div id="social_stream_content"></div> 

jQuery:

var myInterval; 
var interval_delay = 1000; 
var is_interval_running = false; //Optional 

$(document).ready(function(){ 
    data = '<textarea id="comments" rows="4" cols="50" placeholder="Set focus to stop timer..."></textarea>'; 
    $(data).appendTo("#social_stream_content"); 

    //Refresh auto_load() function after 10000 milliseconds 
    var myInterval = setInterval(interval_function, interval_delay); 

    $('#comments').focus(function() { 
     console.log('focus'); 
     clearInterval(myInterval); // Clearing interval on window blur 
     is_interval_running = false; //Optional 
    }).focusout(function() { 
     console.log('focusout'); 
     clearInterval(myInterval); // Clearing interval if for some reason it has not been cleared yet 
     if (!is_interval_running) //Optional 
      myInterval = setInterval(interval_function, interval_delay); 
    }); 
}); 

interval_function = function() { 
    is_interval_running = true; //Optional 
    // Code running while textarea is NOT in focus 
    $("#comments").val(""); 
    console.log("loop"); 
} 

Hoffe, es hilft.