Connexion
Ces billets correspondent à un filtre sur: W3C

HTML5 - L'attribut draggable

Après avoir évoqué l'attribut contentEditable d'HTML5, je vous propose cette fois de nous intéresser à l'API de drag and drop de cette prochaine version.

Présentation

L'attribut draggable peut être associé à n'importe quel élément HTML et placé à trois valeurs: 'false' (par défaut) , 'true' afin de rendre le déplacement possible et enfin 'auto' dont le comportement dépendra du navigateur. Il représente la mise en application de l'API de drag and drop d'HTML5.

Avec cet API et cet attribut, il existe un certain nombre d'évènements qui sont déclenchés par les actions de l'utilisateur et qui peuvent être écoutés pour exécuter des actions:

  • dragstart (ondragstart pour l'attribut HTML): qui se déclenche lorsqu'un drag and drop d'une zone est commencé.
  • drag (ondrag pour l'attribut HTML): déclenché pendant le déplacement (et donc potentiellement à répétition...).
  • dragenter (ondragenter pour l'attribut HTML): déclenché lorsqu'un drag and drop entre au dessus de la zone concernée.
  • dragleave (ondragleave pour l'attribut HTML): déclenché lorsqu'un drag and drop quitte la zone concernée.
  • dragover (ondragover pour l'attribut HTML): déclenché lorsqu'un drag and drop se situe au dessus de la zone concernée (et donc potentiellement à répétion...).
  • drop (ondrop pour l'attribut HTML): déclenché lorsqu'un élément en cours de déplacement est relaché au dessus de la zone concernée.
  • dragend (ondragend pour l'attribut HTML): déclenché lorsqu'un drag and drop a été réalisé ou annulé.

La preuve par l'exemple

Scénario de l'exemple

Afin de rendre tout ça plus "buvable" nous allons utilisez pour l'exemple un scénario très simple basé sur ces évènements et ces actions:

  1. L'utilisateur commence le déplacement d'une "boite" depuis une source de contenu représentée par une plus grosse "boite". Du coup l'évènement "dragstart" est déclenché pour cette boite. On ne s'occupera pas de l'évènement "drag" pour la suite.
  2. Il la déplace sur la page et arrive au dessus de la "boite" cible. L'évènement "dragenter" est déclenché par la cible.
  3. En déplaçant la petite "boite" au dessus de la cible, cette dernière déclence des évènements "dragover".
  4. L'utilisateur relâche la petite "boite" sur la cible qui déclenche l'évènement "drop". Cet évènement nous servira de référence pour retirer l'objet déplacé de sa source et le placer dans la cible de façon concrête.

Le code HTML

Nous allons créer 2 div qui nous serviront de source ('src') ou de cible ('tgt'). À l'intérieur de la boite 'src' nous aurons une petite boite nommée 'box' qui pourra être déplacée dans 'src'.

<!-- just a container -->
<div class="bordered">
    <!-- our drag source container -->
    <div class="half-width source" id="src">
        <!-- our box to drag and drop -->
        <div class="box" id="box"
             draggable="true">
            Simple Box 1
        </div>
    </div>
    <!-- our drag and drop target -->
    <div class="half-width target" id="tgt"></div>
</div>

Rien de plus simple jusque là. À noter toutefois, l'utilisation de l'attribut draggable à la valeur 'true' pour autoriser le déplacement de la boite 'box'.

CSS

Juste un peu de mise en forme et un 'hack' pour le moteur WebKit (Safari entre autres) nécessaire pour activer le drag and drop (cette situation ne saurait être définitive je pense car elle ne respecte pas la norme HTML5.)

.bordered {
    border: 1px solid #888888;
}
.half-width {
    float:left;
    width:50%;
    min-height:160px;
}
.target {
    background-color:#BFFF80;
}
.source {
    background-color:#FFDF80;
}
.box {
    background-color:#FF8080;
    margin:5px;
    padding:5px;
    border: 1px solid #888888;
    height:100px;
    width:100px;
    text-align:center;
}
*[draggable=true] {
    -khtml-user-drag: element; /* WebKit hack */
    cursor:move;               /* a move cursor */
    -moz-user-select:none;     /* disabled content selection
                                  on mozilla browsers */
}

dragstart

Comme expliqué plus haut, l'évènement dragstart se déclenche lorsqu'un drag and drop d'une zone est commencé. Nous allons donc associer à l'évènement dragstart de la boite à déplacer, la création de notre drag and drop.

/* on associe le démarrage du drag and drop à la fonction
   dragStartHandler */
document.getElementById('box').addEventListener("dragstart", dragStartHandler, false);

function dragStartHandler(event) {
    /* autoriser les drag and drop de type "copy" */
    event.dataTransfer.effectAllowed = 'copy';
    /* transmettre en donnée de drag and drop l'id de la boite
       déplacée */
    event.dataTransfer.setData('Text', event.target.id);
    return false;
}

dragenter

Cette fois-ci nous allons associer une fonction javascript à l'entrée dans la zone cible:

/* on associe l'entrée du drag and drop sur la cible à la fonction
   dragEnterHandler */
document.getElementById('tgt').addEventListener("dragenter", dragEnterHandler, false);

function dragEnterHandler(event) {
    /* éviter le comportement par défaut du navigateur (déplacement
       de sélection) */
    event.preventDefault();
    return false;
}

dragover

Ici nous nous intéressons à ce qu'il se passe lorsqu'on survole la cible. Conformément à ce que nous avons mis dans la fonction dragStartHandler nous allons donner au déplacement la zone la capacité à recevoir les drag and drop de type 'copy':

/* on associe le survole de la cible à la fonction
   dragOverHandler */
document.getElementById('tgt').addEventListener("dragover", dragOverHandler, false);

function dragOverHandler(event) {
    /* verification de la cible au cas où l'on survole un autre
       objet */
    if (event.target != document.getElementById('tgt')) {
        return false;
    } else {
        /* on attribue l'effet de curseur qui correspond au type
           accepté plus haut */
        event.dataTransfer.dropEffect = 'copy';
        /* éviter le comportement par défaut du navigateur
           (déplacement de sélection) */
        event.preventDefault();
    }
    return false;
}

drop

Nous y voilà. L'étape finale du déplacement et l'action de "relaché" plus communément appelée "drop" va être connectée à une fonction qui déplacera la zone déplacée dans la cible.

/* on associe le 'laché' d'un élément sur la cible à la fonction
   dropHandler */
document.getElementById('tgt').addEventListener("drop", dropHandler, false);

function dropHandler(event) {
    /* on se sert de l'id transporté en donnée pour déplacer
       l'élément dans son nouveau parent DOM */
    event.target.appendChild(document.getElementById(event.dataTransfer.getData('Text')));
    /* et voila, on a finit et pour s'assurer on coupe manuellement
       la propagation de l'évènement (pas forcément nécessaire !) */
    event.stopPropagation();
    return false;
}

Le résultat

Voila donc notre exemple prêt à marcher :

Simple Box 1

Références de l'article

Commentaires: 1 | Buzz it!

HTML5 - L'attribut contenteditable

Nouvelle série de billets liée à HTML5 et aux nouveautés apportées par le W3C (organisme qui gère les normes du World Wide Web) sur le langage le plus utilisée sur internet: HTML.

Si la norme HTML5 n'est pas encore publiée de façon définitive, le Working Draft publié en Janvier 2008 est toute fois supporté (de façon plus ou moins efficace) par la majorité des navigateurs web actuels (au moins les meilleurs).

Aujourd'hui, le but de l'article est d'appréhender un nouvel attribut, 'contenteditable', proposé par cette future norme.

Présentation

L'attribut 'contenteditable' peut être associé à un élément HTML (ou balise) et placé à deux valeurs: 'false' (par défaut) et 'true' afin d'en rendre l'édition possible. Cette édition se contonnant, sans autre artifice, à une modification locale. Il ne s'agit pas d'un attribut magique qui autoriserait à lui seul à rendre une page éditable pour que les modifications apportées soient ensuites visibles par toutes les personnes chargeant la même page. Toutefois, rien empêche de se servir de cet attribut à cette fin, mais ce sera au développeur de prévoir les échanges lorsqu'un changement est réalisé sur la page.

'contenteditable' est aussi associé à une valeur et un getter IDL (Interface Definition Language) du DOM (Document Object Model):

  • 'contentEditable' qui accepte les valeurs 'true' ou 'false'
  • 'isContentEditable' qui retourne les valeurs 'true' ou 'false'

Utilisation

Rien de plus simple, puisqu'il suffit de placer l'attribut et sa valeur dans la déclaration de la balise concernée pour la rendre éditable:

<p contenteditable="true">Lorem ipsum dolor...</p>

En concret:

Lorem ipsum dolor...

Afin de se servir des changements effectués, un certains nombre d'écouteurs peuvent être positionnés. Ceux-ci, réagissants aux évènements émis, peuvent ainsi renseigner sur l'état de l'élément HTML:

  • 'focus' au moment où l'utilisateur sélectionne une zone éditable par un click.
  • 'blur' au moment où l'utilisateur quitte la zone (après édition par exemple).

Que l'on peut par exemple écouter comme suit afin d'appeler la méthode 'store' lorsque l'élément 'element' est modifié:

editable = document.getElementById('element');
editable.addEventListener("blur", store, false);

Autour de cet attribut

L'attribut 'contenteditable' présenté plus tôt dans cet article accompagne d'autres attributs relativement liés à celui-ci

designMode

L'attribut IDL designMode accepte lui aussi deux valeurs. Mais ce sont 'on' et 'off' (par défaut) pour changer. Cet attribut, normalement associé à l'élément 'document.' permet de rendre modifiable l'intégralité d'un document HTML (ou page).

document.designMode = 'true';

spellcheck

'spellcheck' permet quant à lui permet d'activer ou de désactiver la correction orthographique ou grammaticale sur un élément d'une page. Utilisant les valeurs 'true' et 'false' et associé à l'attribut 'contenteditable' il permet de créer une zone d'édition efficace dans un élément non prévu initialement à cet effet.

element.spellcheck = 'true';

Tester

Afin que vous puissiez mieux comprendre comment marchent les attributs 'contenteditable' et 'spellcheck', j'ai réalisé une petite démo très simple: Tester ces attributs.

Plus d'info sur cet attribut sur le site du W3C.

Commentaires: 3 | Buzz it!

Ed4H4S, un éditeur HTML strict

Après quelques semaines où le projet a été mis en pause forcée, je vous propose la première version d'un petit éditeur maison qui propose certains raccourcis pour l'édition en ligne de code HTML 4.01 Strict.

En effet, ce n'est pas un éditeur "What You See Is What You Get" puisqu'il s'agit d'une zone de texte où le code HTML est clairement visible. Seule facilité lié au rendu final, une fonction de prévisualisation est intégrée aux boutons par défaut et permet d'afficher ce qui est édité sous forme interprétée.

Les besoins pour ce type d'outils peuvent être assez divers, de l'édition d'articles sur un blog à celle d'une plateforme de développement en ligne, sans oublier la rédaction d'email ou de réponses sur un forum.

Raccourcis

Le tout, en respectant les standards du W3C et en utilisant une syntaxe HTML 4.01 Strict. La liste de boutons est assez minimaliste mais devrait suffire à la majorité des cas d'utilisation :

  • Gras
  • Italique
  • Souligné
  • Titre de niveau 1
  • Titre de niveau 2
  • Titre de niveau 3
  • Paragraphe
  • Code
  • Lien hypertexte
  • Image
  • Liste ordonnée
  • Liste non ordonnée
  • Prévisualisation

Et cette liste peut être étendue à volonté sans trop de difficulté par l'intermédiaire d'un fichier JSON qui regroupe les bouton de la barre.

Licence

L'outil en lui même est basé sur du JavaScript et inclus un certain nombre d'icônes réalisées par Famfamfam qui se trouve sous licence Creative Commons Attribution 2.5 License. L'éditeur Ed4H4S est lui sous licence GPLv3.

Quelques liens pour finir :

Commentaires: 0 | Buzz it!