Hi
ich lerne gerade webapp development und bin neu in dem Bereich.
Ich versuche gerade einen Slider zu relaisiren. Aber der hackelt und ist
recht langsam.
Liegt es an Javascript?
Oder sollte ich event handler benutzen?
Oder was anderes als oninput?
Vielen Dank,
<FORM action="/red.cgi" method="post" id="form1">
<input type="range" name="POT" min="0" max="100" value="{{ red_value }}"
class="slider" id="myRange">
<p>Power: <span id="demo"></span>%</p><br>
</P>
</FORM>
<script>
var slider = document.getElementById("myRange");
var output = document.getElementById("demo");
output.innerHTML = slider.value;
slider.oninput = function() {
document.getElementById("form1").submit();
output.innerHTML = this.value;
}
</script>
Der Slider ansich ist so schon OK.
Das Problem, was Du Dir da eingebaut hast, ist das hier:
1
slider.oninput = function() {
2
document.getElementById("form1").submit();
So wird bei jeder Änderung das Formular übertragen, was natürlich nicht
besonders zielführend ist, da Du beim verschieben von 0 auf 100 auch 100
Requests an Deinen Server sendest.
Besser wäre, wenn Du das mit einem Timeout versiehst oder für den Submit
ein anderes Event verwendest...
Hi
>> da Du beim verschieben von 0 auf 100 auch 100 Requests an Deinen Server sendest
ich baue ja einen webapp was nur auf mein PC läuft. Und es ist eine
Anförderung dass zwar nicht alle 100 Werte übertragen werden aber
zumindest einige.
gehts auch dass ich jedes n'te Wert rausschicke?
Danke?
klaus schrieb:> Ich sehe dass nur der letzte Wert submitted wird, keins der> Zwichenwerte.
Dann mach mal Deine Browserkonsole (F12) auf und schau dir an, wann das
Formular submitted wird.
Entweder machst Du asynchron mit ajax/jquery oder dem bereits
vorgeschlagenen Timeout. Alternativ kannst Du natürlich in Deinem
EventHandler auch einen Zähler einbauen. Was hindert Dich?
klaus schrieb:> ich baue ja einen webapp was nur auf mein PC läuft.
Dann ist Dein PC halt in diesem Moment der Server. Spielt ja keine
Rolle. Es wird ein HTTP Request gesendet, die Anwendung muss reagieren
und die Daten verarbeiten und dann gibt's eine Antwort an den Browser.
Das kostet nunmal Zeit und darum wirds holprig...
'oninput' triggert bei jeder Bewegung des Sliders und löst damit einen
HTTP-Request aus (auch, wenn der nur lokal ist, benötigt er doch Zeit).
'onchange' triggert er beim loslassen des Sliders einmalig.
1
<!DOCTYPE html>
2
<html>
3
<body>
4
<h1>This slider fires an event on each change using 'oninput':</h1>
Vielen dank.
Bitte bedenkt dass ich der volle Anfänger bin.
Bevor ich die Lösung von VN nn probiere:
Mein Code sendet den Submit nur einmal. Das Problem ist dass der server
(python flask) nach dem submit ja die html seite mit dem letzten wert
zurück sendet, und der slider ist nicht mehr unterm mouse ;-)
wtf
jetzt probiere ich mal das was vn nn freundlicher weise geschickt hat
;-)
Hi
Also wenn ich es richtig sehe, macht ja vn nn nichts anderes.
Wie löse ich das Problem, dass nach der ersten Übertragung der server
die html Seite zurück schickt, und mit diesem refresh mein mouse den
slider nicht mehr selektiert?
Muss der Wert denn sofort übermittelt werden?
slider.oninput wird bei jeder Bewegung am Slider
aufgerufen, jede minimale Änderung submitted die
Form (du siehst das wahrscheinlich nur einmal,
weil der Browser noch die Rückantwort des Servers
verarbeiten muss). Ändere doch mal
1
document.getElementById("form1").submit();
in
1
console.log(this.value);
Ich würde den Wert entweder dediziert übermitteln
(separater Send-Button oder sowas) oder erst mit
einem Zeitversatz nach der letzten Änderung am
Slider.
merciless
klaus schrieb:> Wie löse ich das Problem, dass nach der ersten Übertragung der server> die html Seite zurück schickt, und mit diesem refresh mein mouse den> slider nicht mehr selektiert?
Mit Ajax. Wenn du nur moderne Browser unterstützen musst, reicht fetch.
Wenn du auch IE9 oder so unterstützen willst, dann nimm am besten ne
Library wie jQuery.
https://caniuse.com/#feat=fetchhttps://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
z.B. (ungetestet)
klaus schrieb:> Bevor ich die Lösung von VN nn probiere:
Es ist keine Lösung, es ist eine Demo die dir den Unterschied zwischen
onchange und oninput zeigt.
klaus schrieb:> Mein Code sendet den Submit nur einmal.
Natürlich, weil du danach die Seite neu lädst. Ändert auch nix daran,
dass 'oninput' bereits während der Bewegung triggert, und das ist für
deine Anwendung halt zu früh.
klaus schrieb:> Also wenn ich es richtig sehe, macht ja vn nn nichts anderes.
Hast du es ausprobiert? Hast du es angesehen? Hast du es verstanden?
Es sind zwei Slider, einer arbeitet mit 'oninput' wie du, der andere mit
'onchange'.
klaus schrieb:> Wie löse ich das Problem, dass nach der ersten Übertragung der server> die html Seite zurück schickt, und mit diesem refresh mein mouse den> slider nicht mehr selektiert?
Nein. Einfach nur nein. Dein Problem ist ganz, ganz was anderes.
Aber ja, du könntest natürlich auch mit AJAX die Daten ohne neu laden
senden. Aber das löst dein Grundproblem nicht, nämlich dass du nicht
verstehst was 'oninput' macht.
Dirk K. schrieb:> erst mit> einem Zeitversatz nach der letzten Änderung am> Slider.
Dafür hat man onchange erfunden.
Mathias schrieb:> klaus schrieb:>> Wie löse ich das Problem, dass nach der ersten Übertragung der server>> die html Seite zurück schickt, und mit diesem refresh mein mouse den>> slider nicht mehr selektiert?>> Mit Ajax.
Ändert nix daran, dass er oninput nicht verstanden hat. Aber ja, an den
Symptomen herumdoktoren ist immer super.
Mathias schrieb:> nimm am besten ne> Library wie jQuery.
Natürlich. Lassen wir ihn jQuery gleich reinziehen ohne jeden Grund.
Hilft sicher. Vielleicht noch zwei, drei Frameworks?
ja, der wert muss sofort ( alle 200 ms) übermittelt werden.
Kann man es irgendwie verhindern dass ein refresh stat findet?
Meine Flask funtion sieht ungefähr so aus: siehe unten.
"return render_template" refreshed die seite in firefox. Damit wird der
Wert vom Slider auf den alten Wert zurück gesetzt
@app.route("/red.cgi", methods=['GET', 'POST'])
def red_cgi():
if request.method == 'POST':
red = int(request.form.get("RED_VALUE"))
print("red value " + str(red))
return render_template('bootloader.html', red_value=red)
vn nn schrieb:
>>Hast du es ausprobiert? Hast du es angesehen?
Ja vielen Dank. Ich habe es verstanden. Aber wie du es schon sagst dass
löst mein Problem noch nicht.
Was schlägst du mir genau vor? (sorry, ich bin echt ein Anfänger in
diesem bereich)
klaus schrieb:> Wie löse ich das Problem, dass nach der ersten Übertragung der server> die html Seite zurück schickt, und mit diesem refresh mein mouse den> slider nicht mehr selektiert?
Also ganz grundsätzlich würde ich Dir empfehlen, dass Du Dir mal die
Funktionsweise von CGI zu Gemüte führst.
klaus schrieb:> ich lerne gerade webapp development und bin neu in dem Bereich.
Wenn Du vorn anfangen würdest, stellte sich die Frage nämlich gar nicht.
Zu Deinem Problem:
Da müsstest Du mal ein bisschen ausholen, was dein red.cgi Skript
eigentlich macht bzw. ob die Ausgabe des Skriptes von der Oberfläche
irgendwie verwertet wird.
Im Prinzip gibt es mehrere Möglichkeiten. Zwei wären:
1) Wie oben beschrieben, den Request mit einem Timer hinauszögern.
Dabei bewegst Du den Schieberegler und erst wenn sich über eine Zeit X
(hier 300ms) der Wert nicht mehr verändert hat, werden die Daten
abgesendet.
Das ändert aber noch nichts an der Tatsache, dass der Browser das
Formular absendet und anschließend die Ausgabe Deines red.cgi Skriptes
wieder darstellt.
2) Daher wäre das Absenden des eingestellten Wertes per Ajax wesentlich
sinnvoller, zum Beispiel mit jQuery, welches Du Dir vorher runterlädst
und in deinem Webserververzeichnis ablegst.
klaus schrieb:> Ja vielen Dank. Ich habe es verstanden. Aber wie du es schon sagst dass> löst mein Problem noch nicht.
Du hast es nicht verstanden, denn genau das habe ich nicht geschrieben.
klaus schrieb:> ja, der wert muss sofort ( alle 200 ms) übermittelt werden.
Warum kommst du mit der Anforderung erst jetzt her? Was genau möchtest
du damit erreichen? Wo kommen diese 200ms her?
Salamitaktik hat noch niemanden weitergebracht.
klaus schrieb:> Kann man es irgendwie verhindern dass ein refresh stat findet?
Mit AJAX z.B.
Aber dafür müsste man erstmal wissen, was du erreichen willst.
Kenny schrieb:> Daher wäre das Absenden des eingestellten Wertes per Ajax wesentlich> sinnvoller, zum Beispiel mit jQuery, welches Du Dir vorher runterlädst> und in deinem Webserververzeichnis ablegst.
Warum sollte er sich für einen einfachen AJAX-Request eine fette,
überladene jQuery-Library reinziehen?
Wenn du das Formular absendest, wird die Seite immer neu geladen, das
ist sicherlich nicht was du willst. Mit Ajax läd man nur ein paar Daten
nach und muss die Webseite dann mit Javascript so verändern, wie du das
willst.
Der Server muss dann eben nicht das ganze HTML Template neu ausgeben,
sondern nur die Nutzdaten, z.B. als JSON Objekt. Ich kenne mich jetzt 0
mit Flask aus. Probier mal im 'if ... == "POST":' Zweig einfach ein
"return red". Evtl. klappt dann mein obiges Beispiel schon. Komplexere
Daten dann aber als JSON ausliefern.
vn nn schrieb:> klaus schrieb:>> ja, der wert muss sofort ( alle 200 ms) übermittelt werden.>> Warum kommst du mit der Anforderung erst jetzt her? Was genau möchtest
In seinem zweiten Post schreibt er das doch praktisch schon.
vn nn schrieb:> Was genau möchtest du damit erreichen?
Ist doch klar, slider bewegt sich => Antwort vom Server wird angezeigt.
vn nn schrieb:> Wo kommen diese 200ms her?
Die fallen vom Himmel. Ist das relevant, ob das jetzt 200 oder 20 sind?
Was er wollte ist ab dem zweiten Post ziemlich klar.
...
> Wo kommen diese 200ms her?
ich wil paar LEDs Dimmen. LEDs sollen ganz smooth hoch dimmen wenn ich
den slider hin und her schiebe.
Liege ich dann richtig dass ich mich mit ajax und json auseinander
setzen muss um nur Teile der Seite zu refreshen?
Mathias schrieb:> In seinem zweiten Post schreibt er das doch praktisch schon.
Ach? Wo?
Mathias schrieb:> vn nn schrieb:>> Was genau möchtest du damit erreichen?> Ist doch klar, slider bewegt sich => Antwort vom Server wird angezeigt.
Tja, nur stellt sich immer noch die Frage, ob das überhaupt notwendig
ist, oder ob man das auch einfacher lösen könnte.
Aber dass kommt dir natürlich nicht in den Sinn.
Mathias schrieb:> Die fallen vom Himmel. Ist das relevant, ob das jetzt 200 oder 20 sind?> Was er wollte ist ab dem zweiten Post ziemlich klar.
Natürlich ist es relevant, und gerade bei einem Anfänger ist nicht
zwingend sinnvoll, was er sich als Lösungsweg ausgedacht hat.
Wenn er schreibt, was er eigentlich erreichen will, kann man beurteilen
ob seine Lösung so überhaupt Sinn macht. Siehe auch
http://catb.org/~esr/faqs/smart-questions.html#symptoms
Aber scheinbar kommt das dir nicht in den Sinn.
klaus schrieb:> ich wil paar LEDs Dimmen. LEDs sollen ganz smooth hoch dimmen wenn ich> den slider hin und her schiebe.>> Liege ich dann richtig dass ich mich mit ajax und json auseinander> setzen muss um nur Teile der Seite zu refreshen?
Wenn sie das tun sollen, während du den Slider bewegst, ja.
Dafür ist natürlich kein fettes jQuery notwendig, sondern ein einfaches
XMLHttpRequest reicht. fetch() wäre die modernere Variante, wird aber
nicht von allen Browsern supported, ist also derzeit noch mit Vorsicht
zu genießen.
https://caniuse.com/#search=XMLHttpRequesthttps://caniuse.com/#search=fetch
Auf flask-Seite definierst du ein Ziel mit "methods=['POST']".
Z.B.:
vn nn schrieb:> Warum sollte er sich für einen einfachen AJAX-Request eine fette,> überladene jQuery-Library reinziehen?
Weil ich mir ganz sicher nicht den Punk gebe und jemandem mit dem
Kenntnisstand erkläre, wie er XHR requests erzeugt, die parameter
kodiert und ein JSON objekt mit seinen Parametern übergibt.
Aber das kannst Du ja machen, wenn Du das für zielführender hälst.
Vielleicht verrät er Dir ja auch noch, in welchen Browsern das alles so
laufen soll. Dann kannst Du das bei Deinen Ausführungen gleich
berücksichtigen.
klaus schrieb:> Liege ich dann richtig dass ich mich mit ajax und json auseinander> setzen muss um nur Teile der Seite zu refreshen?
Das wäre sinnvoll.
Kenny schrieb:> Weil ich mir ganz sicher nicht den Punk gebe und jemandem mit dem> Kenntnisstand erkläre, wie er XHR requests erzeugt, die parameter> kodiert und ein JSON objekt mit seinen Parametern übergibt.>> Aber das kannst Du ja machen, wenn Du das für zielführender hälst.> Vielleicht verrät er Dir ja auch noch, in welchen Browsern das alles so> laufen soll. Dann kannst Du das bei Deinen Ausführungen gleich> berücksichtigen.
XMLHttpRequest ist nun wirklich keine Hexerei. Gibt auch genügend
Anleitungen und Beispiele dazu.
z.B.
https://gist.github.com/KentaYamada/2eed4af1f6b2adac5cc7c9063acf8720
Und dann wundern wir uns, dass im Web nur noch Müll existiert, wenn wir
Anfängern einfach mal pauschal sagen "nimm jQuery, wie es wirklich geht
kapierst du es sowieso nicht".
Hi Leute
vielen Dank für eure Geduld.
Die Ajax Variante tut den Job für mein inhouse Projekt mehr als genug.
Es gibt nur noch ein kleines Problem, wie kann ich einen delay einbauen?
Aktuell wenn ich 2 Minuten den Slider hin und her bewege, scheint sich
ein Stau auf zu bauen.
Wie löse ich das?
$.ajax({
method: "POST",
url: "red.cgi",
data: { POT: slider.value }
});
Um bei jquery zu bleiben:
z.B. mit sowas
http://benalman.com/projects/jquery-throttle-debounce-plugin/
da kannst du dann angeben, dass z.B. max. alle 250 msec ein Post an den
Server geht, auch wenn öfter change-events kommen.
Ach übrigens, wenig bekannt, aber auch vor AJAX gab's da eine
Möglichkeit mit Post Daten ohne Seiten-Reload zu übermitteln:
Einfach das CGI mit dem HTTP-Status "204 No Content" antworten lassen.
Löst natürlich nicht das throttling-Problem.
vn nn schrieb:> Mathias schrieb:>> In seinem zweiten Post schreibt er das doch praktisch schon.>> Ach? Wo?
Da:
klaus schrieb:> Und es ist eine Anförderung dass zwar nicht alle 100 Werte übertragen werden
aber zumindest einige.
Aber Mitdenken kommt dir natürlich nicht in den Sinn.
Ab dem zweiten Post war klar, dass sein Ansatz der falsche und AJAX der
richtige ist und du nicht verstanden hast, was er wollte. Ihm dann
beibringen zu wollen, dass er onChange nicht verstanden hätte ist auf
jeden Fall falscher als seine Motivation nicht zu hinterfragen.
Dass ein simples onChange ohne limitierung Probleme bereitet hat er dann
ja selber rausgefunden, nachdem er die passende (unvollständige) Lösung
bekommen hat...
Mathias schrieb:> vn nn schrieb:>> Mathias schrieb:>>> In seinem zweiten Post schreibt er das doch praktisch schon.>>>> Ach? Wo?>> Da:>> klaus schrieb:>> Und es ist eine Anförderung dass zwar nicht alle 100 Werte übertragen werden> aber zumindest einige.>> Aber Mitdenken kommt dir natürlich nicht in den Sinn.
Von 200ms lese ich dort nix.
Mathias schrieb:> Ihm dann> beibringen zu wollen, dass er onChange nicht verstanden hätte ist auf> jeden Fall falscher als seine Motivation nicht zu hinterfragen.
Nachdem er ziemlich lang der Meinung war, dass oninput (nicht onchange,
das hat er nie verwendet) nur ein einziges Mal feuert, hat er es
offensichtlich auch nicht verstanden.
Was allerdings auch nicht schlimm ist, immerhin ist er ja Anfänger. Dass
du als Besserwisser 'onchange' und 'oninput' nicht auseinander halten
kannst, ist hingegen mehr als peinlich.
Mathias schrieb:> Dass ein simples onChange ohne limitierung Probleme bereitet hat er dann> ja selber rausgefunden
Ich wage mal zu behaupten, dass onchange keine Limitierung braucht.
Lern, die beiden auseinander zu halten.
Εrnst B. schrieb:> Um bei jquery zu bleiben:>> z.B. mit sowas>> http://benalman.com/projects/jquery-throttle-debounce-plugin/
Funktioniert btw auch ohne jQuery. Just for the record.