Javascript Daten über die Url senden ohne Seiten aufzurufen

xycgerry

Lieutenant
Registriert
Nov. 2010
Beiträge
920
Hallo,
ich möchte ein kleines Luftschiff über einen esp 8266 Wlan Chip steuern.

Der Chip funktioniert so das ich z.B http://192.168.4.1/gpio/1 aufrufe, dadurch wird der Ausgang 1 auf True gesetzt, die Ip ist hierbei die des Wlan Chips.

Unten hänge ich meinen Code an. Ich habe es schon so, das ich über einen Button und Javascript die Url aufrufen, sodass der Ausgang gesetzt wird, und mit einem anderen Button wieder auf 0 gesetzt werden kann.

Problem ist nun das in meinem Code jedesmal eine neue Seite aufgemacht wird, die dann natürlich nicht aufgerufen werden kann, ich habe schon den Code so verändert das ich danach wieder auf meine ursprüngliche Seite geschickt werde, trotzdem hat man nach einer Weile ziemlich viele Felder im Browser offen.

Außerdem hätte ich es gerne als Taster, sodass während ich das Feld drücke es auf 1 gesetzt wird, ansonsten auf 0

Ist dies machbar und wenn ja wie? Muss dazu sagen das dies mein erster Exkurs in Web, Javascript ist und ich vorher nur C++ Programmiert habe.

Schonmal danke!

<head>
<meta http-equiv="Conent-Type" content="text/html;charset=utf-8">
<title>JavaScript Kurs- Teil 1</title>
<style type="text/css">
body{
margin: 20px;
background-color:#222;}
h1 {
font-family:Ubuntu, sans-serif;
color: #FFF;
margin 0;
}
</style>
</head>
<body>
<SCRIPT type= "text/javascript">



function java(){

var eins= window.location;
//alert(eins);
//window.location = "www.google.de";

window.open(" http://192.168.4.1/gpio/1");

window.open(eins);
alert("Du bist ein Dummkopf!");}
function java2(){
var eins= window.location;
window.open(" http://192.168.4.1/gpio/0");
window.open(eins);}






</script>
<FORM name="heey">
<input type="button" value="an" onclick="java()">
<input type="button" value="aus" onclick="java2()">

<h1> JavaScript Kurs- Teil 1 </h1>
</FORM>

</body>
</html>
 
nur, dass er moeglicherweise keine html-seite auf dem wlan-chip ablegen kann. und fuer modifikation der origin allow headers um CORS zu umgehen muesste er serverseitig scripten, was auch bonusaufwand ist.

da ist ein iframe schon besser.

zbsp. sowas wie hier:

https://jsfiddle.net/wy0okqmw/

die gpio ids werden hier programmatisch generiert, wenn die bei dir bei 0 anfangen einfach in zeile 8 des js auf
Code:
var i = 0; i < n; i++
abaendern.
 
Also ich hab auf meinem ESP damals nen Mini-Webserver laufen gehabt, aber das hängt natürlich von der Umsetzung hier ab...
 
gut, kenne ich mich nicht aus mit. klang nur im OP so, als waere dieser "wlan-chip" was aeusserst rudimentaeres.

in dem fall, dass man auf http://192.168.4.1 selbst eine seite mit js-code ablegen kann, wuerde ich vorschlagen, aus meinem jsfiddle zeile 17 mit folgendem code zu ersetzen:
Code:
var xhr = new XMLHttpRequest();
xhr.open("GET", url + this.getAttribute("data-gpioid"));
xhr.send();

alternativ kann man dann noch error handling einbauen, das waere dann der xmlhttprequest dokumentation, stichwort onreadystatechange zu entnehmen.
 
bog schrieb:
nur, dass er moeglicherweise keine html-seite auf dem wlan-chip ablegen kann. und fuer modifikation der origin allow headers um CORS zu umgehen muesste er serverseitig scripten, was auch bonusaufwand ist.

da ist ein iframe schon besser.

zbsp. sowas wie hier:

https://jsfiddle.net/wy0okqmw/

die gpio ids werden hier programmatisch generiert, wenn die bei dir bei 0 anfangen einfach in zeile 8 des js auf
Code:
var i = 0; i < n; i++
abaendern.

Sorry aber das ist mein erster Programmierversuch mit Javascript,

wie benutz ich den code, den Javascript Teil kopiere ich in den Javascript Bereich meines Codes?
Und das oben drüber?
Das ist ja dann keine vollständige Website?
 
xycgerry schrieb:
Sorry aber das ist mein erster Programmierversuch mit Javascript,

und html offenbar ;)

du hast in deiner datei aus dem originalpost drei interessante tags: <style>, <body> und <script>. idealerweise kopierst du diese datei und loeschst aus den drei tags alles raus, und fuegst dann aus meinem jsfiddle folgendes wieder ein:

HTML => <body>
CSS => <style>
JAVASCRIPT => <script>

idealerweise fuegst du den HTML-inhalt zu beginn des <body>-tags ein und bewegst den <script>-tag ans ende des kurz vor den schliessenden </body>.

damit hast du alle drei komponenten (css/styling, html und javascript) in einer datei.
 
bog schrieb:
gut, kenne ich mich nicht aus mit. klang nur im OP so, als waere dieser "wlan-chip" was aeusserst rudimentaeres.

in dem fall, dass man auf http://192.168.4.1 selbst eine seite mit js-code ablegen kann, wuerde ich vorschlagen, aus meinem jsfiddle zeile 17 mit folgendem code zu ersetzen:

Gehen beide Varianten, vielen Dank. Was ist jetzt der Unterschied zwischen den beiden?

Und Wie kann ich leerzeichen in meine Seite einfügen so dass ich die Buttons beliebig auf der Seite positionieren kann?

Und ja, ist meine erste Html Programmierung :D

MFG
 
xycgerry schrieb:
Gehen beide Varianten, vielen Dank. Was ist jetzt der Unterschied zwischen den beiden?
das erste setzt den request ab und rendert die aus dem aufruf resultierende seite in einen iframe, also ein kleines fensterchen auf der rechten seite.
das zweite setzt lediglich im hintergrund den request ab und ignoriert jegliche ausgabe des servers.

xycgerry schrieb:
Und Wie kann ich leerzeichen in meine Seite einfügen so dass ich die Buttons beliebig auf der Seite positionieren kann?
den versteh ich nicht. aber prinzipiell wuerde ich dir fuer die anordnung der elemente ein wenig eigenlektuere von HTML/CSS empfehlen. ein guter anfang wird vielleicht sein, aus dem JS-code meines jsfiddles in zeile 9 den zeilenumbruch ("<br />") zu entfernen.
 
Ja sollte mich da mal bisschen einlesen ist ja auch irgendwie spannend.

Gibt es eine möglichkeit einen Taster zu Bauen in Javascript, der solange er gedrückt wird den Ausgang auf High schaltet, und wenn nicht dann auf low?

Im jetzigen Beispiel wird die Information ja erst versendet wenn ich den Taster loslasse.
MFG
 
das kommt wohl drauf an, wie du stetiges high bzw. low per http triggern kannst...
 
Man muss ja nur das "Click" zu einem mousedown ändern.(hab das 1h probiert gerade :)

Hab es jetzt so gemacht das beim mousedown die Funktion aufgerufen wird die den Ausgang setzt,
und beim mouseup wird der Ausgang rückgesetzt, somit muss ich garnicht stetiges High senden :D
MFG

Verdammt, mit dem Smartphone geht es nicht da beim drücken zwar ein mousedown registriert wird, beim loslassen des Toucbuttons aber kein Mousdown, jemand ne Idee?

Update ok es gibt extra Toucfunktionen das hab ich jetzt herausgefunden,

jetzt hänge ich jedoch wieder. Problem ist das im Button etwas drin stehen muss, sonst wird er sehr klein.
Wenn man auf dem Smartphone jedoch einen Button länger drückt wird automatisch der Text da drinnen markiert.
Gibt es die möglichkeit einen leeren Button mit beliebiger Größe zu herstellen?
Habe es oben schon in CSS Teil versucht aber das nimmt er garnicht.

Code:
Code:
<head>
<meta http-equiv="Conent-Type" content="text/html;charset=utf-8">
<title>JavaScript Kurs- Teil 1</title>
<style type="text/css">
#buttons {
  float: left;
  width: 900px;
  height: 100px;
}
#iframe {
  float:right;
}
	
</style>
</head>
<body>
<div   id="buttons"   />


</div>
<div id="iframe">
<iframe id="output">

</iframe>
</div>
<SCRIPT type= "text/javascript">

// anzahl der gpio pins
var n = 20;
// adressen-basis
var url = "http://192.168.4.1/gpio/";

// erstelle knoepfe fuer n GPIO pins
var btnContainer = document.querySelector("#buttons")
//for(var i = 0; i <= n; i++) {
//var a="Hallo";
 var i=1;
	btnContainer.insertAdjacentHTML("beforeend", '<button data-gpioid="' + i + '">' + "amliebstenleer" + '</button> ');
	//<br />
//}

// registriere aktionen auf den buttons
var iframe = document.querySelector("#output");
var btns = document.querySelectorAll("button");
btns.forEach(function(btn) {
	btn.addEventListener("touchstart", function(ev) {
      var xhr = new XMLHttpRequest();
    xhr.open("GET", url + this.getAttribute("data-gpioid"));
    xhr.send();
	});
	btn.addEventListener("touchend", function(ev) {
      var xhr = new XMLHttpRequest();
    xhr.open("GET", url + this.getAttribute("data-gpioid"-1));
    xhr.send();
 
  });
});
 var elem = document.getElementById("Eingabe");
    elem.addEventListener("mousedown", mouseDown);
    elem.addEventListener("mouseup", mouseUp);		
 
    function mouseDown() {
     elem.innerHTML = 'Maustaste wurde gedrückt.';
    }
 
    function mouseUp() {
      elem.innerHTML = 'Maustaste wurde losgelassen.';
    }
</script>


</body>
 
Zuletzt bearbeitet:
bitte
Code:
-tag benutzen.

vielleicht ist das hier die bessere herangehensweise, ungetestet... http://stackoverflow.com/a/4407335
 
Das sieht gut aus, aber ich versteh leider nicht wie man es einbindet, unter welchen von den drei tags?
MFG
habs, im style tag und ich musste noch ein body aufmachen und es in {} packen :D

Super es funktioniert, vielen dank.
Es währe trotzdem noch gut zu wissen wie man den Button vergrößert ohne mehr text reinzuschreiben
MFG
 
Zuletzt bearbeitet:
Hallo,

habe noch das Problem das bei dem Motor ein Button die Information einmal versendet werden soll, damit der Motor angeht und beim loslassen aus.

Für die Höhensteuerung werden jedoch Servos verwendet und diese sollen ihre Position verfahren solange ich den Taster drücke, habe dies mit einer Do while schleife versucht,
jedoch sendet diese die Information nur 3 mal und danach bleibt das Browser Fenster hängen.

Ich denke es liegt daran weil er sich dann in einer Art Dauerschleife befindet, gibt es eine Möglichkeit durchs " Mouseup" aus der Schleife zu bringen?
Oder irgendeine andere Möglichkeit mein Problem zu lösen.

Mit freundlichen Grüßen

Code:
<head>
<meta http-equiv="Conent-Type" content="text/html;charset=utf-8">
<title>JavaScript Kurs- Teil 1</title>
<style type="text/css">//Größe der Buttons wird festgelegt
#buttons {
  float: left;
  width: 900px;                 
  height: 100px;
}
#iframe {
  float:right;
}
body{
	  -webkit-touch-callout: none; /* iOS Safari */     // Das sorgt dafür das kein Text markiert werden kann, sonst versucht das Handy das immer wenn man auf dem button bleibt
    -webkit-user-select: none; /* Safari */
     -khtml-user-select: none; /* Konqueror HTML */
       -moz-user-select: none; /* Firefox */
        -ms-user-select: none; /* Internet Explorer/Edge */
            user-select: none; /* Non-prefixed version, currently
                                  supported by Chrome and Opera */}

</style>
</head>
<body>

<div   id="buttons"   />


</div>
<div id="iframe">
<iframe id="output">

</iframe>
</div>
<SCRIPT type= "text/javascript">

// anzahl der gpio pins
var n = 20;
// adressen-basis
var url = "http://192.168.4.1/gpio/";

// erstelle knoepfe fuer n GPIO pins
var btnContainer = document.querySelector("#buttons")
//for(var i = 0; i <= n; i++) {
//var a="Hallo";
 var i=2,a=4,b=6,c=8;
 btnContainer.insertAdjacentHTML("beforeend", '<button data-gpioid="' + a + '">' + "aufsteigen" + '</button> <br />');   //einzelne Buttons werden erstellt, variable a,b,i ist das was gesendet wird
 btnContainer.insertAdjacentHTML("beforeend", '<button data-gpioid="' + b + '">' + "vorwaerts" + '</button> ');
 btnContainer.insertAdjacentHTML("beforeend", '<button data-gpioid="' + i + '">' + "Motor ein" + '</button> <br />');
 
 

	btnContainer.insertAdjacentHTML("beforeend", '<button data-gpioid="' + c + '">' + "sinken" + '</button><br /> ');
	//<br />
//}

// registriere aktionen auf den buttons
var iframe = document.querySelector("#output");
var btns = document.querySelectorAll("button");
btns.forEach(function(btn) {
	btn.addEventListener("touchstart", function(ev) {     
do{	//hier wird auf eine Eingabe gewartet, und dann mit xhr.open und send die Url aufgerufen
      var xhr = new XMLHttpRequest();
    xhr.open("GET", url + this.getAttribute("data-gpioid"));
    xhr.send();
	
	}
	while((this.getAttribute("data-gpioid"))>2);
	});
	btn.addEventListener("touchend", function(ev) {
      var xhr = new XMLHttpRequest();
    xhr.open("GET", url + this.getAttribute("data-gpioid"-1));
    xhr.send();
 
  });
});
 var elem = document.getElementById("Eingabe");
    elem.addEventListener("mousedown", mouseDown);
    elem.addEventListener("mouseup", mouseUp);		
 
    function mouseDown() {
     elem.innerHTML = 'Maustaste wurde gedrückt.';
    }
 
    function mouseUp() {
      elem.innerHTML = 'Maustaste wurde losgelassen.';
    }
</script>


</body>
</html>
 
Nutze ein rekursives setTimeout anstatt einer while-Schleife

Code:
function sendMove() {
   if (button is up) {
      return;
   }

   if (no xhr active) {
      [...]xhrstuff[...]
   }

   setTimeout(() => sendMove(), 10);
}

Du solltest dabei aber noch beachten, dass XHR (standardmäßig) asynchron ist und du so viele parallele Requests aufbaust, da solltest du noch eine überprüfung einbauen ob bereits einer "aktiv" ist.
 
Zuletzt bearbeitet:
xycgerry schrieb:
Ich denke es liegt daran weil er sich dann in einer Art Dauerschleife befindet
Code:
while((this.getAttribute("data-gpioid"))>2);

hasse rääsch. deine abbruchkondition hier besagt, dass solange weiter XHRs geschickt werden sollen, wie das "data-gpioid"-attribut groesser als 2 ist. das bedeutet, dass du fuer alle gpio-knoepfe mit id 3 oder hoeher eine endlosschleife kriegst, weil sich deren id ja nie aendert.

ich habe wie zuvor schon mal erwaehnt keine erfahrung mit robotik und verstehe moeglicherweise alles falsch, aber so wie du das beschreibst waere es wohl am ehesten sinnvoll, wenn es auf seiten des wlan-chips einen benutzungsmodus gaebe, der permanent einen pin auf high/low schaltet. so koenntest du dann fuer das touchstart/mousedown event das constante high signal triggern und fuer das touchend/mouseup event auf low stellen.

das problem mit deiner schleife ist, dass XHR standardmaessig asynchron sind, d.h. die send()-methode nicht blockiert. dadurch werden, ohne das ende des vorigen requests abzuwarten, kontinuierlich send()s ausgefuehrt, vermutlich bis du an irgendein limit an gleichzeitigen requests seitens deines browsers stoesst, oder du den wlan-chip per denial of service attacke zum gluehen bringst.

wenn du keine wie oben erwaehnte permanent-high/-low schalter hast, koenntest du irgendwo eine statusvariable ablegen, die bei mousedown dann "an"schalten und dann rekursiv XHRs ausfuehren und zwar genau so lange, wie diese statusvariable nicht durch den mouseup-event wieder auf "aus" geschaltet wird. die rekursion wuerde ich dann bei readyState==4 beginnen, was bedeutet, dass der XHR abgeschlossen ist. dann hast du keine dutzende parallele requests, sondern immer nur einen.
 
Zurück
Oben