Détection et polyfill pour émuler mouseenter et mouseleave [JavaScript]

Il semblerait qu’à l’heure où j’écris ces lignes, les événements « mouseenter » et « mouseleave » ne soient pas encore supportés par la dernière version stable de Chrome (alors que FF16 et IE les supportent).
D’autres plus anciennes versions de Firefox peuvent aussi être impactées.
Mais heureusement il existe un polyfill pour ça.

Tout d’abord voici une fonction pour détecter si l’événement est supporté (source) :

// source: http://perfectionkills.com/detecting-event-support-without-browser-sniffing/
function isMouseEventSupported(eventName) {
  var el = document.createElement('div');
  eventName = 'on' + eventName;
  var isSupported = (eventName in el);
  if (!isSupported) {
    el.setAttribute(eventName, 'return;');
    isSupported = typeof el[eventName] == 'function';
  }
  el = null;
  return isSupported;
}

isMouseEventSupported("mouseenter"); // --> true ou false

Maintenant voici le polyfill :

// inspired by : http://blog.stchur.com/2007/03/15/mouseenter-and-mouseleave-events-for-firefox-and-other-non-ie-browsers/

// bindEvent is an easy way to create a native binding events
// @param {DOMElement} element The DOM element related to the event
// @param {String} eventName An event name just like 'click'
// @param {Function} fct The function that will be triggered by the event
function bindEvent(element, eventName, fct) {
  if (!element) throw new ErrorType("The element doesn't exist");
  
  if (element.addEventListener) {
    // if it's mouseenter or mouseleave, we want to check the compatibility
    if (eventName === "mouseenter" || eventName === "mouseleave") {
      if (!isMouseEventSupported(eventName)) {
        switch (eventName) {
          case "mouseleave": eventName="mouseout"; break;
          case "mouseenter": eventName="mouseover"; break;
        }
        fct=fixMouseEnter(fct);
      }
    }
    element.addEventListener(eventName, fct, false);
  }
  else
    element.attachEvent("on"+eventName, fct);
}

function fixMouseEnter(fct) {
  return function(evt) {
    var relTarget = evt.relatedTarget;
    if (this === relTarget || isChildOf(this, relTarget)) return;
    fct.call(this, evt);
  }
}
function isChildOf(parent, child) {
  if (parent === child) return false;
  while (child && child !== parent) child = child.parentNode
  return child === parent;
}

Voir tout le code JavaScript présent dans une page [Astuce]

Il peut arriver qu’on ait besoin de voir tout le code JavaScript d’une page dans un unique endroit. Pour cela vous pouvez utiliser ce bout de code. Grâce à la partie « bookmarklet » vous pouvez créer un nouveau marque-page et utiliser le code fourni comme URL du marque-page. Ensuite il suffit d’aller sur la page voulue et d’appeler le marque-page : cela ouvrira une nouvelle page avec tout le code JavaScript, qui sera « unminifié » grâce à jsbeautifier.org. Cependant, seuls les scripts qui sont sur le même domaine pourront être visualisés.

L’autocomplete des passwords ne fonctionne plus sur Firefox ? [Astuce]

Après un crash de mon ordinateur je me suis retrouvé avec Firefox qui ne remplissait plus mes zones « Password » sur les différents sites. Plutôt ennuyeux. Après une recherche j’ai trouvé qu’une option s’était décochée d’elle-même ! Il suffit d’aller dans les Options, onglet Sécurité, puis de vérifier que « Enregistrer les mots de passe » est bien coché.

Vertical scroll en JavaScript [programmation]

Si l’on souhaite faire un scroll vertical seulement pour accéder à un élément de notre page, alors on pourra utiliser :

window.scrollTo(document.documentElement.scrollLeft,document.getElementById('id-de-mon-element').offsetTop)

Autre solution (en repérant le conteneur qui a les scrollbar) :

document.getElementById('mon-conteneur').scrollTop = document.getElementById('id-de-mon-element').offsetTop

Pour que offsetTop retourne une valeur il faut que l’élément associé soit visible.

Un autocomplete/autosuggest simple, léger et efficace en JavaScript [programmation]

On trouve plusieurs programmes JavaScript pour l’auto-complétion, mais souvent ils sont lourds et proposent des listes déroulantes plus ou moins attrayantes.
Après quelques recherches je suis tombé sur Mo Autocomplete créé par un russe.

Une fois minifié, le code ne fait que 1423B, et son principe n’est pas d’afficher une liste sous le champ mais de compléter le mot directement dans le champ.
Ci-dessous une démo (tapez un mois de l’année en français) :

Et le code associé :

<input type="text" id="demo-autocomplete" autocomplete="array:months" />
<script>
/* autocomplete - http://momche.net/res/autocomplete/ */
var cAutocomplete={sDescription:"autcomplete class"};cAutocomplete.complete=function(hEvent){if(hEvent==null){var hEvent=window.hEvent}var hElement=(hEvent.srcElement)?hEvent.srcElement:hEvent.originalTarget;var sAA=hElement.getAttribute("autocomplete").toString();if(sAA.indexOf("array:")>=0){hArr=eval(sAA.substring(6))}else{if(sAA.indexOf("list:")>=0){hArr=sAA.substring(5).split("|")}}if(hEvent.keyCode==16){return}var sVal=hElement.value.toLowerCase();if(hEvent.keyCode==8||hEvent.keyCode==46){sVal=sVal.substring(0,sVal.length-1)}if(sVal.length<1){return}for(var nI=0;nI<hArr.length;nI++){sMonth=hArr[nI];nIdx=sMonth.toLowerCase().indexOf(sVal,0);if(nIdx==0&&sMonth.length>sVal.length){hElement.value=hArr[nI];if(hElement.createTextRange){hRange=hElement.createTextRange();hRange.findText(hArr[nI].substr(sVal.length));hRange.select()}else{hElement.setSelectionRange(sVal.length,sMonth.length)}return}}};cAutocomplete.init=function(){var a=0;var c=document.getElementsByTagName("INPUT");for(var a=0;a<c.length;a++){if(c[a].type.toLowerCase()=="text"){var b=c[a].getAttribute("autocomplete");if(b){if(document.attachEvent){c[a].attachEvent("onkeyup",cAutocomplete.complete)}else{if(document.addEventListener){c[a].addEventListener("keyup",cAutocomplete.complete,false)}}}}}};if(window.attachEvent){window.attachEvent("onload",cAutocomplete.init)}else{if(window.addEventListener){window.addEventListener("load",cAutocomplete.init,false)}};
var months=["Janvier","Février","Mars","Avril","Mai","Juin","Juillet","Août","Septembre","Octobre","Novembre","Décembre"];
cAutocomplete.init();
</script>

Avertissement de redirection sur Google [Astuce]

Depuis quelques jours, toutes mes recherches sur Google Images me retournaient un message disant :

Avertissement de redirection
La page que vous consultiez essaie de vous rediriger vers xxxx.
Si vous ne souhaitez pas consulter cette page, vous pouvez revenir à la page précédente.

Message pour le moins agaçant. C’est finalement en supprimant mes cookies que Google a arrêté de me montrer cet avertissement.

Récupérer les détails d’un utilisateur dans une masterpage [Sharepoint]

Il est assez simple de stocker dans un coin d’une masterpage les détails de l’utilisateur pour pouvoir ensuite les réutiliser. Pour cela vous devez rajouter une ligne au début de votre masterpage :

<%@ Register Tagprefix="SPSWC" Namespace="Microsoft.SharePoint.Portal.WebControls" Assembly="Microsoft.SharePoint.Portal, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

(Attention de bien mettre Version=14.0.0.0 si vous êtes sous Sharepoint 2010, et Version=12.0.0.0 pour Sharepoint 2007)

Maintenant, juste après la balise FORM, il faut ajouter cette ligne :

<form>
  <SPSWC:ProfilePropertyLoader runat="server"/>
  [...]

Voilà, vous pouvez désormais récupérer les informations de l’utilisateur. Il suffit de mettre le bloc suivant entre les balises FORM de votre masterpage :

   <div id="userDetails" style="display:none">
     <asp:LoginName runat="server" id="userLogin">
     <SPSWC:ProfilePropertyValue PropertyName="FirstName" ApplyFormatting="false" id="userFirstName" runat="server"/>
     <SPSWC:ProfilePropertyValue PropertyName="LastName" ApplyFormatting="false" id="userLastName" runat="server"/>
     <SPSWC:ProfilePropertyValue PropertyName="WorkEmail" ApplyFormatting="false" id="userWorkEmail" runat="server"/>
     <SPSWC:ProfilePropertyValue PropertyName="PreferredName" ApplyFormatting="false" id="userPreferredName" runat="server"/>
   </div>

Grâce à ça vous obtenez le nom complet, le username, le prénom, le nom et l’email de l’utilisateur courant.
On peut trouver d’autres propriétés à cette adresse:

Cross-browser solution to read a local file and return the Data URI in base64 [Javascript]

I searched for a solution to have a way to read a local file and then have the Base64 content returned into all the web browsers. The Javascript FileReader API exists for the modern browsers but not for Internet Explorer (IE). The solution is finally with Flash !

Look at the project on http://aymkdn.github.com/FileToDataURI/, and thanks to Country/FileToDataURI.as for the inspiration 🙂

Raccourcis pour SublimeText [Astuce]

Vous connaissez sûrement SublimeText : c’est un éditeur de texte très puissant, et parfait pour la programmation.

J’ai décidé de lister les commandes/raccourcis qui sont bien utiles :

  • CTRL + d : sélectionnez un mot puis faire CTRL+d pour voir les autres mots identiques être sélectionnés à leur tour à chaque nouvelle pression du raccourci, ce qui permet ensuite de modifier tous les mots sélectionnés d’un seul coup… à utiliser en collaboration avec CTRL+K+D qui permet de désélectionner le dernier mot identique et de sélectionner le suivant;
  • CTRL + SHIFT + UP/DOWN : permet de déplacer vers le haut ou vers le bas la ligne sur laquelle le curseur se trouve;
  • CTRL + SHIFT + P : va appeler une console rapide qui permet d’accéder aux fonctionnalités des menus… par exemple si vous voulez activer la syntaxe Javascript pour un nouveau fichier il suffit de faire CTRL+SHIFT+P et de taper « syntax javascript »;
  • CTRL + Clic : il est possible de placer plusieurs curseurs dans son document en maintenant CTRL et en cliquant, et lorsque vous tapez le texte apparait à la suite de tous les curseurs créés;

Tous les raccourcis sont décrits dans la documentation sur http://docs.sublimetext.info/en/latest/reference/keyboard_shortcuts_win.html