Visualizzazione post con etichetta Javascript. Mostra tutti i post
Visualizzazione post con etichetta Javascript. Mostra tutti i post

10 maggio 2010

Browser.Engine : distinguere i Browser con mootools

I mootools tra la miriade di funzionalità, ci permette di individuare la versione del browser mediante la classe Browser.

Un classico esempio di distinzione tra i browser possiamo vederla nel seguente esempio.


var BE = Browser.Engine;
if (!this.BE.webkit && !this.BE.gecko && !this.BE.trident){
// firefox 3.6 bug
BE = Browser.Engines;
}
if (BE.webkit) {
alert ("webkit : Safari, Google Chrome, Konqueror";
}
if (BE.gecko) {
alert ("gecko : Firefox, or any Mozilla Browser";
}
if (BE.trident) {
alert ("trident : Internet Explorer";
}

Come potete vedere nell'esempio nel caso in cui si tratti di firefox 3.6, visto che l'oggetto Broser.Engine.gecko non è definito (undefined), è stato fixato con un workaround, utilizzando l'oggetto Browser.Engines.gecko per intercettare il browser.

08 aprile 2009

Scrolling fluido sugli anchor usando i Mootools

Una delle funzionalità implementate dai more dei mootools-more è quella legata al modulo SmoothScroll.
I mootools infatti hanno prestato parecchia attenzione allo sviluppo delle funzionalità legata al “Fx” all'interno del proprio framework.

Gli ancoraggi all'interno delle pagine HTML sono molto importanti, permettono infatti di poter accedere in maniera istantanea a determinati contenuti sommersi della marea di informazioni contenute nella pagina.

Un altro esempio di ancoraggio è quello che permette di poter accedere al "top" della pagina senza dover forzare l'utente a dover scrollare per tutta la lunghezza della stessa. Il problema è che in maniera nativa questa funzionalità è troppo istantanea, infatti la pagina esegue un salto immediato che trasmette all'utente una sorta di risveglio immediato da quello che può essere il relax trasmesso della pagina.

Per questo in questo post si vuole suggerire un modo mediante cui eseguire uno scrolling fluido e graduale della pagina quando si clicca sugli ancoraggi.

La potenza stà nel fatto che l'html da inserire nella pagina è lo stesso che inseriremmo in una normale situazione di utilizzo degli ancoraggi.
Esempio;
<a href="#top" >Top</a>


Questo è il codice da inserire nella vostra pagina per ottenere l'effetto desiderato su tutti gli ancoraggi.
window.addEvent('load', function() { new SmoothScroll({ duration: 1800 }); }); 


E' necessario importare all'interno della pagina 2 file javascript:
- Il core dei mootools
- il more dei mootools contenente il plugin Asset
I 2 files sono disponibili qui (core) e qui (more).
<script type="text/javascript" language="JavaScript" src="http://www.franziale.netsons.org/src/js/mootools/mootools-1.2.1-core-nc.js"></script>
<script type="text/javascript" language="JavaScript" src="http://www.franziale.netsons.org/src/js/mootools/mootools-1.2-more.js"></script>

E' possibile trovare un esempio di questa funizionalità a questo link Ancoraggi fluidi

30 marzo 2009

Chiamare Javascript da filmato Flash

Potrebbe risultare utile dover chiamare una funzione javascript da un filmato flash.
Tale azione può essere associata ad un evento o richiamata alla fine dell'esecuzione del filmato in base alle esigenze dello sviluppatore.

Di seguito potete trovare un esempio di actionScript da includere in un qualunque frame del vostro flash:

function runJS(script:String):Void {
getURL("javascript:" + script + "");
}

var js = "var doc = document.URL; alert(doc);";
runJS(js);

Nell' esempio viene richiamata la funzione alert, ma è possibile richiamare qualsiasi funzione dichiarata nel documento.
Questo risulterà senz'altro utile per chi ha a che fare con entrambe le tecnologie all'interno della propria applicazione web.

10 gennaio 2009

Importare dinamicamente un file css o js all'interno del body

Una limitazione nell'inclusione dei fogli di stile css mediante l'utilizzo del tag html <link> consiste nel fatto che lo stesso debba essere incluso all'interno del tag <head> affinchè gli stili inclusi possano essere utilizzati dal browser.
Nel caso in cui si voglia includere un file css in un qualsiasi punto della pagina, ad esempio nel <body>, magari associando l'inclusione ad un determinato evento o ad una determinata condizione risulterebbe impossibile se non ci venisse in contro il framework Javascript : MooTools.

E' possibile mediante questa classe includere anche file javascript a runtime, così come per i file css.
E' necessario importare all'interno della pagina 2 file javascript:
- Il core dei mootools
- il more dei mootools contenente il plugin Asset
I 2 files sono disponibili qui (core) e qui (more).
<script type="text/javascript" language="JavaScript" src="http://www.franziale.netsons.org/src/js/mootools/mootools-1.2.1-core-nc.js"></script>
<script type="text/javascript" language="JavaScript" src="http://www.franziale.netsons.org/src/js/mootools/mootools-1.2-more.js"></script>

Il passo successivo è quello di utilizzare all'interno della pagina il seguente codice:
// include un file css a runtime
var myCSS = new Asset.css("style.css");
// include un file javascript a runtime
var myJS = new Asset.javascript("jsdefinition.js");

Di seguito è presente il codice per poter gestire la stampa del javascript per la chiamata ai metodi dei mootools mediante una classe PHP.
/**
* Classe Boundary per la gestione della stampa
* @author a.franzi
*/
class MooTools{

/**
* Metodo per recuperare la chiamata al metodo della classe Asset dei mootools per
* importare un file css a runtime (quindi non necessariamente nell'head della pagina)
*
* @param $cssFile : path al file css
* @return : stringa javaScritpt contenente la chiamata al metodo della clase
* Asset dei mootools
*/
public static function getAssetCss($cssFile){
// nel caso in cui non si voglia usare un nome univoco , è possibile decommentare questa riga
// ed eliminare la seguente
//return "var myCss = new Asset.css('".$cssFile."');";
return "var myCss".Random::string()." = new Asset.css('".$cssFile."');";
}
/**
* Metodo per stampare la chiamata al metodo della classe Asset dei mootools per
* importare un file css a runtime (quindi non necessariamente nell'head della pagina)
*
* @param $cssFile : path al file css
*/
public static function printAssetCss($cssFile){
echo self::getAssetCss($cssFile);
}
/**
* Metodo per recuperare la chiamata al metodo della classe Asset dei mootools per
* importare un file js a runtime
*
* @param $cssFile : path al file js
* @return : stringa javaScritpt contenente la chiamata al metodo della clase
* Asset dei mootools
*/
public static function getAssetJs($jsFile){
// nel caso in cui non si voglia usare un nome univoco , è possibile decommentare questa riga
// ed eliminare la seguente
//return "var myJs = new Asset.javascript('".$jsFile."')";
return "var myJs".Random::string()." = new Asset.javascript('".$jsFile."')";
}
/**
* Metodo per stampare la chiamata al metodo della classe Asset dei mootools per
* importare un file js a runtime
*
* @param $cssFile : path al file js
* @return : stringa javaScritpt contenente la chiamata al metodo della clase
* Asset dei mootools
*/
public static function printAssetJs($jsFile){
echo self::getAssetJs($jsFile);
}
}

Attenzione : nel codice si fà riferimento alla classe Random la cui implementazione è possibile recuperarla sul post Generazione valori random in php.
Sicuramente questo post sarà utile a coloro, come nel mio caso utilizzino un controller per la gestione centralizzata dell'inclusione di file js e file css.

02 dicembre 2008

Recuperare un oggetto Javascript senza problemi (in popup, frame, etc..)

Chiunque ami o odi Javascript può trovarsi ad un problema del tipo : "Litigare con la gerarchia degli oggetti oggetti del documento per poterne individuare uno" come ad esempio window.parent.window.opener.document..... A volte questo lavoro è talmente arduo da indurre il programmatore a ridurre la propria pazienza in brandelli.
La perdita di tempo può notevolmente aumentare quando ad esempio si utilizzano popup o frame.
Però una soluzione esiste....

Il sottoscritto non adora dover incorrere 2 volte nello stesso problema, così mi sono creato una funzione alla quale dare in pasto il nome dell'oggetto da recuperare e il nome del primo oggetto non nullo da cui far partire la nostra ricerca.
Ecco il codice :
function takeObject(){                                                             
objReceived = searchElement("window","objtoFind");
if (objReceived == null){
alert ('non trovato');
}else{
alert(objReceived.value);
}
}

var ArrayFramesToJump = ["onbeforeunload","onafterprint","top",
"location","parent","offscreenBuffering","frameElement",
"onerror","screen","event","clipboardData","onresize","defaultStatus",
"onblur","window","onload","onscroll","screenTop","onfocus","Option",
"length","onbeforeprint","frames","self","clientInformation","external",
"screenLeft","opener","onunload","document","closed","history","Image",
"navigator","status","onhelp","name"];

String.prototype.endsWith = function(str)
{return (this.match(str+"$")==str)}

Array.prototype.contains = function (element) {
for (var i = 0; i < this.length; i++) {
if (this[i] == element) {
return true;
}
}
return false;
}


function searchElement (lastNotNull,divName){

eval ("var last = "+lastNotNull+";");
// DEBUG : alert(lastNotNull);
if (last){
// document (non posso concatenare 2 document)
if (!lastNotNull.endsWith("document")){
eval("var docum = "+lastNotNull+".document;");
if (docum!=null){
if (docum.getElementById(divName)!=null){
alert (lastNotNull+".document.getElementById('"+divName+"')");
return docum.getElementById(divName);
}else{
var objReceived = searchElement(lastNotNull+".document",divName);
if (objReceived !=null){
return objReceived;
}
}
}
}
// parent (evito di avere 2 parent per non incorrere in problemi ma
// potenzialmente è possibile che ce ne siano 2)
eval("var par = "+lastNotNull+".parent;");
if (lastNotNull.indexOf('parent') == -1){
if (par!=null){
var objReceived = searchElement(lastNotNull+".parent",divName);
if (objReceived !=null){
return objReceived;
}
}
}
// window (non posso concatenare 2 window
eval("var windo= "+lastNotNull+".window;");
if (!lastNotNull.endsWith("window")){
if (windo!=null){
var objReceived = searchElement(lastNotNull+".window",divName);
if (objReceived !=null){
return objReceived;
}
}
}
// opener
eval("var ope= "+lastNotNull+".opener;");
if (ope!=null){
var objReceived = searchElement(lastNotNull+".opener",divName);
if (objReceived !=null){
return objReceived;
}
}

// tutti i frame fratelli
if (lastNotNull.endsWith("parent")){
eval("var frameset= "+lastNotNull+".frames;");
if (frameset){
// se esiste il frameset
for (var framecurr in frameset) {
if (!ArrayFramesToJump.contains(framecurr)){
var currframeObj = frameset[framecurr];
if (currframeObj!=null){
// se ho intercettato il frame
var objReceived = searchElement(lastNotNull+".frames['"+framecurr+"']",divName);
if (objReceived !=null){
return objReceived;
}
}
}
}
}
}
}
return null;
}

// richiamo la funzione
takeObject();


Come si può notare la funzione esegue ricorsivamente la ricerca dell'oggetto, senza ingappare in loop infiniti visto che in Javascript ad esempio è possibile utilizzare window.window oppure window.parent.window.parent.
Il risultato è il riferimento all'oggetto nel caso venga trovato o null per un esito negativo della ricerca.
Spero sia utile a farvi risparmiare un sacco di tempo.

25 novembre 2008

Interpetare il Javascript incluso in un DIV mediante innerHTML con Ajax

Una classica modalità di utilizzo di Ajax è quella in cui in maniera asincrona viene chiamata una pagina (jsp,aspx,php,..) la quale alla fine della propria esecuzione restituisce al controller Ajax l'html ottenuto.
Nella maggiorparte dei casi si tende ad utilizzare tale html per visualizzare nella pagina chiamante il risultato ottenuto in un DIV senza dover ricaricare la pagina.
Un problema in cui si incorre in questa tipologia di approccio è rappresentato dall'interpretazione da parte del browser del javascript che può essere contenuto in questa pagina inclusa all'interno del DIV.
Il problema stà nel fatto che il browser, carica i javascript man mano che carica la pagina, quando in maniera asincrona si và a "riempire" un div mediante la proprietà innerHTML, il browser non si preoccupa di caricare i javascript contenuti.

A volte, quando non si ha la necessità di dover generare gli script in maniera dinamica, è possibile ovviare a tale problema includendo il codice all'interno della pagina principale. In altri casi è necessario costruire gli script in maniera dinamica, quindi può essere davvero utile adottare la seguente strategia per poter risolvere il problema.
Il sorgente seguente rappresenta la pagina principale.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Pagina senza titolo</title>
<script type="text/javascript" src="../js/libreria.js"></script>
<script language="javascript" type="text/javascript">
// <!CDATA[

function Button1_onclick()
{
//faccio la richiesta alla pagina php o jsp che restituisce
//<p>Ciao</p><_script language=\"javascript\">alert('pippo')</_script>
ajax("a.asp", onload);
function onload()
{
//t contiene la risposta
var t = this.request.responseText;

//execJS esegue javascript contenuto in t e restituisce
//t senza javascript
t = execJS(t);

//finalmente metto t 'pulito' dento il div
$("div1").innerHTML = t;

}
}



// ]]>
</script>
</head>
<body>
<input id="Button1" type="button" value="button" onclick="return Button1_onclick()" />
<div id="div1"></div>
</body>
</html>


La funzione javascript execJS è definita così:
function execJS(t)
{
var p1 = 0, p2 = 0, p3 = 0, p4 = 0;
p1 = t.indexOf("<" + "script", 0);
if(p1 == -1) return t;

p2 = t.indexOf(">", p1 + 7) + 1;
p3 = t.indexOf("<" + "/script>", p2);
p4 = p3 + 9;

var c = t.substring(p2, p3);
var s = document.createElement("script");
s.type = "text/javascript";
s.text = c;
document.getElementsByTagName("head")[0].appendChild(s);

t = t.substring(0, p1) + t.substr(p4);
return execJS(t);

}

Inserire solo numeri in un Input Text

Ecco un piccolo javascript tramite il quale permettere ad una textbox di accettare solamente cifre durante la digitazione.

function isNumberKey(evt){
var charCode = (evt.which) ? evt.which : event.keyCode
if (charCode > 31 && (charCode < 48 || charCode > 57))
return false;

return true;
}


Questo script può essere utilizzando in maniera semplicissima all'interno del tag HTML nel seguente modo:
<input type="text" name="codice" maxlength="7" size="8" onkeypress="return isNumberKey(event)">

Stampare in Javascript il contenuto di un DIV

Ecco un utile funzione per stampare il contenuto di un solo div mediante la funzione window.open di javascript.

Il codice da utilizzare è il seguente:
<script>
function printDiv()
{
var a = window.open('','','width=300,height=300');
a.document.open("text/html");
a.document.write(document.getElementById('foo').innerHTML);
a.document.close();
a.print();
}
</script>
<div id="foo">stuff to print</div>
<input type="button" onclick="printDiv()" value="print div">

10 novembre 2008

Javascript, aggiungere options ad una selectbox

Una problematica classica di chiunque utilizzi javascript è quella di dover aggiungere delle option alle selectbox.
E' possibile facilitarsi il compito creando delle opportune funzioni alle quali passando l'id della select box e un elenco (in questo caso map da cui recuperare le opzioni da inserire nella select box esistente aggiorna la textbox senza dover ricaricare la pagina.
Queste funzioni sono utilissime qualora si stessero utilizzando framework Ajax come ad esempio Dwr. In tal caso è sufficiente richiamarle come postback di una chiamata asincrona mediante Ajax.

Ecco un esempio di un metodo che svolge questo compito:
 // metodo per aggiornare qualsiasi tipo di elenco di options
// per id si intende l'id della selectbox
function addOptionValues(_id,_map){
var sel = document.getElementById(_id);
var opt = null;
if(sel != null){
for(var prop in _map) {
opt=document.createElement("option");
opt.setAttribute("value",prop);
opt.appendChild(document.createTextNode(_map[prop]));
sel.appendChild(opt);
}
}
}


Una possibile estensione è la seguente, in cui oltre a specificare l'elenco delle opzioni da aggiungere, ne seleziona una specifica il cui valore viene passato in input :
// metodo per aggiornare qualsiasi tipo di elenco di options selezionandone una
// per id si intende l'id della selectbox
function addOptionValuesSel(_id,_map,selez){
var sel = document.getElementById(_id);
var opt = null;
if(sel != null){
for(var prop in _map) {
opt=document.createElement("option");
opt.setAttribute("value",prop);
if (prop == selez){
opt.setAttribute("selected","selected");
}
opt.appendChild(document.createTextNode(_map[prop]));
sel.appendChild(opt);
}
}
}

Recuperare parametri da QueryString con Javascript

In Javascript può essere utile un metodo per recuperare un determinato parametro da QueryString. Vediamo come poter scrivere una funzione javascript che invocata con il nome del parametro ci restiruisce il valore associato.

// recuperare parametro query string
function queryString(parameter) {
var loc = location.search.substring(1, location.search.length);
var param_value = false;

var params = loc.split("&");
for (i=0; i< params.length;i++) {
param_name = params[i].substring(0,params[i].indexOf('='));
if (param_name == parameter) {
param_value = params[i].substring(params[i].indexOf('=')+1)
}
}
if (param_value) {
return param_value;
}
else {
return false; //Nel caso in cui nn ci siano parametri
}
}

31 ottobre 2008

Riconoscere funzionalità e verisione dei browser con javascript

Chiunque abbia mai utilizzato un linguaggio di scripting client side come Javascript ad un livello medio-avanzato, si sarà trovato di fronte al problema della compatibilità del codice scritto da parte del motore javascript del proprio browser.
In questo caso è stato sicuramente necessario distinguere diversi comportamenti in base alle diverse funzionalità attive nel browser.

Ecco un esempio di distinzione di tali funzionalità e versioni del browser.
// recupero le informazioni del browser
var AgntUsr=navigator.userAgent.toLowerCase();

// controllo se il browser utilizza i dom
var DomYes=document.getElementById?1:0;

// controllo se il browser è firefox
var NavYes=AgntUsr.indexOf('mozilla')!=-1&&AgntUsr.indexOf('compatible')==-1?1:0;

// controllo se il browser è explorer
var ExpYes=AgntUsr.indexOf('msie')!=-1?1:0;

// controllo se il browser è opera
var Opr=AgntUsr.indexOf('opera')!=-1?1:0;

// controllo se si tratta di una versione di opera maggiore o uguale alle 6
var Opr6orless=window.opera && navigator.userAgent.search(/opera.[1-6]/i)!=-1 //DynamicDrive.com added code

// controllo se viene utilizzato il modello dom di firefox
var DomNav=DomYes&&NavYes?1:0;

// controllo se viene utilizzato il modello dom di explorer
var DomExp=DomYes&&ExpYes?1:0;

// controllo se si utilizza una versione di firefox che non utilizza i dom
var Nav4=NavYes&&!DomYes&&document.layers?1:0;

// controllo se si utilizza una versione di exlorer che non utilizza i dom
var Exp4=ExpYes&&!DomYes&&document.all?1:0;

// controllo se la versione di explorer è la 7
var ie7 = ExpYes&&typeof document.body.style.maxHeight != "undefined"?1:0;

// controllo se la versione di explorer è la 6
var ie6 = ExpYes&&!ie7?1:0;

Naturalmente chi volesse segnalare altri generi di controlli lo faccia e questi verranno aggiunti.