Je rencontre des problèmes de portée et de fermeture dans un extrait de code JavaScript. J'essaye de mettre à jour les propriétés class
et onclick
d'un bouton. Fondamentalement, cela devrait basculer entre "High" et "Low". Je pourrais obtenir la fonction pour exécuter sans essayer de redéfinir les paramètres, mais il n'a pas réussi à mettre à jour les propriétés. Donc, j'ai essayé de le redéfinir au code ci-dessous et j'obtiens maintenant une erreur que channel
n'est pas définie. Quelqu'un peut-il m'aider avec la syntaxe ici? J'ai besoin de la fonction interne pour pouvoir évaluer à la fois le canal et la valeur.Syntaxe et délimitation de la syntaxe JavaScript
Je sais que le code fourni ne fonctionnera pas en raison du rappel asynchrone. Je ne peux pas sembler obtenir la syntaxe de portée correcte pour la fonction onreadystatechange
. S'il vous plaît laissez-moi savoir si je peux fournir plus de clarification pour le problème que j'ai. Merci.
function setDio(channel, value) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = (function(channel,value) { return function(){
if (this.readyState === 4)
\t \t {
\t \t \t if (this.status === 200) {
\t \t \t \t document.getElementById('ok-msg').innerHTML = 'Digital Output successfully set to '+value+'.';
\t \t \t \t document.getElementById('ok-alert').style.display = 'block';
\t \t \t \t if(value===1)
\t \t \t \t {
\t \t \t \t \t document.getElementById('dio'+channel+'-high').class = 'ibradioactive';
\t \t \t \t \t document.getElementById('dio'+channel+'-low').class = 'ibradioinactive';
\t \t \t \t \t document.getElementById('dio'+channel+'-low').onclick = function(){ setDio(channel,0);};;
\t \t \t \t \t document.getElementById('dio'+channel+'-high').onclick = function(){} ;;
\t \t \t \t }
\t \t \t \t else
\t \t \t \t {
\t \t \t \t \t document.getElementById('dio'+channel+'-high').class = 'ibradioinactive';
\t \t \t \t \t document.getElementById('dio'+channel+'-low').class = 'ibradioactive';
\t \t \t \t \t document.getElementById('dio'+channel+'-high').onclick = function(){ setDio(channel,1);};;
\t \t \t \t \t document.getElementById('dio'+channel+'-low').onclick = function(){} ;;
\t \t \t \t }
\t \t \t }
\t \t \t else
\t \t \t {
\t \t \t \t document.getElementById('error-msg').innerHTML = 'Digital Output set failed ('+ this.status +'): '+this.responseText;
\t \t \t \t document.getElementById('error-alert').style.display = 'block';
\t \t \t }
}
};})(channel,value);
xmlhttp.open('POST', '/dio/' + channel, true);
xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xmlhttp.send('dio-value=' + value);
}
.alert,.ok-alert,.error-alert,.info-alert,.warning-alert {
font-family:arial;
font-weight:700;
color:#FFF;
margin-bottom:15px;
border-radius:20px;
padding:20px;
display:none;
}
.ok-alert {
background-color:#4CAF50;
}
.error-alert {
background-color:#f44336;
}
.info-alert {
background-color:#2196F3;
}
.warning-alert {
background-color:#ff9800;
}
.alert-close {
margin-left:15px;
color:#FFF;
font-weight:700;
float:right;
font-size:22px;
line-height:20px;
cursor:pointer;
transition:.3s;
}
.inner-group {
display:inline-block;
border:0 solid #000;
font-family:arial;
font-weight:700;
font-size:12pt;
background:#ccc;
border-radius:15px;
vertical-align:text-top;
box-shadow:4px 4px 10px #66a;
margin:10px;
padding:10px 4px;
transition:1s;
}
.ibradioactive {
background:#11AF11;
}
.ibradioactive span {
color:#fff;
}
.ibradioinactive span {
color:#000;
}
.ibradioinactive {
background:#ddd;
}
.ibradioinactive:hover {
background-color:#acf;
}
.ibradio,.ibradioactive,.ibradioinactive {
width:50px;
height:50px;
cursor:pointer;
box-shadow:3px 3px 2px #000;
-webkit-box-shadow:3px 3px 2px #000;
-moz-box-shadow:3px 3px 2px #000;
font-weight:700;
color:#000;
border-radius:40px;
border:1px solid #999;
margin:10px 10px 10px 20px;
padding:5px;
}
label {
display:inline-block;
width:125px;
padding:3px 10px;
}
<div id="error-alert" class="error-alert">
<span class="alert-close" onclick="this.parentElement.style.display='none';">×</span>
<span id="error-msg">This is an error alert box.</span>
</div>
<div id="ok-alert" class="ok-alert">
<span class="alert-close" onclick="this.parentElement.style.display='none';">×</span>
<span id="ok-msg">This is a success alert box.</span>
</div>
<div id="info-alert" class="info-alert">
<span class="alert-close" onclick="this.parentElement.style.display='none';">×</span>
<span id="info-msg">This is an info alert box.</span>
</div>
<div id="warning-alert" class="warning-alert">
<span class="alert-close" onclick="this.parentElement.style.display='none';">×</span>
<span id="warning-msg">This is an warning alert box.</span>
</div>
<br />
<div class="inner-group" style="width:550px;">
<label class="l2">Digital I/O #1</label><br>
<label class="l2" style="width:175px">Mode: OUTPUT</label><br />
<label class="l2">New State:</label>
<button class ="ibradioactive" type="submit" id="dio1-high" name="dio1-high" onclick="setDio(1,1)"><span>HIGH</span></button>
<button class ="ibradioinactive" type="submit" id="dio1-low" name="dio1-low" onclick="setDio(1,0)"><span>LOW</span></button>
</div>
EDIT:
Voici une version simplifiée de mon code original qui ne fonctionnait pas:
function setDio(channel, value) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState === 4)
{
if (this.status === 200) {
if(value === 1)
{
document.getElementById('dio'+channel+'-high').class = 'ibradioactive';
document.getElementById('dio'+channel+'-low').class = 'ibradioinactive';
}
else
{
document.getElementById('dio'+channel+'-high').class = 'ibradioinactive';
document.getElementById('dio'+channel+'-low').class = 'ibradioactive';
}
}
}
};
xmlhttp.open('POST', '/dio/' + channel, true);
xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xmlhttp.send('dio-value=' + value);
}
Comme cela ne fonctionnait pas, j'ai essayé de re-scoping et d'ajouter une fermeture pour m'assurer que la fonction évaluait les valeurs de paramètres qui étaient utilisées au moment de l'appel par rapport à la récupération des valeurs par défaut.
Les classes ne changeaient pas comme prévu et, en fait, la requête asynchrone n'était pas réellement détectée par le serveur. Donc, quelqu'un peut-il voir pourquoi cette fonction particulière ne fonctionnerait pas correctement? J'ai des fonctions similaires qui ne font que mettre à jour des valeurs simples innerHTML
avec succès. Changer la classe, cependant, ne semble pas fonctionner.
EDIT 2:
Alors, j'ai découvert une partie de mon problème. La raison pour laquelle la classe ne changeait pas est que j'essayais de définir le class
avec du texte au lieu d'un objet. Passer à className
semble avoir éclairci cela. Je suis également retourné à ne pas utiliser de portée de fermeture supplémentaire et cela peut fonctionner correctement maintenant. Toujours en train de tester pour vérifier tous les changements.
S'il vous plaît faire bouillir votre code pour quelques lignes douzaine. –
Je deuxième commentaire de torazaburo. HTML et CSS semblent inutiles et si votre problème concerne les étendues, l'appel 'document.getElementById()' n'est pas non plus nécessaire. Les observations de valeurs provenant du débogueur ou des sorties de la console devraient suffire. Veuillez ajouter une description de résultat _expected_ et _actual_. Et s'il vous plaît réduire l'indentation. –
Vous ne savez pas pourquoi l'extrait de code a mis de telles indentations. Je pense qu'il a été converti en onglets pour une raison quelconque. J'ai inclus tout parce que la fonction devrait changer les propriétés de style CSS et elles ne sont pas changées. Je vais simplifier mon code pour inclure simplement le JS pertinent à regarder. Pas tout à fait pourquoi vous avez dit 'getElementById()' n'est pas nécessaire. Sinon, comment vais-je accéder aux propriétés des éléments qui doivent être modifiés lorsque les résultats de la requête ont été renvoyés? – Psyfun