Pagina 1 di 4 1 2 3 ... ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 35
  1. #1

    Estendere elementi del browser

    Salve, volevo sapere se è possibile estendere elementi di default in javascript, tipo se io un array del tipo:
    codice:
    document.getElementsByTagName("input")
    volevo fare in modo di scrivere:
    codice:
    document.getElementsByTagName("input").whereTypeIs("password");

    E' possibile ?

  2. #2
    Vorresti prelevare una array di elementi non solo sulla base del tipo di tag ma anche di uno dei suoi attributi a scelta. Richiesta legittima, ma che allo stato attuale non implementa alcun metodo nativo in javascript per lo scopo.

    D'altra parte, anche se esistesse un tale metodo, ti ritornerebbe comunque una array (di tutti gli elementi input presenti in una pagina che siano anche del tipo password - se poi ne hai solo uno, sempre una array ti ritorna a meno che non gli assegni un ID e poi lo indirizzi direttamente con getElementByid )

    per cui: no, ti tocca prelevare tutta la array degli elementi input, e poi fare un ciclo e individuare da te quelli il cui type=="password"

    var foo=document.getElementsByTagName('INPUT');
    var inputPassword=[];
    if(foo){
    for(var e=0; e<foo.length; e++){
    if(foo[e].type=='password'){inputPassword[++inputPassword.length-1]=foo[e];}
    }
    }

    //da qui in poi inputPassword è una array con tutti gli elementi password, cioè emula quello che ti ritornerebbe un ipotetico metodo whereTypeIs ritornerebbe se esistesse

  3. #3
    ps comunque puoi fare di meglio: ti crei la tua funzione whereTypeIs(nomeTag, nomeAttributo) che ti ritorna quello che vuoi. Tra l'altro, risparmi anche parecchia scrittura:

    whereTypeIs('input', 'password')
    è decisamente più semplice da scrivere che
    document.getElementsByTagName("input").whereTypeIs ("password");

    Da quello che so (magari sbaglio) getElementsByTagName non è prototypizzabile. Ma appendere nuovi metodi ai metodi nativi soddisfa solo il nostro gusto estetico, non la funzionalità: perchè probabilmente se tu potessi appendere come metodo getElementsByTagName e poi effettuassi un benchmark intensivo su whereTypeIs come oggetto di classe e poi sullo stesso identico whereTypeIs ma nella sua versione procedurale, alla fine verrebbe pure fuori che whereTypeIs è più veloce quando è procedurale.

  4. #4
    Utente di HTML.it L'avatar di carlomarx
    Registrato dal
    Oct 2009
    Messaggi
    1,669
    L'oggetto document.getElementsByTagName("input") non è un array, è una HTMLCollection (è molto simile a un array, ma non dispone degli stessi metodi dell'array).

    Esiste il metodo push? Usiamolo.

    codice:
    var foo = document.getElementsByTagName("input");
    var inputPassword = [];
    if (foo) {
    	for (var e = 0; e < foo.length; e++){
    		if (foo[e].type === "password") { inputPassword.push(foo[e]); }
    	}
    }
    Originariamente inviato da TrueLies
    per cui: no, ti tocca prelevare tutta la array degli elementi input, e poi fare un ciclo e individuare da te quelli il cui type=="password"
    Esiste per la verità un metodo più sintetico, assai simile alla via suggerita dalla domanda iniziale:

    codice:
    var aMiaCollezione = [];
    Array.prototype.forEach.call(document.getElementsByTagName("input"), function (oInputEl) { if (oInputEl.type === "password") { this.push(oInputEl); } }, aMiaCollezione);
    alert(aMiaCollezione.length);
    Ma credo che non vada bene per le versioni di Internet Explorer inferiori alla 9. Per cui se vuoi percorrere questa via devi implementare questo codice in testa al tuo script per renderlo compatibile con tutti i browser:

    codice:
    if (!Array.prototype.forEach) {
    	Array.prototype.forEach = function(fun /*, thisp */) {
    		"use strict";
    		if (this === void 0 || this === null) { throw new TypeError(); }
    		var t = Object(this);
    		var len = t.length >>> 0;
    		if (typeof fun !== "function") { throw new TypeError(); }
    		var thisp = arguments[1];
    		for (var i = 0; i < len; i++) { if (i in t) { fun.call(thisp, t[i], i, t); } }
    	};
    }
    (fonte: https://developer.mozilla.org/en/Jav...#Compatibility)

  5. #5
    E' uguale Carlo - HTMLCollection è puristicamente più corretto ma all' atto pratico, per quel che ci devi fare, è una array. Chi usa getElementsByTagName fa uno scan con un ciclo, cioè utilizza l'oggetto come array: non esistono, sull' oggetto ritornato, operazioni che permettano di distinguere HTMLCollection da array.

    Per quello che riguarda il metodo push è questione di preferenze personali - per fortuna in programmazione c'è più di un modo di fare le cose.
    Io personalmente (ma non pretendo che la mia posizione debba essere condivisa) non uso push sift pop e unshift per manipolare una array in quanto come metodi esistono, ma solo quando, nella array che manipolo, voglio rendere patente l'aspetto FIFO o LIFO - e non è questo il caso.
    Ma se uno vuole può usare anche push se preferisce.

    semmai, forse ti è sfuggita una altra cosa (ti vedo dell' umore di discutere di teoria, e a me sta bene e lo dico senza ironie!), che invece è singolare nel mio codice:
    inputPassword[++inputPassword.length-1]

    Noti nulla di strano?
    Beh se no n noti nulla, te lo rivelo io bastava scrivere: [inputPassword.length]
    Come mai prima incremento e poi decremento, operazione apparentemente futile?

  6. #6
    Originariamente inviato da TrueLies
    bene e lo dico senza ironie!), che invece è singolare nel mio codice:
    inputPassword[++inputPassword.length-1]

    Noti nulla di strano?
    Beh se no n noti nulla, te lo rivelo io bastava scrivere: [inputPassword.length]
    Come mai prima incremento e poi decremento, operazione apparentemente futile?
    Grazie ragazzi delle delucidazioni !
    No non noto niente di strano, prima incrementa la variabile, poi accede all'indice della variabile - 1.
    Un po' come scrivere:
    codice:
    inputPassword[inputPassword.length];
    inputPassword++;
    Solo che semmai dovrebbe essere -2, non -1

  7. #7
    Sì beh in realtà
    inputPassword[++inputPassword.length-1]
    è una operazione superflua che tradisce un background:

    1) ++inputPassword.length è come se uno allocasse prima la slot di memoria, poi con -1 indirizza la ultima slot appena allocata. Ma in javascript questo non serve, per quanto concettualmente va benissimo.

    2) assegnare ad una array un indice numerico può creare array con entità soprannumerarie "fantasma"

    var foo=new Array();
    foo[7]='ciao'

    ora, purtroppo, esistono anche foo[0] foo[1] foo[2] ecc..., tutte equivalenti a undefined. E' come se io avessi scritto
    var foo= new Array();
    foo.length=8;
    ora foo ha 8 elementi validi, indirizzabili, ma che custodiscono valori undefined.
    La espressione ++inputPassword.length-1 ti fa capire che questo qui deve averci preso un tale picchio anni fa con questa caratteristica, che ancora se ne vedono le tracce di quanto teme gli ricapiti

  8. #8
    Utente di HTML.it L'avatar di carlomarx
    Registrato dal
    Oct 2009
    Messaggi
    1,669
    Stavo pensando che se vuoi ricavarti un metodo standard per setacciare una HTMLCollection puoi fare così:

    codice:
    function HTMLStrictCollection(sElName, sElType) {
    	Array.prototype.forEach.call(document.getElementsByTagName(sElName), function (oInputEl) { if (oInputEl.type === sElType) { Array.prototype.push.call(this, oInputEl); } }, this);
    }
    HTMLStrictCollection.prototype = HTMLCollection;
    
    function ottieniCollezione() {
    	var oMiaCollezione = new HTMLStrictCollection("input", "password");
    	alert(oMiaCollezione.length);
    }
    Originariamente inviato da TrueLies
    E' uguale Carlo - HTMLCollection è puristicamente più corretto ma all' atto pratico, per quel che ci devi fare, è una array. Chi usa getElementsByTagName fa uno scan con un ciclo, cioè utilizza l'oggetto come array: non esistono, sull' oggetto ritornato, operazioni che permettano di distinguere HTMLCollection da array.
    Prova a utilizzare il metodo slice con una HTMLCollection, ad esempio così:
    codice:
    document.getElementsByTagName("input").slice(1, 3)
    Non funzionerà mai, perché una HTMLCollection non ha il metodo slice. Se vuoi applicarlo a una HTMLCollection dovrai fare così:
    codice:
    Array.prototype.slice.call(document.getElementsByTagName("input"), 1, 3)
    Ergo, una HTMLCollection è spesso interscambiabile con un'array, ma non sempre!

    Originariamente inviato da TrueLies
    Per quello che riguarda il metodo push è questione di preferenze personali - per fortuna in programmazione c'è più di un modo di fare le cose.
    Io personalmente (ma non pretendo che la mia posizione debba essere condivisa) non uso push sift pop e unshift per manipolare una array in quanto come metodi esistono, ma solo quando, nella array che manipolo, voglio rendere patente l'aspetto FIFO o LIFO - e non è questo il caso.
    Ma se uno vuole può usare anche push se preferisce.
    Certo, ma c'è quasi sempre una via più performante di un'altra. Se non usi il metodo push sei costretto a leggere la proprietà length dell'array, che significa dispendio di processore. In un ciclo molto complesso può comportare tanto (prova a scrivere un programma di scacchi in javascript e ti assicuro che noterai la differenza!)

    Originariamente inviato da TrueLies
    semmai, forse ti è sfuggita una altra cosa (ti vedo dell' umore di discutere di teoria, e a me sta bene e lo dico senza ironie!), che invece è singolare nel mio codice:
    inputPassword[++inputPassword.length-1]

    Noti nulla di strano?
    Beh se no n noti nulla, te lo rivelo io bastava scrivere: [inputPassword.length]
    Come mai prima incremento e poi decremento, operazione apparentemente futile?
    Sinceramente non capisco perché lo fai ... se pensi di preallocare la memoria sei sulla strada sbagliata.

  9. #9
    Cito: "Se non usi il metodo push sei costretto a leggere la proprietà length dell'array, che significa dispendio di processore"

    hai un benchmark di questa cosa? Voglio dire a prescindere dalla applicazione a cui fai riferimento, e che può avere specificità sue responsabili del fenomeno che accusi. Lo chiedo perchè, a regola, la lettura di una proprietà dovrebbe essere assai meno dispendiosa della invocazione di un metodo.

    Ottimo l' esempio di slice: mai usato su una HTMLCollection per cui figurati, non ero mai incorso nella cosa e ne ho imparata una nuova - oh non si finisce mai! Come mai in 12 anni questo fenomeno non mi abbia mai morso il sedere non lo so: probabilmente deve avere a che fare con il fatto che ho sempre manipolato le array di elementi DOM in place: gli swap avvenivano sempre sulla pagina, non prima altrove e poi sulla pagina.

  10. #10
    Utente di HTML.it L'avatar di carlomarx
    Registrato dal
    Oct 2009
    Messaggi
    1,669
    Hai risposto mentre scrivevo, per cui leggo solo ora...

    Originariamente inviato da TrueLies
    ora, purtroppo, esistono anche foo[0] foo[1] foo[2] ecc..., tutte equivalenti a undefined. E' come se io avessi scritto
    var foo= new Array();
    foo.length=8;
    ora foo ha 8 elementi validi, indirizzabili, ma che custodiscono valori undefined.
    La espressione ++inputPassword.length-1 ti fa capire che questo qui deve averci preso un tale picchio anni fa con questa caratteristica, che ancora se ne vedono le tracce di quanto teme gli ricapiti
    Un'array è un'insieme ordinato ma non per forza consecutivo;

    Se io scrivo:

    codice:
    var aMioArray = ["hello", "world"];
    aMioArray[15] = "!";
    Tra l'index n. 1 e l'index n. 14 non viene allocato un bel nulla! Se chiamo un indice inesistente ottengo sempre comunque come risultato undefined su qualsiasi array...:

    codice:
    alert(["hello", "world"][144]);

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.