Projet 2 jQuery
Sommaire
- 1- Objectifs
- 2- Présentation
- 2.1- Description
- 2.2- Tâches
- 3-
- Création de la page et du wrapper du plugin
- 3.1- Explication
- 4-
- Génération du balisage sous-jacent
- 4.1- Explication
- 5-
- Ajout de gestionnaires d'événements pour la réception de fichiers à télécharger
- 5.1- Explication
- 6-
- Affichage de la liste des fichiers sélectionnés
- 6.1- Explication
- 7-
- Retrait de fichiers de la liste de téléchargement
- 7.1- Explication
- 8-
- Ajout d'un indicateur de progression de l'interface utilisateur jQuery
- 8.1- Explication
- 9-
- Téléchargement des fichiers sélectionnés
- 9.1- Explication
- 9.1.1- Sommaire du cours jQuery
Barre latérale à position fixe avec défilement animé
-
Objectifs
- Utiliser Jquery pour créer une barre latérale à position fixe avec défilement animé
-
Présentation
-
Description
- Dans ce tutoriel nous allons, créer un widget de téléchargement de fichiers complet avec HTML5 et jQuery.
- Nous pouvons facilement ajouter la prise en charge de fonctionnalités avancées telles que les téléchargements multiples et une interface de glisser-déposer, et avec juste un peu d’aide de jQuery.
- Nous pouvons également ajouter des fonctionnalités d’interface utilisateur attrayantes telles que des informations détaillées sur les fichiers et des commentaires de progression.
- Ce qui suit est une capture d’écran qui montre le résultat final de ce projet:
-
Tâches
- Pour terminer ce projet, nous devrons effectuer les tâches suivantes:
- Création de la page et du wrapper de plugin
- Génération du balisage sous-jacent
- Ajout de gestionnaires d’événements pour la réception de fichiers à télécharger
- Affichage de la liste des fichiers sélectionnés
- Retrait de fichiers de la liste de téléchargement
- Ajout d’un indicateur de progression de l’interface utilisateur jQuery
- Téléchargement de l’élément sélectionné files
- Reportage du succès et rangement
- Création de la page et du wrapper du plugin
- Dans cette tâche, nous allons créer la page qui établit un lien vers les ressources requises, ainsi que l’ajout de l’encapsuler dans lequel notre plugin vivra.
- La nouvelle page doit être liée à la feuille de style de l’interface utilisateur jQuery afin que nous obtenions le style requis par le widget Progressbar, ainsi que la feuille de style pour ce projet dans le <head> de la page, directement après le lien existant vers css:
- Tout ce dont notre plugin aura besoin est un conteneur dans lequel le widget peut restituer le balisage requis. Dans le <body> de la page.
- En plus de créer un lien vers le fichier de script qui contient le code de notre plugin, nous devrons également appeler le plugin afin de l’initialiser. Directement après l’existant <script>
- L’encapsuleur du plugin est une construction simple que nous utiliserons pour initialiser le widget. Dans uploader.js, ajoutez le code suivant:
-
Explication
- l’élément <script> que nous ajoutons au bas de l’élément <body> appelle notre méthode de plugin afin d’invoquer le plugin, c’est ainsi que quelqu’un qui utilise notre plugin l’invoquerait
- Dans notre script fichier, nous commençons avec un point-virgule et une fonction anonyme immédiatement invoquée. Le point-virgule prend en charge la nature modulaire des plugins jQuery et protège notre plugin des autres plugins qui n’arrêtent pas l’exécution correctement.
- Si un autre plugin utilisé sur la page ne termine pas sa déclaration ou expression finale par un point-virgule, et que nous ne démarrons pas notre plugin par un point-virgule, cela peut produire des erreurs de script qui empêchent notre plugin de fonctionner.
- Nous utilisons une fonction anonyme comme enveloppe pour notre plugin et l’invoquons immédiatement avec un jeu de parenthèses supplémentaire après le corps de la fonction. Nous pouvons également nous assurer que notre plugin fonctionne avec la méthode
noConflict()
de jQuery en scopant localement le caractère$
dans notre plugin et en passant l’objet jQuery dans la fonction anonyme comme argument. - Dans la fonction anonyme, nous définissons d’abord un littéral d’objet appelé
defaults
qui sera utilisé comme objet de configuration pour notre plugin. Cet objet contient un autre objet appelé chaînes, qui est l’endroit où nous stockons tous les différents bits de texte qui sont affichés dans divers éléments. - Génération du balisage sous-jacent
- Dans cette tâche, nous allons ajouter une méthode d’initialisation à notre plugin qui générera le balisage requis dont le widget a besoin
- Tout d’abord, nous devons ajouter le code suivant directement après la fonction
constructeurUp()
dans projet02.js: - Nous devons également appeler cette méthode
new init()
. Modifiez la méthode ajoutée aufnobject
de jQuery afin qu’elle apparaisse comme suit: - Nous pouvons également ajouter le CSS pour le balisage généré par le plugin. Dans projet02.css, ajoutez le style suivant:
-
Explication
- Nous pouvons ajouter une méthode
init()
qui prend soin de créer et d’injecter le balisage à partir duquel le widget est construit en l’ajoutant au prototype de notre constructeur. Tous les objets créés par le constructeur hériteront de la méthode. - Nous stockons d’abord l’objet
this
, qui à l’intérieur de la méthodeinit()
fait toujours référence à la collection d’éléments jQuery, afin que nous puissions facilement y faire référence à l’intérieur des gestionnaires d’événements, que nous ajouterons dans la tâche suivante. - Nous étendons également localement la propriété
strings
pour rendre la résolution légèrement plus rapide, car nous nous référons fréquemment à cette propriété afin d’ajouter les chaînes de texte visibles à l’interface utilisateur visible du widget. - Ensuite, nous créons les nouveaux éléments HTML et stockons chacun d’eux dans des variables. Cela signifie que nous pouvons créer le conteneur et y ajouter tous les éléments requis pendant qu’il est encore en mémoire, puis injecter le widget entier dans le DOM de la page en une seule fois, au lieu de modifier à plusieurs reprises le DOM et d’ajouter les éléments un par un .
- Le conteneur externe du widget est un élément
<article>
qui a un nom de classe pour un style facile. La spécification HTML5 décrit un<article>
en tant que widget interactif autonome, donc je pense que c’est le conteneur parfait pour notre widget. Bien que tout aussi pertinent, le<article>
ne se limite pas à ce que nous qualifierions traditionnellement d ‘ »article » – par exemple, un blog / une nouvelle ou un article de style éditorial. - Nous avons un
<header>
élément pour contenir l’en-tête principal du widget, dans lequel nous utilisons un standard<h1>
. Nous utilisons également deux éléments<h1>
à l’intérieur du widget pour afficher les différentes sections (la zone de glisser-déposer et le fichier plus traditionnel - L’élément
<input>
a un attribut type de fichier et reçoit également le multiple attribut, en utilisant la méthode jQueryprop()
, afin que plusieurs fichiers puissent être téléchargés dans les navigateurs compatibles. - Nous ajoutons également un élément
<a>
directement après la<input>
, que nous utiliserons pour ouvrir la boîte de dialogue Ouvrir utilisée pour sélectionner les fichiers à télécharger. Le problème avec le typefile
standard<input>
, c’est qu’il n’y a pas de standard! - Ajout de gestionnaires d’événements pour la réception de fichiers à télécharger
- Nous pouvons utiliser la méthode
init()
que nous avons ajoutée dans la dernière tâche pour attacher les gestionnaires d’événements dont notre widget aura besoin pour gérer les fichiers sélectionnés pour le téléchargement. Cela peut se produire soit lorsque des fichiers sont déposés sur la cible de dépôt, soit lorsqu’ils sont sélectionnés à l’aide du bouton. - Directement après avoir ajouté les nouveaux éléments HTML au conteneur à la fin de la méthode
init()
dans projet02.js (mais toujours dans la méthodeinit()
), ajoutez le code suivant: -
Explication
- Nous utilisons d’abord la méthode
on()
de jQuery, en mode délégation d’événement, pour attacher un gestionnaire d’événements au conteneur externe du widget. Nous spécifions l’événementclick
comme premier argument et un sélecteur qui correspond à notre bouton avec le nom de classeup-choose
comme second argument. - Dans la fonction de gestionnaire passée à
on()
comme troisième argument, nous empêchons d’abord le comportement par défaut de le navigateur en utilisantpreventDefault()
de JavaScript, puis déclencher un événement de clic pour l’élément caché<input>
utilisé pour sélectionner les fichiers à télécharger. Cela entraînera l’ouverture de la boîte de dialogue Fichier dans le navigateur et permettra la sélection des fichiers. - Nous avons ensuite attaché un autre gestionnaire d’événements. Cette fois, nous recherchons les événements de drop, dragover, et change.
- L’événement drop sera déclenché lorsque des fichiers sont déposés dans la zone drop, l’événement dragover sera déclenché pendant que les fichiers sont maintenus sur la zone drop et l’événement change sera déclenché si des fichiers sont supprimés.
- Affichage de la liste des fichiers sélectionnés
- Dans cette tâche, nous pouvons remplir le
<div>
nous avons créé afin d’afficher la liste des fichiers qui ont été sélectionnés pour le téléchargement. Nous allons construire un tableau où chaque ligne du tableau répertorie un seul fichier avec des informations telles que le nom et le type du fichier. - Directement après la méthode
init ()
dans projet02.js, ajoutez le code suivant: - Nous pouvons également ajouter du CSS supplémentaire pour le nouveau balisage que nous avons créé. Ajoutez le code suivant au bas de projet02.css:
-
Explication
- Nous avons commencé par ajouter la méthode
handleFiles()
au prototype du widget, en faisant fonctionner la méthode appelwidget.handleFiles()
que nous avons ajoutée à la fin de la dernière tâche. Il a été ajouté exactement de la même manière que la méthodeinit()
plus tôt, et tout comme dansinit()
, cet objet pointe vers l’instance du widget à l’intérieur dehandleFiles ()
. Cela facilite l’accès à l’élément sur la page, aux options de configuration et à la liste de fichiers sélectionnée. - À l’intérieur de la méthode, nous avons d’abord créé une série de variables. Comme dans la méthode
- init()
- Retrait de fichiers de la liste de téléchargement
- Dans cette tâche, nous allons ajouter les gestionnaires d’événements qui feront fonctionner les liens Supprimer et Supprimer tous les éléments de la nouvelle liste de fichiers. Nous pouvons attacher les gestionnaires d’événements au même endroit que nous avons ajouté d’autres gestionnaires d’événements plus tôt pour garder les choses organisées.
- Dans projet02.js, dans la méthode
init()
du widget et directement après les appels existants à la méthodeon()
de jQuery, ajoutez le nouveau code suivant: -
Explication
- Ajout d’un indicateur de progression de l’interface utilisateur jQuery
- Dans cette tâche, nous allons ajouter les éléments et le code d’initialisation requis par le widget jQuery UI Progressbar. Le widget ne fera rien pour le moment car nous ne téléchargerons rien avant la prochaine tâche, mais nous devons tout câbler prêt.
- Nous allons ajouter une méthode
initProgress()
au prototype de notre widget pour sélectionner le<div>
les éléments que nous avons ajoutés à l’élément et les convertissons en widgets Progressbar. Nous pouvons également ajouter la méthode qui sera utilisée pour mettre à jour les Progressbars. - Directly after
thehandleFiles()
method, add the following code: - Ensuite, nous devrons appeler cette méthode après avoir ajouté de nouvelles lignes à
<table>
. Ajoutez l’appel suivant à notre nouvelle méthode à la fin de la méthodehandleFiles()
: - Nous pouvons maintenant ajouter le code qui met à jour la barre de progression. Ajoutez le code suivant directement après la méthode
initProgress()
que nous venons d’ajouter - Nous avons également besoin d’un tout petit peu de CSS pour les nouvelles barres de progression. Ajoutez le code suivant à la fin de
uploader.css
: -
Explication
- Téléchargement des fichiers sélectionnés
- Nous avons maintenant une liste de fichiers attachés à l’instance de notre plugin prêts à être téléchargés. Dans cette tâche, nous ferons exactement cela et téléchargerons les fichiers de manière asynchrone à l’aide de jQuery. Ce comportement sera lié au bouton Télécharger les fichiers que nous avons ajouté au balisage généré par le plugin.
- Nous pouvons également utiliser cette tâche pour mettre à jour nos barres de progression avec la progression actuelle de chaque fichier en cours de téléchargement.
- Comme il s’agit d’un autre gestionnaire d’événements, nous l’ajouterons dans la méthode
init()
avec tous les autres gestionnaires d’événements afin qu’ils soient tous conservés au même endroit. Ajoutez le code suivant à la fin de la méthodeinit()
, après les gestionnaires d’événements existants: - Ajoutez ensuite la méthode
new uploadFiles ()
. Cela peut aller après les méthodes liées au progrès que nous avons ajoutées dans la dernière tâche: -
Explication
……………….
;(function ($) {
var defaults = {
strings: {
title: "Up - A jQuery uploader",
dropText: "Drag files here",
altText: "Or select using the button",
buttons: { choose: "Choose files",
upload: "Upload files" },
tableHeadings: [ "Type", "Name", "Size", "Remove all x"
]
}
}
function Up(el, opts) {
this.config = $.extend(true, {},
defaults, opts);
this.el = el;
this.fileList = [];
this.allXHR = [];
}
$.fn.up = function(options) {
new Up(this, options);
return this; };
}(jQuery));
Up.prototype.init = function() {
var widget = this,
strings = widget.config.strings, container = $("<article/>", { "class": "up" }),
heading = $("<header/>").appendTo(container),
title = $("</h1>", { text: strings.title }).appendTo(heading),
drop = $("</div>", {
"class": "up-drop-target", html: $("</h2>",
{ text: strings.dropText }) }).appendTo(container),
alt = $("</h3>", { text: strings.altText }).appendTo(container),
upload = $("</input>",
{ type: "file" }).prop("multiple", true).appendTo(container),
select = $("", { href: "#", "class": "button up-choose",
text: strings.buttons.choose }).appendTo(container),
selected = $("</a>", { "class": "up-selected" }).appendTo(container),
upload = $("", { href: "#", "class": "button up-upload",
text: strings.buttons.upload }).appendTo(container);
widget.el.append(container);
}
$.fn.up = function(options) {
new Up(this, options).init(); return this;
};
article.up {
width:90%;
padding:5%;
}
article.up input {
display:none;
}
.up-drop-target {
height:10em;
border:5px dashed #ccc;
border-radius:5px;
margin-bottom:1em;
text-align:center;
}.up-drop-target h2 {
margin-top:-.5em;
position:relative; top:50%;
}.up-selected {
margin:1em 0;
border-bottom:1px solid #ccc;
}
widget.el.on("drop change dragover", "article.up", function(e) {
if (e.type === "dragover") {
e.preventDefault();
e.stopPropagation();
return false;
} else if (e.type === "drop") {
e.preventDefault();
e.stopPropagation();
widget.files = e.originalEvent.dataTransfer.files;
} else {
widget.files = widget.el
.find("input[type='file']")[0]
.files;
}
widget.handleFiles();
});
Up.prototype.handleFiles = function() {
var widget = this, container = widget.el.find("div.up-selected"),
row = $("</tr>"), cell = $("</td>"), remove = $("</a>", { href: "#" }),
table;
if (!container.find("table").length) { table = $("</table>");
var header = row.clone().appendTo(table),
strings = widget.config.strings.tableHeadings;
$.each(strings, function(i, string) {
var cs = string.toLowerCase().replace(/\s/g, "_"),
newCell = cell.clone()
.addClass("up-table-head " + cs)
.appendTo(header); if (i === strings.length - 1) {
var clear = remove.clone()
.text(string)
.addClass("up-remove-all");
newCell.html(clear).attr("colspan", 2);
} else { newCell.text(string); }
});
} else {
table = container.find("table");
}
$.each(widget.files, function(i, file) {
var fileRow = row.clone(),
filename = file.name.split("."),
ext = filename[filename.length - 1],
del = remove.clone() .text("x")
.addClass("up-remove"); cell.clone()
.addClass("icon " + ext) .appendTo(fileRow);
cell.clone() .text(file.name).appendTo(fileRow);
cell.clone() .text((Math.round(file.size / 1024)) + " kb")
.appendTo(fileRow);
cell.clone().html(del).appendTo(fileRow);
cell.clone().html("<div class='up-progress'/>")
.appendTo(fileRow);
fileRow.appendTo(table);
widget.fileList.push(file);
});
if (!container.find("table").length) {
table.appendTo(container);
}
}
.up-selected table { width:100%; border-spacing:0; margin-bottom:1em;}
.up-selected td { padding:1em 1% 1em 0;
border-bottom:1px dashed #ccc; font-size:1.2em;}
.up-selected td.type { width:60px; }
.up-selected table { width:100%; border-spacing:0; margin-bottom:1em;}
.up-selected td { padding:1em 1% 1em 0;
border-bottom:1px dashed #ccc; font-size:1.2em;}
.up-selected td.type { width:60px; }
.up-selected td.name { width:45%; }
.up-selected td.size { width:25%; }
.up-selected td.remove_all_x { width:20%; }
.up-selected tr:last-child td { border-bottom:none; }
.up-selected a { font-weight:bold; text-decoration:none;}
.up-table-head { font-weight:bold; }
.up-remove-all { color:#ff0000; }
.up-remove { display:block; width:17px; height:17px;
border-radius:500px; text-align:center;
color:#fff; background-color:#ff0000;}
.icon { background:url(../img/page_white.png) no-repeat 0 50%; }
.doc, .docx { background:url(../img/doc.png) no-repeat 0 50%; }
.exe { background:url(../img/exe.png) no-repeat 0 50%; }
.html { background:url(../img/html.png) no-repeat 0 50%; }
.pdf { background:url(../img/pdf.png) no-repeat 0 50%; }
.png { background:url(../img/png.png) no-repeat 0 50%; }
.ppt, .pptx { background:url(../img/pps.png) no-repeat 0 50%; }
.txt { background:url(../img/txt.png) no-repeat 0 50%; }
.zip { background:url(../img/zip.png) no-repeat 0 50%; }
, nous créons une variable locale appelée widget qui stocke l’objet this
. Nous n’ajouterons aucun gestionnaire d’événements à cette méthode, nous n’avons donc pas à le faire, mais nous accédons à l’objet plusieurs fois, il est donc logique de le mettre en cache dans une variable.
widget.el.on("click", "td a", function(e) {
var removeAll = function() {
widget.el.find("table").remove();
widget.el.find("input[type='file']").val("");
widget.fileList = []; }
if (e.originalEvent.target.className == "up-remove-all") {
removeAll();
} else {
var link = $(this),
removed,
filename = link.closest("tr") .children() .eq(1).text();
link.closest("tr").remove(); $.each(widget.fileList, function(i, item) {
if (item.name === filename) {
removed = i; }
});
widget.fileList.splice(removed, 1);
if (widget.el.find("tr").length === 1) {
removeAll(); }
}
});
Up.prototype.initProgress = function() {
this.el.find("div.up-progress").each(function() {
var el = $(this);
if (!el.hasClass("ui-progressbar")) {
el.progressbar(); }
});
}
widget.initProgress();
Up.prototype.handleProgress = function(e, progress) {
var complete = Math.round((e.loaded / e.total) * 100);
progress.progressbar("value", complete);
}
.up-progress { height:1em; width:100px; position:relative; top:4px; }
widget.el.on("click", "a.up-upload", function(e) {
e.preventDefault();
widget.uploadFiles();});
Up.prototype.uploadFiles = function() {
var widget = this, a = widget.el.find("a.up-upload");
if (!a.hasClass("disabled")) { a.addClass("disabled");
$.each(widget.fileList, function(i, file) {
var fd = new FormData(),
prog = widget.el .find("div.up-progress") .eq(i);
fd.append("file-" + i, file);
widget.allXHR.push($.ajax({ type: "POST", url: "/upload.asmx/uploadFile",
data: fd, contentType: false, processData: false, xhr: function() {
var xhr = jQuery.ajaxSettings.xhr();
if (xhr.upload) {
xhr.upload.onprogress = function(e) {
widget.handleProgress(e, prog);
}
} return xhr; }
}));
});
}}
Source: inspiration du livre JQuery Hotshot : Ten Practical Projects That Exercise Your Skill, Build Your Confidence, and Help You Master JQuery
Auteurs: Wellman, Dan
Informations sur la publication: Birmingham, U.K. : Packt Publishing. 2013