Gli ultimi mesi hanno visto una diffusione capillare del framework Bootstrap, una libreria CSS/JS che consente di dotare qualsiasi sito web di tutte le funzionalità necessarie per rendere le proprie pagine mobile-friendly e, cosa ancor più importante, pienamente compatibili con tutti i device. Il Framework, oggi giunto alla versione 3.3.1, è dotato di una serie di plugin javascript che richiedono JQuery v1.9.0 o superiore: è quindi facile immaginare come si sia diffuso principalmente sui siti che includono quest'ultimo, i quali non di rado ospitano anche JQuery UI.
Utilizzare questi due framework insieme è possibile, ma occorre fare attenzione ad almeno due conflitti presenti tra le due librerie e che rischiano di produrre errori JS e/o di compromettere alcune funzionalità del sito. Si tratta dei plugin tooltip e button, entrambi presenti (con il medesimo nome) in ciascuna delle librerie.
Il Problema.
Prendiamo come esempio il plugin tooltip. Andiamo sul sito http://jqueryui.com/tooltip/ e diamo un'occhiata al codice di esempio (view source) per la creazione di un tooltip con JQuery UI:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>jQuery UI Tooltip - Default functionality</title> <link rel="stylesheet" href="//code.jquery.com/ui/1.11.2/themes/smoothness/jquery-ui.css"> <script src="//code.jquery.com/jquery-1.10.2.js"></script> <script src="//code.jquery.com/ui/1.11.2/jquery-ui.js"></script> <link rel="stylesheet" href="/resources/demos/style.css"> <script> $(function() { $( document ).tooltip(); }); </script> <style> label { display: inline-block; width: 5em; } </style> </head> <br> |
Il testo evidenziato presenta una chiamata alla funzione tooltip che JQuery UI aggiunge a livello runtime per ogni oggetto JQuery. La stessa operazione viene effettuata da Bootstrap come si può vedere analizzando il codice del relativo tutorial:
1 |
$('#example').tooltip(options) |
Questo conflitto di nomi, oltre ad impedire a entrambi i plugin di funzionare, provoca una serie di errori Javascript variabili a seconda di quale libreria viene eseguita prima. Nel caso in cui Boostrap sia inserito dopo JQuery UI, ad esempio, l'errore che vedremo nella nostra Console Javascript sarà con tutta probabilità il seguente:
Uncaught TypeError: Cannot read property 'documentElement' of null
Dovuto al fatto che la sintassi del plugin di JQueryUI, solitamente utilizzato a livello di $(document), viene utilizzata per eseguire il plugin di Bootstrap.
La Soluzione.
Il modo migliore per far convivere le due librerie risolvendo "in positivo" i conflitti di nomi è utilizzare il plugin $.widget.bridge che consente di poter ridefinire a piacimento questi ultimi. Il plugin è fortunatamente incluso all'interno di JQuery UI, quindi non appesantirà ulteriormente il nostro sito. Il suo utilizzo è molto semplice:
1 2 3 |
// Change JQueryUI plugin names to fix name collision with Bootstrap. $.widget.bridge('uitooltip', $.ui.tooltip); $.widget.bridge('uibutton', $.ui.button); |
Queste istruzioni vanno ovviamente inserite nella pagina in modo sincrono dopo aver incluso il riferimento alla libreria JQueryUI e prima dello script di Bootstrap. Nell'esempio seguente vediamo un esempio completo di implementazione nel blocco <head> di una pagina web:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<html> <head> <title>My JqueryUI + Boostrap page</title> <script type="text/javascript" src="cdn/or/local/path/to/jquery.ui.js"></script> <script type="text/javascript"> // Change JQueryUI plugin names to fix name collision with Bootstrap. $.widget.bridge('uitooltip', $.ui.tooltip); $.widget.bridge('uibutton', $.ui.button); </script> <script type="text/javascript" src="cdn/or/local/path/to/bootstrap.js"></script> </head> <body> [...] </body> </html> |
In conseguenza di questa operazione i metodi tooltip e button diventeranno una prerogativa di Bootstrap, mentre per utilizzare gli omonimi plugin offerti da JQuery UI sarà necessario utilizzare i nuovi alias uitooltip e uibutton.
Riferimenti:
http://stackoverflow.com/a/27745464/1233379 (la mia risposta sul sito StackOverflow che ha ispirato questo post).