{"id":6190,"date":"2017-02-22T18:12:59","date_gmt":"2017-02-22T17:12:59","guid":{"rendered":"https:\/\/www.creativejuiz.fr\/blog\/?p=6190"},"modified":"2017-02-22T18:12:59","modified_gmt":"2017-02-22T17:12:59","slug":"creer-menu-contextuel-html5-javascript","status":"publish","type":"post","link":"https:\/\/www.creativejuiz.fr\/blog\/tutoriels\/creer-menu-contextuel-html5-javascript","title":{"rendered":"Cr\u00e9er un menu contextuel avec HTML5"},"content":{"rendered":"<p>Vous vous souvenez certainement des scripts JS qui permettent de hacker le clic-droit afin de proposer un menu contextuel personnalis\u00e9 ? Sachez qu&rsquo;il est possible depuis peu de le faire gr\u00e2ce \u00e0 du HTML et un bout de JS. HTML5 \u00e9tend les capacit\u00e9s de l&rsquo;\u00e9l\u00e9ment <code>menu<\/code> gr\u00e2ce \u00e0 un nouvel attribut.<\/p>\n<p><!--more--><\/p>\n<p>On est d&rsquo;accord, en dehors des probl\u00e8mes d&rsquo;accessibilit\u00e9 qu&rsquo;implique ce genre de modification, le changement de ce bout d&rsquo;interface pour l&rsquo;utilisateur n&rsquo;est clairement pas conseill\u00e9. En effet l&rsquo;utilisateur qui utilise son clic-droit dans son navigateur a l&rsquo;habitude des commandes dont il peut b\u00e9n\u00e9ficier, en ajouter ou les modifier peut s&rsquo;av\u00e9rer perturbateur pour lui.<\/p>\n<blockquote><p>Ce n&rsquo;est pas parce que vous pouvez le faire qu&rsquo;il FAUT n\u00e9cessairement le faire !<\/p><\/blockquote>\n<p>Puis entre nous cacher des commandes dans un clic-droit\u2026 m&rsquo;enfin, si jamais vous avez besoin de ce genre de chose, voici comment faire.<\/p>\n<h2>Place au code<\/h2>\n<p>L&rsquo;\u00e9l\u00e9ment HTML <code>menu<\/code> permet de cr\u00e9er de base\u2026 un menu, oui. Il permet de regrouper des commandes, comme par exemple les commandes disponibles dans une application web (enregistrer, ouvrir, d\u00e9placer, etc.). Gr\u00e2ce \u00e0 ses enfants <code>menuitem<\/code> et aux attributs <code>contextmenu<\/code> et <code>type=\"context\"<\/code> il est possible de transformer votre menu en un compl\u00e9ment du menu contextuel existant.<\/p>\n<figure id=\"attachment_6193\" aria-labelledby=\"figcaption_attachment_6193\" class=\"wp-caption aligncenter\" style=\"width: 275px\"><img decoding=\"async\" class=\"wp-image-6193 size-full\" src=\"https:\/\/www.creativejuiz.fr\/blog\/wp-content\/uploads\/2017\/02\/context-menu-html5.png\" width=\"265\" height=\"242\" \/><figcaption id=\"figcaption_attachment_6193\" class=\"wp-caption-text\">Ma d\u00e9mo de menu contextuel dans Firefox.<\/figcaption><\/figure>\n<p>Voici le code HTML propos\u00e9. Seul, il ne fait que compl\u00e9ter le menu contextuel avec des items qui n&rsquo;auront aucun effet dans votre interface.<\/p>\n<pre class=\"code\"><code class=\"language-markup\">&lt;div contextmenu=\"menu\" id=\"box\"&gt;\r\n\tRight click to get the context menu demo.\r\n&lt;\/div&gt;\r\n\r\n&lt;menu type=\"context\" id=\"menu\"&gt;\r\n\r\n\t&lt;menuitem type=\"checkbox\" id=\"move\"&gt;Moooove&lt;\/menuitem&gt;\r\n\r\n\t&lt;menuitem type=\"command\" label=\"Test me\" id=\"custom\"&gt;Hello World!&lt;\/menuitem&gt; \r\n\r\n\t&lt;menuitem type=\"radio\" name=\"aligngroup\" value=\"left\"&gt;Align Left&lt;\/menuitem&gt;\r\n\r\n\t&lt;menuitem type=\"radio\" name=\"aligngroup\" value=\"right\"&gt;Align Right&lt;\/menuitem&gt;\r\n\r\n\t&lt;menuitem type=\"radio\" name=\"aligngroup\" checked=\"true\" value=\"center\"&gt;Align Center&lt;\/menuitem&gt;\r\n\r\n\t&lt;menuitem type=\"checkbox\" disabled&gt;Disabled menu item&lt;\/menuitem&gt;\r\n&lt;\/menu&gt;<\/code><\/pre>\n<p>Comme vous pouvez le voir, il existe plusieurs type de <code>menuitem<\/code>.<\/p>\n<ul>\n<li><code>checkbox<\/code> : qui permet de cocher ou d\u00e9cocher une option. L&rsquo;item de menu peut donc avoir deux \u00e9tats et son \u00e9tat peut \u00eatre contr\u00f4l\u00e9 gr\u00e2ce \u00e0 JavaScript.<\/li>\n<li><code>command<\/code> : qui permet simplement de lancer une commande pr\u00e9cise au clic sur cet item.<\/li>\n<li><code>radio<\/code> : qui combin\u00e9 \u00e0 un attribut <code>name<\/code> de m\u00eame valeur permet de cr\u00e9er un groupe d&rsquo;option dont une seule option sera s\u00e9lectionnable en m\u00eame temps. L&rsquo;\u00e9tat peut \u00e9galement \u00eatre v\u00e9rifi\u00e9 en JS.<\/li>\n<\/ul>\n<p>Vous pouvez \u00e9galement rendre temporaire indisponible une commande gr\u00e2ce \u00e0 l&rsquo;attribut <code>disabled<\/code>.<\/p>\n<p>Du c\u00f4t\u00e9 de JavaScript, je vous propose quelques actions tr\u00e8s basique pour cette d\u00e9monstration, \u00e0 vous d&rsquo;aller cherche plus loin les cas d&rsquo;utilisation. Le principe est simplement d&rsquo;intercepter les clics et de les traiter.<\/p>\n<pre class=\"code\"><code class=\"language-javascript\">var move    = document.getElementById('move'),\r\n    box     = document.getElementById('box'),\r\n    custom  = document.getElementById('custom'),\r\n    radios  = document.querySelectorAll('[name=\"aligngroup\"]'); \r\n\r\n\/\/ moooove action\r\nmove.addEventListener('click', function() {\r\n  if ( ! box.classList.contains('move') ) {\r\n    box.classList.add('move');\r\n  } else {\r\n    box.classList.remove('move');\r\n  }\r\n} );\r\n\r\n\/\/ custom\r\ncustom.addEventListener('click', function() {\r\n  alert('This text menu should be \"' + this.childNodes[0].nodeValue + '\" but label attribute rules the displayed text.' );\r\n} );\r\n\r\n\/\/ radios\r\nfor ( var key in radios ) {\r\n  if ( typeof radios[key] === 'object' ){\r\n    radios[key].addEventListener('click', function() {\r\n      box.classList.remove('aligncenter', 'alignleft', 'alignright');\r\n      box.classList.add('align' + this.getAttribute('value') );\r\n    } )\r\n  }\r\n}\r\n\r\n<\/code><\/pre>\n<p style=\"text-align: center;\"><a class=\"demo\" href=\"http:\/\/codepen.io\/CreativeJuiz\/pen\/MJZOLo\">D\u00e9monstration<\/a><\/p>\n<h2>Exemples d&rsquo;usage<\/h2>\n<p>Avec tout cela, je ne vous donne pas vraiment d&rsquo;exemple d&rsquo;utilisation, ce n&rsquo;est pas tr\u00e8s motivant ! Faisons cela. J&rsquo;ai pens\u00e9 \u00e0 deux exemples, mais vous en aurez certainement d&rsquo;autres :<\/p>\n<h3>Afficher des options au clic-droit sur une image<\/h3>\n<p>Le cas que je vois le plus souvent pour l&rsquo;utilisation du clic-droit, c&rsquo;est celui de la r\u00e9cup\u00e9ration d&rsquo;une image sur un site web. Un clic-droit, enregistrer-sous et hop, c&rsquo;est dans la bo\u00eete.<br \/>\nJe me souviens d&rsquo;un site web qui sur son logo proposait quelque chose d&rsquo;int\u00e9ressant : rediriger l&rsquo;utilisateur vers la page \u00ab\u00a0Kits Media\u00a0\u00bb sur laquelle \u00e9taient propos\u00e9es des ressources comme les logos vectoriels ou les kits de presse pour leur communication. La redirection \u00e9tait un peu violente pour l&rsquo;exp\u00e9rience utilisateur puisqu&rsquo;inattendue.<\/p>\n<p>Avec un menu contextuel en HTML5 vous pourriez proposer de nouvelles options comme par exemple :<\/p>\n<ul>\n<li>T\u00e9l\u00e9charger l&rsquo;image en PNG<\/li>\n<li>T\u00e9l\u00e9charger l&rsquo;image en SVG<\/li>\n<li>Voir la page \u00ab\u00a0Kits Media\u00a0\u00bb<\/li>\n<\/ul>\n<p>en plus des options classiques du menu contextuel.<\/p>\n<h3>Am\u00e9liorer votre application web<\/h3>\n<p>Vous avez une application web qui permet de g\u00e9rer des mails, ou des utilisateurs, ou que sais-je encore ? Vous pouvez facilement proposer des commandes additionnelles au clic-droit sans compl\u00e8tement hacker le comportement par d\u00e9faut du navigateur.<\/p>\n<h2>Support Navigateur<\/h2>\n<p>Je vous laisse avec cela :<\/p>\n<div class=\"ciu_embed\" data-feature=\"menu\" data-periods=\"future_1,current,past_1,past_2\"><a href=\"http:\/\/caniuse.com\/#feat=menu\">Can I Use menu?<\/a><\/div>\n\t\t<script src=\"\/\/cdn.jsdelivr.net\/caniuse-embed\/1.0.1\/caniuse-embed.min.js\"><\/script>\n","protected":false},"excerpt":{"rendered":"<p>Vous vous souvenez certainement des scripts JS qui permettent de hacker le clic-droit afin de proposer un menu contextuel personnalis\u00e9 ? Sachez qu&rsquo;il est possible depuis peu de le faire gr\u00e2ce \u00e0 du HTML et un bout de JS. HTML5 \u00e9tend les capacit\u00e9s de l&rsquo;\u00e9l\u00e9ment menu gr\u00e2ce \u00e0 un nouvel attribut.<\/p>\n","protected":false},"author":4,"featured_media":6198,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_bluesky_dont_syndicate":"","_bluesky_syndication_accounts":"","_bluesky_syndication_text":"","footnotes":""},"categories":[610,9,12],"tags":[16,157],"coauthors":[597],"class_list":["post-6190","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-javascript","category-tutoriels","category-veille-technologique","tag-html5","tag-menu"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/posts\/6190","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/comments?post=6190"}],"version-history":[{"count":0,"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/posts\/6190\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/media\/6198"}],"wp:attachment":[{"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/media?parent=6190"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/categories?post=6190"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/tags?post=6190"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.creativejuiz.fr\/blog\/wp-json\/wp\/v2\/coauthors?post=6190"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}