3D Home Architect Design Deluxe 8 discount software secure cheap software cheap adobe cs4 cheap soft buy windows 7 64 buy cheap adobe buy cheap windows 7 cheap CDLab Wincan 7.6 MultiLanguage buy buy cheap microsoft CoffeeCup Flash Photo Gallery 5.7 buy adobe cs4 WinRar 3.7 cheap adobe

Strani comportamenti di IE7 con jQuery

by Gianluca 10 settembre 2009 00.51

Da diverso tempo avevo notato che la funzione anti-aliasing di Internet Explorer 7 aveva un malfunzionamento nel rendering dei testi, quando questi venivano "nascosti" usando metodi jQuery come hide o fadeOut, poi visualizzati con chiamate a show o fadeIn. Beh, fino ad oggi non mi ero interessato poi così tanto alla cosa, stanco dell'ennesimo pelo nell'uovo diverso tra i vari IE, Firefox, Chrome e chi più ne ha più ne metta. Ma stasera ho deciso di voler approfondire il discorso. Ho trovato un grandioso articolo di Benjamin Michael Novakovic (http://blog.bmn.name/2008/03/jquery-fadeinfadeout-ie-cleartype-glitch/), che a quanto pare sembra essere l'unico depositario della soluzione al problema.

Ebbene, il Novakovic sostiene che causa di tutto sia l'attributo di stile filter, il quale, dichiarato o no nei propri fogli di stile, causa questo malfunzionamento del motore di anti-aliasing di IE7 sui testi processati tramite jQuery. Quindi la soluzione consiste nel trasformare eventuali chiamate a show o fadeIn, che originariamente appararianno come

$('#sample1').show('slow');

$('#sample1').fadeIn('slow');

in


$('#sample1').show('slow', function() {
   this.style.removeAttribute('filter');
});

$('#sample1').fadeIn('slow', function() {
   this.style.removeAttribute('filter');
});

Ho fatto diversi test (tra l'altro sputtanando per l'eternità il mio IE8 nel tentativo di installare una versione standalone di IE7...):

Effettivamente il codice del Novakovic sembra risolvere il problema. Sembra che con IE8 il problema non sussista, mentre con IE7 la differenza è palese.

UPDATE 13/09/2009

Dopo aver effettuato ulteriori test ho notato che applicando la soluzione di Novakovic, FireFox, ma soprattutto FireBug, si incazza di brutto, segnalando un errore Javascript e smettendo di rivolgerti la parola per l'intera giornata. Giustamente FireBug segnala la mancata definizione del metodo removeAttribute. Per questo motivo il codice corretto deve prevedere un controllo preliminare sul tipo di browser che sta eseguendo il codice. Il codice corretto diventerebbe quindi:


$('#sample1').show('slow', function() {
   if (jQuery.browser.msie)
		this.style.removeAttribute('filter');
});

$('#sample1').fadeIn('slow', function() {
   if (jQuery.browser.msie) 
		this.style.removeAttribute('filter');
});

Un "tester" interessante, che tra l'altro propone una versione più completa della soluzione, l'ho trovato qui: jQuery IE Fade Test

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Vota questo post per primo

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , , ,

Web

CSS e Javascript minification con ASP.NET

by Gianluca 11 agosto 2009 19.52

Chiunque abbia a che fare con la programmazione web si sarà reso conto che l'utilizzo dei CSS, così come l'utilizzo di framework javascript come jQuery, sia ormai praticamente uno standard de-facto.
Per quanto riguarda i framwork Javascript, questi vengono rilasciati costantemente sia in versione 'sources' che in versione 'minified', lasciando però la scelta del minifier da utilizzare esclusivamente ai creatori/mantainer del framework.
Purtroppo ho la smania di tenere costantemente tutto sotto controllo, ragion per cui negli ultimi mesi ho cominciato a studiare i vari software che operano la minification.
Sul web se ne trovano diversi:

Su tutti, la mia attenzione si è focalizzata molto su YUI Compressor, che a detta dei suoi sviluppatori

The YUI Compressor is JavaScript minifier designed to be 100% safe and yield a higher compression ratio than most other tools.

Dopo diversi test e diverse rilasci in produzione di fogli di stile e codice javascript minimizzato con questo tool, posso affermare di non aver mai riscontrato incompatibilità o problemi di sorta.
L'unico grande difetto di questo tool è il suo essere un tool da riga di comando, il che si traduce in una serie di step da eseguire in pre-produzione.
Se da un lato, le modifiche a queste tipologie di file, sono rare, una volta raggiunta la fase di rilascio, è pur vero che piccole migliorie vengono sempre apportate dopo il rilascio di una applicazione web.
Stanco quindi di aprire frequentemente il prompt dei comandi, ho cercato una soluzione da inglobare direttamente nei progetti web, che riuscisse a minimizzare on-the-fly i CSS e i JS.

Animato dall'esigenza e dalla scoperta di questo porting per .NET YUI Compresso for .NET, ho buttato giù questo semplice HttpHandler, capace di riconoscere le richieste giuste e rispondere con la versione minimizzata del file richiesto.

        using System;
        using System.Collections.Generic;
        using System.IO;
        using System.Linq;
        using System.Text;
        using System.Web;
        using Yahoo.Yui.Compressor;

        namespace Gianluca.Esposito.Web.Handlers
        {
            public class YUICompressor : IHttpHandler
            {
                private const int DEFAULT_CACHE_DURATION = 1440;
                private bool useCache = true;
                private bool noCompression = false;

                public bool IsReusable { get { return true; } }
                
                public void ProcessRequest(HttpContext context)
                {
                    bool.TryParse(context.Request.QueryString.Get("useCache"), out this.useCache);
                    bool.TryParse(context.Request.QueryString.Get("noCompression"), out this.noCompression);
                    context.Response.ContentType = "text/plain";
                    string filePath = GetFilePath();
                    string fileExtension = Path.GetExtension(filePath);
                    if (File.Exists(filePath))
                    {
                        context.Response.AddHeader("Content-Disposition", "filename=" + Path.GetFileName(filePath));
                        switch (fileExtension)
                        {
                            case ".css":
                                context.Response.ContentType = "text/css";
                                if (!this.noCompression) 
                                    CompressCSS(filePath);
                                else
                                    HttpContext.Current.Response.WriteFile(filePath);
                                break;
                            case ".js" :
                                context.Response.ContentType = "application/x-javascript";
                                if (!this.noCompression)
                                    CompressJavaScript(filePath);
                                else
                                    HttpContext.Current.Response.WriteFile(filePath);
                                break;
                            default :
                                context.Response.StatusCode = 404;
                                break;
                        }
                    }
                    else
                    {
                        context.Response.StatusCode = 404;
                    }
                    context.Response.Flush();
                    context.Response.End();
                }
                
                private string GetFilePath()
                {
                    string filePath = HttpContext.Current.Request.Url.AbsolutePath;
                    filePath = filePath.Remove(filePath.LastIndexOf(".axd"));
                    filePath = HttpContext.Current.Server.MapPath(filePath);
                    return filePath;
                }

                private void CompressCSS(string filePath)
                {
					HttpContext current = HttpContext.Current;
					string requestHash = current.Request.Url.AbsolutePath.GetHashCode().ToString();
                    if (this.useCache & current.Cache[requestHash] != null)
                    {
                        current.Response.Write((string)current.Cache[requestHash]);
                        return;
                    }
                    object fileLock = new object();
                    lock (fileLock)
                    {
                        StreamReader sr = new StreamReader(filePath, true);
                        string compressed = CssCompressor.Compress(sr.ReadToEnd());
                        current.Response.Write(compressed);
                        if (this.useCache)
                            current.Cache.Add(requestHash,
								compressed,
								null,
								DateTime.MaxValue,
								new TimeSpan(0, DEFAULT_CACHE_DURATION, 0),
								System.Web.Caching.CacheItemPriority.Normal,
								null);
                        sr.Close();
                    }
                }

                private void CompressJavaScript(string filePath)
                {
					HttpContext current = HttpContext.Current;
					string requestHash = current.Request.Url.AbsolutePath.GetHashCode().ToString();
                    if (this.useCache & current.Cache[requestHash] != null)
                    {
                        current.Response.Write((string)current.Cache[requestHash]);
                        return;
                    }
                    object fileLock = new object();
                    lock (fileLock)
                    {
                        StreamReader sr = new StreamReader(filePath, true);
                        string compressed = JavaScriptCompressor.Compress(sr.ReadToEnd());
                        current.Response.Write(compressed);
                        if (this.useCache)
                            current.Cache.Add(requestHash,
								compressed,
								null,
								DateTime.MaxValue,
								new TimeSpan(0, DEFAULT_CACHE_DURATION, 0),
								System.Web.Caching.CacheItemPriority.Normal,
								null);
                        sr.Close();
                    }
                }
            }
        }
    

L'handler va ovviamente mappato nel web.config. Devo però fornire una doverosa annotazione: nel mio caso ho mappato le estensioni *.js.axd e *.css.axd. Questa scelta mi obbliga a dover fare attenzione nelle pagine .aspx o .html che creo, in quanto i riferimenti ai fogli di stile ed ai file javascript devono finire con questa estensione per essere processati. In un contesto di hosting condiviso (leggi Aruba), dove non ho possibilità di intervento sulle estensioni mappate in IIS, questa mi sembrava la scelta migliore. In contesti di maggior libertà di mapping delle estensioni in IIS, sarebbe bastato mappare le estensioni .css e .js sull'engine di ASP.NET, e mappare le stesse estensioni sull'handler.

Come si evince dal codice, l'handler utilizza anche la cache in modo da evitare di processare i singoli file ad ogni richiesta, ma solo quando strettamente necessario.

Una ulteriore aggiunta potrebbe essere l'utilizzo di chiavi negli appSettings, in modo da controllare l'abilitazione globale dell'handler direttamente da web.config, ma lo lascio fare a voi, mentre mi godo il fresco di questo temporalone estivo :)

Aggiornamento 07/06/2010: Qui una versione modificata delle DLL per farle girare in Medium Trust (Aruba)

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Valutato 1.0 da 1 utenti

  • Currently 1/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , , ,

ASP.Net 2.0 | ASP.NET 3.5 | C# | Web

jMonthCalendar, un calendario mensile molto interessante

by Gianluca 20 luglio 2009 23.49

jMonthCalendar è un plugin per jQuery nato per soddisfare alcune esigenze di visualizzazione di eventi ed informazioni temporali. Nell'aspetto è simile ad un planner mensile, poi facilmente personalizzabile utilizzando i fogli di stile CSS. Anche l'utilizzo risulta molto semplice: è sufficiente inizializzare il calendario specificandone le opzioni ed un array di eventi. E' inoltre totalmente compatibile con tutti i browser, l'ho testato al volo su Firefox 3.5, Google Chrome 2 ed Internet Explorer 8 senza riscontrare anomalie. Tra le principali caratteristiche:

  • supporto multi eventi/giorno
  • primo giorno della settimana personalizzabile
  • supporto AJAX

Il plugin è stato sviluppato da Kyle LeNeau, ed è disponibile per il download sotto licenza MIT. Per tutte le informazioni ed i download è possibile consultare la pagina http://code.google.com/p/jmonthcalendar/

 

Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Vota questo post per primo

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

Web | jQuery

Offrimi un caffè
Microsoft Certified Technology Specialist
Microsoft Certified Professional Developer