Écrit par Neil Deakin
.
Traduit par Laurent Jouanneau (11/11/2004), mise à jour par Alain B. (04/04/2007) .
Attention : Ce tutoriel est ancien et n'est pas mis à jour. Bien que beaucoup d'informations soient encore valables pour les dernières versions de gecko, beaucoup sont aussi obsolètes. Il est préférable d'aller consulter cette page sur la version française de ce tutoriel sur developer.mozilla.org.
Attention, cette page est maintenue dans la version française, mais elle a été enlevée par son auteur sur la version anglaise.
Cette section décrit l'utilisation d'un conteneur JavaScript pour le glisser-déposer.
Le conteneur JavaScript pour le glisser-déposer simplifie le processus en appelant toutes les interfaces XPCOM pour vous. Il fonctionne en fournissant un objet qui implémente les gestionnaires d'événements. Tout ce que vous avez à faire est d'écrire quelques fonctions simples qui travaillent sur les données qui sont glissées.
L'interface glisser-déposer est stockée dans le paquetage "global", dans le fichier chrome://global/content/nsDragAndDrop.js
. Vous pouvez inclure ce fichier dans votre
fichier XUL avec la balise script
de la même manière que pour
vos scripts. La bibliothèque dépend aussi d'autres scripts, que vous aurez également à inclure,
habituellement au début de votre page XUL. Vous pouvez regarder le contenu de ces fichiers pour
voir comment fonctionne le glisser-déposer au plus bas niveau.
Notez que vous ne pouvez utiliser ces bibliothèques qu'à l'intérieur de fichiers XUL chargés avec un URL chrome.
<script src="chrome://global/content/nsDragAndDrop.js"/>
<script src="chrome://global/content/nsTransferable.js"/>
Cette bibliothèque glisser-déposer crée un objet stocké dans la variable nsDragAndDrop
.
L'objet contient une série de fonctions, une pour chaque gestionnaire d'événements (excepté
pour dragenter
où il n'y a rien de spécial à faire). Chacune de ces fonctions
prend deux arguments : le premier est l'objet event
et le second est un
objet observateur que vous créez. Vous trouverez plus d'explications par la suite.
L'exemple suivant est un exemple d'appel de l'objet nsDragAndDrop
:
<button label="Glissez-moi" ondraggesture="nsDragAndDrop.startDrag(event,buttonObserver);" />
La fonction startDrag
sera appelée quand le glisser-déposer débutera à partir du bouton.
Le premier paramètre est l'objet event
, disponible dans tous les gestionnaires d'événements.
Le second paramètre de cette fonction est l'observateur, que nous créerons bientôt.
Dans cet exemple, nous ne faisons rien d'autre quand débute le glisser du bouton.
Si nous voulions aussi prendre en compte les autres cas, nous pourrions appeler les autres
fonctions, comme dans l'exemple suivant :
<description value="Cliquez et glissez ce texte."
ondraggesture="nsDragAndDrop.startDrag(event,textObserver)"
ondragover="nsDragAndDrop.dragOver(event,textObserver)"
ondragexit="nsDragAndDrop.dragExit(event,textObserver)"
ondragdrop="nsDragAndDrop.drop(event,textObserver)"/>
Comme mentionné plus haut, rien n'est spécialement à faire pendant l'événement
dragenter
, aussi pouvez-vous l'écrire vous-même.
Les fonctions sont implémentées par l'objet nsDragAndDrop
, qui est déclaré
dans le fichier nsDragAndDrop.js
inclu par l'une des balises
script
.
Elles prennent en charge les événements, les appels aux interfaces XPCOM et passent une
structure de données simple aux fonctions de l'objet observateur.
L'observateur est un objet que vous déclarez vous-même. Dans les exemples ci-dessus, cet
observateur est stocké dans les variables buttonObserver
et textObserver
.
L'observateur est déclaré dans un script que vous devez inclure dans votre fichier XUL avec
la balise script
.
Il doit avoir un certain nombre de propriétés, chacune
s'occupant d'un aspect particulier du glisser-déposer. Cinq fonctions peuvent être définies.
Vous pouvez simplement définir celles dont vous avez besoin.
onDragStart (event , transferData, action)
event
qui a été passé au
gestionnaire d'événement, les données à transférer, le type d'action du glisser.
Cette fonction doit ajouter les données à transférer à l'objet transferData
.onDragOver (event, flavour, session)
event
,
le deuxième est le type de donnée et le troisième l'objet de session du glisser qui fournit
plus de détails sur le glisser-déposer en cours. Vous devez définir cette fonction
pour les éléments qui autorisent la dépose de données « glissées » sur eux-mêmes.onDragExit (event, session)
event
et la session
du glisser-déposer.onDrop (event, dropData, session)
event
et le
deuxième est la donnée qui était glissée. Le troisième argument est la session du
glisser-déposer.getSupportedFlavours ( )
Pour un observateur lié à un élément qui peut débuter un glisser-déposer, vous
devriez définir au moins la fonction onDragStart
. Pour les éléments
qui peuvent recevoir des objets glissés, vous devriez définir onDragOver
,
onDrop
et getSupportedFlavours
(et si vous le voulez,
onDragExit
).
Le type des données pouvant être glisser-déposer est stocké comme un ensemble de type. Souvent, un objet glissé peut être disponible dans un certain nombre de types. Ce faisant, un élément cible peut accepter le type qu'il trouve le mieux adapté. Par exemple, un fichier peut être transmis dans deux types, le fichier lui-même et son nom. Si le fichier est glissé et déposé sur un répertoire, le type 'fichier' sera utilisé. Si le fichier est glissé sur un champ de saisie, le type 'nom de fichier' sera utilisé. Le texte du nom du fichier est par conséquent utilisé quand les fichiers ne peuvent être déposés directement.
Un type d'objet a un nom, qui est formaté comme un type MIME, comme text/unicode.
À l'intérieur de la fonction onDragStart
, vous spécifiez quels types
sont disponibles pour l'élément en cours de glisser-déposer. Pour ce faire, ajoutez les
données et les types à l'objet transferData
, qui est le deuxième argument de
onDragStart
.
L'exemple ci-après devrait vous aider. La fonction onDragStart
ajoute
des données à l'objet transferData
.
var textObserver = {
onDragStart: function (evt , transferData, action){
var htmlText="<strong>Cabbage</strong>";
var plainText="Cabbage";
transferData.data=new TransferData();
transferData.data.addDataForFlavour("text/html",htmlText);
transferData.data.addDataForFlavour("text/unicode",plainText);
}
};
Ici, un observateur a été déclaré et stocké dans la variable textObserver
.
Il a une propriété appelée onDragStart
(en JavaScript, les propriétés peuvent
être déclarées avec la syntaxe nom : valeur
).
Cette propriété est une fonction qui définit les données qui seront transférées.
Une fois appelé, il commence le glisser-déposer pour la chaîne Cabbage. Bien sûr,
vous voudrez calculer cette valeur à partir de l'élément sur lequel on a cliqué.
Cet élément est disponible dans la propriété target
de l'objet event
.
Cet objet event
est passé en premier argument à onDragStart
.
Nous créons un objet transferData
qui peut être utilisé pour contenir
toutes les données à transférer. Nous ajoutons deux données à celui-ci. La première
est une chaîne de texte HTML et la seconde une chaîne de texte brut.
Si l'utilisateur dépose sur une zone qui accepte le HTML (comme la fenêtre d'édition HTML
de Mozilla), le type HTML sera utilisé et le texte apparaîtra en gras. Sinon, c'est la
version en texte brut qui sera utilisée.
En général vous devrez fournir une version texte de la donnée, ainsi de nombreuses applications pourront l'accepter. L'ordre dans lequel vous définissez les types devra s'établir de la meilleure correspondance vers la moins bonne. Dans le cas ci-dessus, le type HTML (text/html) vient en premier, et le type texte (text/unicode) en second.
L'exemple ci-dessous montre comment spécifier les données à transférer à partir
de l'attribut label
de l'élément. Dans ce cas, nous
fournissons la donnée dans un seul type.
var textObserver = {
onDragStart: function (evt){
var txt=evt.target.getAttribute("label");
transferData.data=new TransferData();
transferData.data.addDataForFlavour("text/unicode",txt);
}
}
Il peut être utile lors de l'implémentation du glisser-déposer pour les cellules d'un arbre. Vous pouvez utiliser la valeur d'une cellule, ou d'une ressource du fichier RDF si l'arbre est construit à partir d'un gabarit (template), comme valeur pour le glisser-déposer. Si vous la stockez dans une chaîne, n'importe quel objet acceptant les chaînes pour un glisser-déposer pourra récupérer cette valeur.
Vous aurez besoin d'ajouter un observateur à chaque élément qui peut soit démarrer
une action glisser-déposer, soit accepter des objets glissés. Vous pouvez réutiliser
le même observateur sur plusieurs éléments. Pour un élément qui démarre un
glisser-déposer, vous devez simplement implémenter onDragStart
.
Pour un élément sur lequel on peut déposer, l'observateur aura besoin d'implémenter
au moins les fonctions getSupportedFlavours
, onDragOver
et
onDrop
. Certains éléments pourraient être capables d'initier un glisser et
d'accepter un déposer. Dans ce cas, onDragStart
sera également nécessaire.
La fonction getSupportedFlavours
doit retourner une liste de types
que peut accepter pour une dépose l'élément sur lequel le glisser-déposer s'effectue.
Une vue d'un répertoire de système de fichiers pourrait accepter des fichiers et peut-être du texte,
mais ne devrait pas accepter du texte HTML. Ci-dessous, nous définissons la fonction
getSupportedFlavours
. Ici, nous n'autorisons qu'un seul type.
var textObserver = {
getSupportedFlavours : function () {
var flavours = new FlavourSet();
flavours.appendFlavour("text/unicode");
return flavours;
}
}
La liste des types de données contient un seul type, qui est text/unicode.
L'objet FlavourSet
peut être utilisé pour contenir une liste de types.
Dans certains cas, vous devez aussi fournir une interface XPCOM. Par exemple,
pour les fichiers :
var textObserver = {
getSupportedFlavours : function () {
var flavours = new FlavourSet();
flavours.appendFlavour("application/x-moz-file","nsIFile");
flavours.appendFlavour("text/unicode");
return flavours;
}
}
La fonction onDragOver
définit ce qui se produit lorsqu'un objet est
glissé au-dessus. Vous pourriez alors changer l'apparence des éléments qui sont
survolés. Dans la plupart des cas, la fonction ne fait rien. Cependant elle doit être
définie pour les éléments qui acceptent des données glissées.
Ensuite, la fonction onDrop
doit être créée. Son second argument
est l'objet de transfert de données qui contient les données transférées. Avant
d'appeler onDrop
, le conteneur aura appelé getSupportedFlavours
pour déterminer le meilleur type de données à déposer, aussi l'objet de transfert
ne contient que les données du meilleur type déterminé.
L'objet de transfert a deux propriétés : data
qui contient la donnée
et flavour
qui contient le type de la donnée. Une fois que vous avez
la donnée, vous pouvez l'ajouter à l'élément de n'importe quelle façon. Par exemple,
vous pourriez modifier la valeur d'un champ de saisie.
var textObserver = {
onDrop : function (evt, transferData, session) {
event.target.setAttribute("value",transferData.data);
}
}
Le système de type utilisé permet à de multiples objets, de types variés, d'être glisser-déposer. Il permet également à des formes alternatives de données d'être utilisées. Le tableau suivant décrit quelques types de données que vous pourriez utiliser. Vous pouvez aussi définir votre propre type si nécessaire.
text/unicode | Text data |
text/html | données HTML |
application/x-moz-url | une URL |
application/x-moz-file | Un fichier local |
Dans la prochaine section, nous étudierons un exemple utilisant le glisser-déposer.
Mozilla® est une marque déposée de la fondation Mozilla.
Mozilla.org™, Firefox™, Thunderbird™, Mozilla Suite™ et XUL™
sont des marques de la fondation Mozilla.