Is declaratie in een included js-document ook valide voor het hoofddocument?

Status
Niet open voor verdere reacties.

JohanDerks

Verenigingslid
Lid geworden
2 dec 2006
Berichten
82
Ondertussen heb ik verschillende fouten gevonden in mijn vorige probleemprogramma, zodanig, dat de titel "Referenceerror i.v.m. (verkeerd?) gebruik van included javascriptdocument?" niet meer van toepassing is.
Eigenlijk gaat het om een heel complexe programmastructuur, bedoeld voor kenners van het Esperanto. Daarin begin ik met de gebruiker te laten bepalen, welke talen gebruikt moeten worden om uit te rekenen of een bepaald woord (ingevoerd door de gebruiker) voldoende "internationaal" is (en dus geësperantiseerd moet worden). Dat zijn zes europese talen - die staan vast - maar welke de zevende en laatste is, mag de gebruiker bepalen: italiaans of portugees, of zoiets als allebei voor de helft. Dat gebeurt met radio buttons:
Code:
<input type="radio" name="pI" value="it" />la itala<br />
			<input type="radio" name="pI" value="pt" />la portugala<br />
			<input type="radio" name="pI" value="ip" checked="checked" />la itala aŭ la portugala<br />
Om de vertalingen van het ingevoerde woord in de zeven talen mee te tellen is er de functie "kalkulu()", maar die werkt soms niet, of ik krijg als foutmelding "lE is niet gedefinieerd". Om met het laatste te beginnen. De included js-documenten zijn:
Code:
<script type="text/javascript" src="IMWeu.js">	
</script>														  
<script type="text/javascript" src="IMWesp.js">	
</script>
Dat lE niet is gedefinieerd klopt, maar ik dacht dat op te lossen door in IMWesp.js te zettenL:
Code:
for (var i=0; i<2; i++) {
            if (lE !== undefined) {if(lE.elements[allingvo][i].checked) {lE.elements[allingvo][i].checked = false;}}
           		}
(De reden voor die regel is, dat IMWesp.js ook voor een ander PHP-document gebruikt wordt, waar lE wel al gedefinieerd is.)
Over de functie, die eerst problemen gaf, heb ik toch nog vragen.
Code:
function kalkulu() {
var mal = "", nbro = 0;
elmPI = document.getElementsByName("pI");	
elmBazLgo = document.getElementsByName(fenro[i]);
if (elmPI.value == "ip") {  // lZ is gedeclareerd als document.forms['lingvojZamenhofaj'], it en pt zijn namen van variabelen in het formulier
        if (lZ.it.value == 1 || lZ.pt.value == 1) {
	  	    nbro += 1;
			}
		}
	else if (elmPI.value == "it" && lZ.it.value == 1) {
		nbro += 1;
		}
    else if (elmPI .value == "pt" && lZ.pt.value == 1) {
		nbro += 1;
		}
    for (var i = 0; i < 6; i++) {
        elmBazLgo = document.getElementsByName(fenro[i])[0];
        if (elmBazLgo.value == 1) {
			nbro += 1;
			} 	// elmBazLgo.value estas automate 0, kiam neniu radibutono estas markita pro kolapso
        else if (elmBazLgo.value === 0) {
			continue;} 	// sum += 1 ne aperas, ĉar tio estas en ĉiuj kazoj 7.
        else {
            alert("(Malfermu la pa\u011Don de lingvo kun kodo '" + fenro[i] + "' kaj)\n " + 
            "marku la (ne)similecon de la traduko de '" + lZ.tradukVorto.value + "' al tiu lingvo!");
        }
    }														
    if (nbro < 4) {
        mal = "mal";
    	document.getElementById("stop").style.display="inline";		
    	document.getElementById("plue").style.display="inline";
    } else {
    	document.getElementById("plue").style.display="inline";
	}
    lZ.rezulto.value = nbro + ", " + mal + "pli ol duono de 7 Zamenhofaj lingvoj";
}
Ik vraag me bijv. af:
1. Waarom wordt getElementsByName afgeraden? getElementsById is een extra attribuut, terwijl "name", denk ik, al een verplicht attribuut is.
2. Is "else {return false;}" overbodig of zelfs fout? Want er zijn maar drie mogelijkheden voor x.value: ip, it of pt.
3. fenro is de array van zes vaste talen, die meetellen. Moet ik dáár misschien [0] achter zetten?
 
Laatst bewerkt:
Een paar tips:
Het is niet overzichtelijk als je de code tijdens het bouwen gaat minimaliseren door dingen op 1 regel te zetten.
Geef verschillende elementen niet dezelfde variabele naam (var x), heb ik hieronder even x en y van gemaakt.
Voorkom boolean bugs en zet voor de zekerheid extra haken bij IF ((a==1) || (b==0)). Dit maakt niets uit voor de performance.
Gebruik geen x en y als variabele naam voor een element, handiger is elmPt en elmFenro dan weet je overal dat het een element is.
Je kan geen <?php echo $tradukVorto ?> in javascript zetten.
Je kan (maar dat weet je al) ook het datatype in een IF testen met === of !==
Code:
function kalkulu() {
    var mal = "",  // ?
        nbro = 0,  // telt aantal goedkeuringen
        x = document.getElementsByName("pI"),
        y = document.getElementsByName(fenro[i]);
        // lZ is gedeclareerd als document.forms['lingvojZamenhofaj']
        // it & pt zijn namen van formulier velden (goedgekeurd of afgekeurd)
    if (x.value == "ip") {
        if ((lZ.it.value == 1) || (lZ.pt.value == 1)) {
            nbro += 1;
        }
    } else if ((x.value == "it") && (lZ.it.value == 1)) {
        nbro += 1;
    } else if ((x.value == "pt") && (lZ.pt.value == 1)) {
        nbro += 1;
    } else {
        return false;
    }
    // test element fenro
    for (var i = 0; i < 6; i++) {
        if (y.value == 1) {
            nbro += 1;
        } else if (y.value == 0) {
            continue;
        } else {
            //  Volgt een opmerking, dat de gebruiker moet goed- of afkeuren:
            alert("(Malfermu la pa\u011Don de lingvo kun kodo '" + fenro[i] + "' kaj)\n " +
            "marku la (ne)similecon de la traduko de '<?php echo $tradukVorto ?>' al tiu lingvo!");
        }
    }
    // 
    if (nbro < 4) {
        mal = "mal";
        document.getElementById("stop").style.display = "inline";
        document.getElementById("plue").style.display = "inline";
    } else {
        document.getElementById("plue").style.display = "inline";
    }
    lZ.rezulto.value = nbro + ", " + mal + "pli ol duono de 7 Zamenhofaj lingvoj";
}
</script>
Noot: x en y heb ik laten staan, naamgeving laat ik aan jou over :)

Suc6 met je applicatie. Hafe fun.
 
Laatst bewerkt:
Ik heb je aanwijzingen opgevolgd, alleen stond die y, die je gegeven had, op de verkeerde plaats. Dat is nu elmBazLgo.
Ik heb met "alert" de datatypes van elmPI en elmBazLgo getest en krijg respectievelijk eenmaal "undefined" en zesmaal "object".
elmPI = document.getElementsByName("pI") haal ik op uit <?php $pI = $_POST['pI']; ?> en
<?php print '<input type="hidden" name="pI" value="'.$pI.'" /> ?>'; binnen het formulier.
Dat is kennelijk geen goeie methode.
Dat elmBazLgo = document.getElementsByName(fenro)[0] een object is (zou ook met getElementById(..) kunnen),
lijkt me juist, maar waarom elmBazLgo.value zes maal 1 oplevert (zes maal een goedkeuring van de gebruiker,
terwijl ik als gebruiker ergens tussen 0 en zes keer goedkeur) is me niet duidelijk.
Vrij elementaire fouten, maar ja ..........
 
Laatst bewerkt:
Het valt mij op dat er variabelen buiten de function zijn gedeclareerd. Op zich geen probleem, met name als het constantes zijn die niet meer veranderen. Soms kan dit wel een probleem veroorzaken omdat de scope van een variabele buiten een function groot is. Voorbeelden:
Code:
var a = 12;
function test1() {
  console.log(a); // 12
}
test1();

var b = 12;
function test2(n) {
  console.log(n);  // 12
}
test2(b);

var c = 8;
function test3() {
  var c = 12;
  console.log(c);  // 12
}
test3();
Stel, je hebt buiten de function een for loop met een var i. Deze i behoudt zijn laatste waarde (+ 1) na de for loop. Als je de i in een function gaat gebruiken zonder te declareren dan krijg je de meest rare effecten.

In bericht #1 zie ik staan: elmBazLgo = document.getElementsByName(fenro);
De variabele i komt van buiten de function en heeft een "willekeurige waarde.

Kan je hier iets mee?
 
Laatst bewerkt:
RE: Waarom wordt getElementsByName afgeraden?
Van alle attributen is de id het enige attribuut die uniek moet zijn binnen een html document. Ook is de id een globaal attribuut die bij elke tag mag worden gebruikt. Om deze 2 redenen wordt de id vaker gebruikt. Stel dat je name[0] gebruikt dan kan een html uitbreiding in de toekomst problemen veroorzaken in de JS. Als je name wilt gebruiken dan zou getElementsByName("naam") meer future-proof zijn.

RE: Is "else {return false;}" overbodig of zelfs fout? Want er zijn maar drie mogelijkheden voor x.value
Een else is optioneel en wordt ook wel vaak gebruikt om onverwachte situaties af te vangen. Als je zeker weet dat else nooit zal worden uitgevoerd kan je 'm gerust weglaten.

Handig if test:
Code:
if (typeof variabele !== 'undefined') {
  // variabele bestaat (is gedeclareerd)
}

if (waarde) {
  // waarde is NIET (null || undefined || NaN || empty || false || "" || 0)
  // dus waarde=true of waard<>0 of waarde=".." (minimaal 1 teken)
}
 
waarde van document.getElementsByName(array) met array van radio-knoppen

De fout zit hem absoluut in het volgende snippet:
Code:
for (var i = 0; i < 6; i++) {
        elmBazLgo = document.getElementsByName(fenro[i])[0];
		if (elmBazLgo.value == 1) {	
			nbro += 1;
			} 	
        else if (elmBazLgo.value == 0) {
			continue;
			}
                }
fenro is een array van zes variabelen met elk drie mogelijke waarden: 1, 0 en -1.
(-1 is de waarde, als geen van de drie radio-knoppen is gecheckt. Waar ik dat vandaan heb, weet ik niet.)
Krijgt fenro[0] die waarde of krijgt fenro die waarde? In het laatste geval moet die [0] weg. Maar dan krijg ik in console.log:
elmBazLgo = [object NodeList]; elmBazLgo.value = undefined
en nbro krijgt de waarde 0, dus elmBazLgo.value != 1
 
Laatst bewerkt:
De 3 waardes die je noemt zijn waarschijnlijk gebruikt door iemand die met Ja (1), Nee (0) en "Weet Niet" (-1) werkte. Dat is geen nette manier van coderen en kan je beter niet overnemen. True en False zijn meestal voldoende. Programmeurs die -1 of 99 als "weet niet" gebruikten waren de veroorzakers van het millennium probleem.

In dit stukje aan het eind in de for loop gebeurt niets en kan je in zijn geheel weghalen
Code:
else if (fenro[i] == 0) {
    continue;
}

Als fenro[4] bijvoorbeeld de waarde -1 heeft dan staat er getElementsByName(-1)[0] en dat mag niet.
Hieronder een algemeen voorbeeld dat je denk ik nog wat moet aanpassen.
Code:
// controleer alle <input type="radio" value="..." name="[B]abcd[/B]">
var elmBazLgo = document.getElementsByName("[B]abcd[/B]"); //alle inpouts met name=abcd
for (i = 0; i < elmBazLgo.length; i++) {  //loop door elk inputveld...
    if (elmBazLgo[i].value == 1) {  //...en vraag de waarde van dat veld op
        nbro += 1;
    }
}
Suc6. Have fun.
 
Laatst bewerkt:
Ophalen van inputwaarden van reeks radioknoppen via naam werkt niet.

if elmBazLgo.value = 1, resp. 0, -1 is kennelijk geen goede manier om de (drie) gevallen van een radiogroep te onderscheiden. Veel makkelijker is
Code:
for (var i = 0; i < 6; i++) {
         var elmBazLgo = document.getElementsByName(fenro[i]);
	      if (elmBazLgo[0].checked) {	
		   nbro += 1;
	      } else if (elmBazLgo[1].checked) {
		   continue;
              }
         }
kalkulu() werkt nu wel.
Ik heb nog wel andere problemen met de scope, maar kan daarvoor beter
een goede uitleg van scope en included js-script zoeken dan een nieuwe vraag stellen.
Bedankt voor de tips !
 
Graag gedaan.
Drie voorbeelden van een scope (waar is een variabele te benaderen) vind je in post #4.
Een include kent JS niet. JS kent wel modules maar die worden nog niet goed ondersteund, beter niet gebruiken dus.

Suc6 met de applicatie.
 
Status
Niet open voor verdere reacties.
Steun Ons

Nieuwste berichten

Terug
Bovenaan Onderaan