Pages

samedi 31 décembre 2011

Stop aux liens qui s'ouvrent grâce à javascript !

Il n'y a rien de plus énervant pour moi qu'un lien qui s'ouvre en java-script. J'ai pour habitude en lisant un article ou certains sites d'annonces d'ouvrir les liens potentiellement intéressants dans un nouvel onglet.
Ceux s'ouvrant en java-script sont une vraie plaie ! Ils ouvrent une page blanche et quelle horreur de constater qu'après un quart d'heure de recherche, toutes mes annonces dûment sélectionnées sont ouvertes sur le néant. Obligé de tout recommencer, ça fait vraiment ch**r -_-.
Et c'est un vrai parcours du combattant pour l'ouvrir dans un onglet :
  1. ouvrir le lien
  2. copier l'url (Ctrl+L, Ctrl+C)
  3. retour en arrière (Ctrl+gauche ou Alt+gauche)
  4. ouvrir un nouvel onglet (Ctrl+T)
  5. aller sur la page copier (Ctrl+Shift+V ou Ctrl+V, Entrée)
  6. revenir sur les annonces (Ctrl+Tab, ou Ctrl+Shift+Tab)
6 étapes pour un pauvre onglet en arrière-plan…

Alors par pitié, mettez un vrai lien, pas un bout de javascript.

mercredi 28 décembre 2011

Charger des pages avec ajax sans gêner les utilisateurs n'ayant pas javascript

Le but d'un site chargeant ces pages avec ajax est de diminuer la charge du serveur en ne demandant que le contenu principal (pas de menu, footer et autres contenus inchangés). Ceci pour une navigation plus rapide.
Le problème apparaît quelquefois au niveau de l'historique et si ce n'est pas pensé, impossible d'accéder à une page via son url. Quant à ceux n'ayant pas java-script ‑moteur de recherche compris‑ il est totalement impossible de visiter le site.

Le premier problème peut se corriger avec history.pushState ou la lib history.js qui permet de normaliser d'un navigateur à l'autre et utilise des ancres pour les vieux navigateurs (ceux ne supportant pas HTML5).

Le second problème est tout simple, il suffit d'indiquer une page complète et ajouter un paramètre dans l'url pour les utilisateurs ayant java-script. Si ce paramètre existe la page ne renvoie que le contenu principal, il ne reste plus qu'à remplacer l'ancien par le nouveau.

Par exemple avec un lien sur ma_page.php qui retourne une page complète.
On intercepte l'événement click. On ajoute un paramètre, par exemple 'ajax', ce qui donne ma_page.php?ajax puis on charge cette page. Le serveur ne renvoie que le contenu, on ajoute ma_page.php dans l'historique et on remplace l'ancien contenu par le nouveau.
De plus, il serait de bon ton d'indiquer le chargement quelque part, c'est perturbant de ne rien voir :).

vendredi 23 décembre 2011

int[2] comment_retourner_un_tableau();

Vous est-il déjà arrivé de vouloir retourner un tableau de n valeur ?
Un prototype du genre int[2] f(); ?
Et là, c'est le drame, un expected unqualified-id before ‘[’ token empêche de compiler.

La meilleure solution est de retourner un objet. Le plus simple étant std::array du C++0x ou boost::array. Un std::vector fera aussi l'affaire ;).

Une autre solution est de retourner un pointeur. Niveau typage c'est pas le top : on perd l'information sur la taille. Mais pourquoi pas.
Attention quand même ! Regardez bien l'exemple suivant :
int* f()
{
 int a[] = {0,1,2,3,4};
 return a;
}

int main()
{
 int* a = f();
 std::cout << a[2] << ',';
 a[2] = 0;
 int* a2 = new int[5];
 std::cout << a[2] << std::endl;
 return 0;
}
À première vue, rien de bien dangereux. Cependant le compilo nous dit warning: address of local variable ‘a’ returned. Étrange erreur, c'est pourtant ce que l'on veut…
En exécutant le binaire celui-ci affiche quelque chose comme : 3,12812616681
Pourquoi ? Tout simplement parce que 'a' pointe sur une mémoire non allouée, ou pour être plus précis dés-allouée. Bah oui, 'a' en sortant de la fonction f est détruit, mais cela n'empêche pas de retourner son pointeur… vers un espace mémoire libre. Le compilateur nous avait prévenu ;).

En réalité f devrait ressembler à
int* f()
{
 int* a = new int[5];
 a[0] = 0;
 a[1] = 1;
 a[2] = 2;
 a[3] = 3;
 a[4] = 4;
 return a;
}
Mais pour éviter les fuites mémoires, ne pas oublier delete[]. Si on veut retourner un pointeur il sera peut-être préférable de retourner un pointeur intelligent, au moins le delete sera automatique.
On revient à la phrase du début, le plus simple reste le retour d'un objet.

std::array<5, int> f()
{
 return {{0,1,2,3,4}};
}

jeudi 22 décembre 2011

jQuery(context).find(expr) vs jQuery(expr, context)

Saviez-vous que $(this).find(".truc") est l'équivalent de $(".truc", this) ?
Mais saviez-vous que le second exemple appelle le premier ;) ?
Maintenant oui ! Alors préférer le premier, ça ne sera que plus performant.