Een afbeeldingsgalerijcomponent bouwen met Polymer

Webcomponenten worden de toekomstige trend van de ontwikkeling van webapplicaties. Ze stellen ons in staat om HTML-opmaak, scripts en stijlen te groeperen in een herbruikbare component. Deze componenten maken deel uit van de browser en hebben daarom geen externe JavaScript-bibliotheken zoals jQuery nodig om de functionaliteit te bieden. Zoals gerapporteerd door Wikipedia,

Webcomponenten zijn een reeks standaarden die momenteel door Google-technici worden geproduceerd als een W3C-specificatie waarmee herbruikbare widgets of componenten in webdocumenten en webapplicaties kunnen worden gemaakt. De bedoeling achter hen is om op componenten gebaseerde software-engineering naar het World Wide Web te brengen. Het componentenmodel zorgt voor inkapseling en interoperabiliteit van individuele HTML-elementen.

Kortom, webcomponenten lossen de complexiteit van elementen in een webpagina op en zorgen voor een eenvoudigere en gemakkelijk te begrijpen elementenstructuur. HTML biedt al sets van ingebouwde tags zoals kopteksten, alinea's, lijsten enzovoort. In sommige gevallen zijn de bestaande tags echter niet voldoende om grote webapplicaties de juiste ondersteuning te bieden en hier komen webcomponenten te hulp. Sommige bibliotheken, met name Polymer, maken webcomponenten bruikbaar in niet-ondersteunende browsers met Polyfill Web Components.

In deze tutorial gaan we leren hoe je een Image Gallery-component maakt met Polymer versie 1.0. Alle code in dit artikel is beschikbaar op GitHub.

Inleiding tot polymeer

Afbeeldingengalerijen worden vaak gebruikt bij de ontwikkeling van websites. Over het algemeen hebben ontwikkelaars de neiging om bestaande galerijbibliotheken te gebruiken en hebben ze vaak te maken met het saaie probleem van de complexiteit van de elementstructuur die door deze bibliotheken wordt gegenereerd. De volgende code geeft een voorbeeld van de structuur van een zeer eenvoudige afbeeldingengalerij.

<div id="gallery-panel" class="gallery-panel">
    <div class="slides">
        <div id="links" name="links">
            <img src="images/thumbnails/img01.jpg" alt="Title 1">
            <img src="images/thumbnails/img02.jpg" alt="Title 2">
            <img src="images/thumbnails/img03.jpg" alt="Title 3">
            <img src="images/thumbnails/img04.jpg" alt="Title 4">
            <img src="images/thumbnails/img05.jpg" alt="Title 5">
        </div>
    </div>
    <div class="modal fade">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header"> <a class="close"><button type="button" class="close" aria-hidden="true"  >X</button></a>

                     <h4 class="modal-title"></h4>

                </div>
                <div class="modal-body next">
                    <img class='modal-img' />
                </div>
                <div class="modal-footer">
                    <button id="previous" type="button" class="btn btn-default pull-left prev">Previous</button>
                    <button id="next" type="button" class="btn btn-default next">Next</button>
                </div>
            </div>
        </div>
    </div>
</div>

Hoewel dit een codefragment is dat laat zien hoe de structuur van een standaard afbeeldingengalerij eruitziet, is het duidelijk dat het niet zo eenvoudig is als het zou kunnen zijn. Mogelijk moeten we dezelfde set code herhalen voor elke galerij op een webpagina, zodat de webpagina erg groot en moeilijk te beheren wordt.

Hier is waar en hoe Polymer zijn oplossing biedt door het gebruik van webcomponenten. Polymer is een bibliotheek die is gemaakt om aangepaste webcomponenten te bouwen. Er zijn verschillende bibliotheken die nuttig zijn om webcomponenten te maken, maar browsercompatibiliteit is een probleem dat de meeste bibliotheken nog niet hebben opgelost. Polymer biedt de beste oplossing door polyfills te bieden waarmee webcomponenten in niet-compatibele browsers kunnen worden beheerd. U kunt hier meer ontdekken over Polymer en het gebruik ervan.

Wanneer Polymer wordt gebruikt om de galerij als een webcomponent te bouwen, zou onze code er als volgt uit moeten zien.

<simple-gallery>
    <img src="images/thumbnails/img01.jpg" alt="Title 1">
    <img src="images/thumbnails/img02.jpg" alt="Title 2">
    <img src="images/thumbnails/img03.jpg" alt="Title 3">
    <img src="images/thumbnails/img04.jpg" alt="Title 4">
    <img src="images/thumbnails/img05.jpg" alt="Title 5">
</simple-gallery>

Zoals u kunt zien, is onze code veel eenvoudiger geworden en heeft deze alleen de essentiële tags. Alle andere complexe codering is verborgen voor de gebruiker, waardoor deze zeer herbruikbaar is. Laten we nu beginnen met het bouwen van de galerijcomponent met Polymer.

Hoe polymeer te installeren

Polymer kan met al zijn afhankelijkheden worden geïnstalleerd door Bower te gebruiken met de volgende opdracht:

bower install --save Polymer/polymer#^1.1.0

Hiermee worden de Polymer-bibliotheek en de polyfills van de webcomponent geïnstalleerd in een map met de naam bower_components .

Voordat we een stap voorwaarts zetten, moeten we de functies identificeren die nodig zijn voor een eenvoudige afbeeldingengalerij. We zijn van plan een webcomponent te maken voor een afbeeldingengalerij en we zullen een apart bestand moeten maken voor de galerijcomponent. Hieronder vindt u een lijst met punten waarmee we rekening moeten houden om onze galerij correct op te bouwen:

  • HTML-opmaak om galerijafbeeldingen weer te geven;
  • HTML-opmaak voor modale pop-up met grote afbeeldingen;
  • CSS-stijlen voor de galerijcomponent;
  • Knoppen voor Volgende, Vorige en Sluiten evenementen;
  • JavaScript om de galerij te openen, te sluiten en te doorlopen.

In tegenstelling tot normale webpagina's, worden al deze dingen gedefinieerd in een enkel componentbestand. Dus alle galerijcode is onafhankelijk van andere componenten en herbruikbaar op meerdere plaatsen. Dat gezegd hebbende, kunnen we beginnen met het bouwen van de hoofdwebpagina en de afbeeldingsgalerijcomponent.

Eerst moeten we de hoofdpagina van onze website maken om de webcomponenten op te nemen. We kunnen een pagina maken met de naam index.html in de hoofdmap van het project. Vervolgens moeten we de benodigde bestanden voor Polymer en de HTML-opmaak voor de afbeeldingengalerij opnemen. Het volgende codefragment laat zien hoe u verder moet gaan:

<!doctype html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Polymer</title>
        <script src="bower_components/webcomponentsjs/webcomponents.js"></script>
        <link rel="import" href="bower_components/polymer/polymer.html">
        <link rel="import" href="simple-gallery.html">
    </head>
    <body>
        <simple-gallery>
            <img data-original="images/img01.jpg" data-index='s1' src="images/thumbnails/img01.jpg" alt="Title 1">
            <img data-original="images/img02.jpg" data-index='s2' src="images/thumbnails/img02.jpg" alt="Title 2">
            <img data-original="images/img03.jpg" data-index='s3' src="images/thumbnails/img03.jpg" alt="Title 3">
        </simple-gallery>
    </body>
</html>

Eerst moeten we de polymer.html . importeren bestand van de bower_components/polymer map met behulp van de link element. Vervolgens moeten we een bestand toevoegen met de naam webcomponents.js van debower_components/webcomponentsjs map. Dit is het bestand dat verantwoordelijk is voor het afhandelen van aangepaste elementen in niet-compatibele browsers. Als je bekend bent met Polymer 0.5, ken je dit bestand misschien als platform.js . Dit is vervangen in de laatste 1.0 versie en nu een bestand genaamdwebcomponents.js dezelfde functionaliteit hanteert. Ten slotte moeten we onze aangepaste galerijcomponent importeren met een link element. In ons voorbeeld hebben we onze gebruikerscomponent simple-gallery . genoemd .

Nu kunnen we beginnen met het definiëren van onze lay-outstructuur met behulp van enkele HTML-tags en webcomponenten. We hebben een aangepaste component toegevoegd met de naam simple-gallery met alle galerijafbeeldingen in de openings- en sluitingstags. Het is je misschien opgevallen dat we weinig data-attributen hebben gebruikt, genaamd data-original en data-index . Deze attributen worden gebruikt om het proces van het verwerken van de URL van de originele afbeeldingen en de index van de afbeeldingen in de galerij te vereenvoudigen. Het is natuurlijk ook mogelijk om zelfs zonder die gegevens een galerij te maken door de DOM te manipuleren.

We hebben de benodigde bestanden op onze hoofdpagina geïmporteerd en nu zijn we klaar om de galerijcomponent te maken. De eerste stap is om een ​​nieuw bestand aan te maken in de projectmap met de naam simple-gallery.html voor de galerijcomponent. We kunnen de volgende code toevoegen om de structuur van onze galerijcomponent te definiëren:

<link rel="import" href="bower_components/polymer/polymer.html">

<dom-module id="simple-gallery" >
   <style>
      /* Styles for the Gallery Component */    
   </style>
   
   <script>
      HTMLImports.whenReady(function () {
          (function () {
              var current_index = 0;
              var image_length = 0;

              Polymer({
                  is: "simple-gallery",
                  ready: function () {},
                  load_popup: function (e, detail, sender) {},
                  next: function () {},
                  prev: function () {},
                  close: function () {},
              });
          })();

      });
   </script>
     
   <template></template>
 </dom-module>

Ten eerste moeten we de polymer.html . opnemen bestand zoals gewoonlijk. Vervolgens beginnen we met het definiëren van de galerijcomponent. Polymer 1.0 gebruikt de dom-module element om nieuwe componenten te definiëren. De componentnaam moet worden gebruikt als de id attribuut van de dom-module element.

We gebruiken de style element om alle stijlen te definiëren die nodig zijn voor onze component. Zelfs deze is veranderd van versie 0.5, waar we style . gebruikten binnen de template element. In versie 1.0 is het nu buiten de template . geplaatst element als een onafhankelijke tag. De HTML-opmaak voor de galerijcomponent gaat in de template element. Ten slotte kunnen we het element Polymer initialiseren binnen de HTMLImports.whenReady terugbel functie. Deze functie zorgt ervoor dat alle geïmporteerde documenten worden geladen voordat de code wordt uitgevoerd.

We moeten de is . gebruiken attribuut met componentnaam (eenvoudige-galerij ) om een ​​polymeercomponent te registreren. Deze procedure verschilt van de procedure die wordt gebruikt met versie 0.5 waar we de volgende syntaxis hadden:

Polymer('simple-gallery', {});

We moeten de benodigde functies voor onze gebruikerscomponent definiëren. We hebben vijf functies:ready , load_popup_ , prev , next en close . Laten we hun functionaliteit een voor een identificeren:

  • ready :Dit is een polymeerfunctie die wordt uitgevoerd zodra het polymeerobject gereed is. We gebruiken deze functie om alle functies in onze component te initialiseren.
  • load_popup :Deze functie wordt gebruikt om de originele afbeelding in een modaal pop-upvenster te laden.
  • prev :Deze functie wordt gebruikt om achteruit door de galerijafbeeldingen te bladeren
  • next :Deze functie wordt gebruikt om vooruit door de galerijafbeeldingen te bladeren
  • close :Deze functie wordt gebruikt om het modale pop-upvenster te sluiten

In de volgende sectie kunnen we beginnen met de implementatie van onze galerijcomponent op basis van de structuur die we in deze sectie hebben gemaakt.

Sjablonen behoren tot de belangrijkste onderdelen van een webcomponent. In deze sectie zullen we zien welke de opmaak is die aan de eindgebruiker wordt weergegeven. De inhoud in de template is niet zichtbaar voor de eindgebruiker omdat gebruikers alleen de simple-gallery . zullen zien tag in de broncode en andere innerlijke elementen zijn alleen zichtbaar met speciale browsertools.

Op dit punt moeten we zowel de HTML implementeren om de afbeeldingen weer te geven als de HTML voor de modale pop-up binnen deze template label. Laten we eens kijken naar de code voor onze galerijcomponentsjabloon:

<div id="gallery-panel" class="gallery-panel">
    <!-- The container for the modal slides -->
    <div class="slides">
        <div id="links" name="links"></div>
    </div>
    <!-- The modal dialog, which will be used to wrap the lightbox content -->
    <div class="modal fade">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header"> <a class="close"><button type="button" class="close" aria-hidden="true" on-click="close" >X</button></a>

                     <h4 class="modal-title"></h4>

                </div>
                <div class="modal-body next">
                    <img class='modal-img' />
                </div>
                <div class="modal-footer">
                    <button id="previous" type="button" class="btn btn-default pull-left prev" on-click="prev">Previous</button>
                    <button id="next" type="button" class="btn btn-default next" on-click="next">Next</button>
                </div>
            </div>
        </div>
    </div>
</div>

De componentsjabloon bestaat uit twee delen. De eerste is gedefinieerd met een div element met klasse slides . Deze container wordt gevuld met de afbeeldingen die we leveren uit de eenvoudige galerij-component. Dit sjabloongedeelte is standaard zichtbaar voor de gebruiker. Het tweede deel begint met de div met class="modal fade" . Dit wordt gebruikt voor een modaal pop-upvenster en wordt daarom standaard voor de gebruiker verborgen. We hebben ook de nodige knoppen voor vorige, volgende en afsluiten met Polymer on-click telefoongesprek. Polymeer gebruikt on-event syntaxis om gebeurtenissen op elementen te definiëren.

Nu we alle benodigde opmaak voor onze sjabloon hebben, is onze volgende taak om onze elementen in de style te stylen label. Indien nodig kunt u ook externe stylesheets in componenten importeren. We gaan hier niet alle stijlen opnemen. U kunt alle stijlen voor onze component vinden in de broncodemap. De volgende code bevat enkele voorbeeldstijlen voor onze component.


    .modal {
        display: none;
        width: 100%;
        height: 100%;
        overflow: hidden;
        background: rgba(0, 0, 0, 0.9) none repeat scroll 0 0;
        overflow: hidden;
        position: fixed;
        z-index: 999999;
        top:0;
    }

We hebben normale CSS-klassen en selectors gebruikt. Deze selectors worden dus afstammelingen van het galerij-element. Bijvoorbeeld .modal klasse wordt geschreven als .modal.simple-gallery . U kunt Polymer :host . gebruiken om specifieke componentelementen en zijn voorouders te targeten. Meer informatie over het stylen van componenten vind je hier.

We hebben in de vorige sectie vijf functies gedefinieerd voor onze galerijcomponent. Laten we die functies een voor een gaan implementeren.

De ready-functie

We gebruiken de ready functie om de afbeeldingen binnen het element eenvoudige galerij gedefinieerd te krijgen en ze toe te voegen aan de #links container in onze sjabloon. De volgende code bevat de implementatie van deze eerste functie.

ready: function () {
    var images = Polymer.dom(this).querySelectorAll('img');
    var container = this.$.links;

    for (var img in images) {
        images[img].addEventListener('click', this.load_popup);
        container.appendChild(images[img]);
    }
}

We selecteren alle afbeeldingen in de component met behulp van de querySelectorAll functie op de Polymer.dom(this) object. Vervolgens doorlopen we elk element en voegen het toe aan de #links container terwijl u een aangepaste klikgebeurtenis definieert om de load_popup . aan te roepen functie.

De load_popup-functie

Deze functie wordt gebruikt om de modale pop-up te openen en de originele afbeelding weer te geven wanneer u op een afbeelding uit de galerij klikt. De volgende code laat zien hoe je het implementeert:

load_popup: function (e, detail, sender) {
    e.preventDefault();
    var links = document.getElementById('links');
    image_length = links.getElementsByTagName('img').length;

    var image_url = e.target.getAttribute('data-original');
    var modalbody = document.getElementsByClassName("modal-body")[0];
    var modal_img = modalbody.getElementsByTagName('img')[0];
    modal_img.setAttribute("src", image_url);
    var modal = document.getElementsByClassName("modal")[0];
    modal.style.display = 'block';

    current_index = parseInt(e.target.getAttribute('data-index').replace("s", ""));
    return false;
}

We kunnen de aangeklikte afbeelding verkrijgen met e.target . Vervolgens pakken we de originele afbeeldings-URL met behulp van de data-original attribuut en gebruik wat DOM-manipulatie om de afbeelding toe te voegen aan het modale venster en het modale venster voor de gebruiker te openen. We kunnen ook de index van de geselecteerde afbeelding opslaan met behulp van de data-index attribuut. Over het algemeen gebruiken we bibliotheken zoals jQuery voor dit type DOM-manipulatie. In dit voorbeeld hebben we echter eenvoudige JavaScript-functies gebruikt en ik zal in de volgende sectie uitleggen waarom ik jQuery niet heb gebruikt.

De volgende functie

Deze functie wordt gebruikt om door de galerijafbeeldingen in het pop-upvenster te bladeren. Zodra de pop-up is geopend, kunnen we de knoppen Volgende en Vorige gebruiken om door de galerij te bladeren in plaats van op elke miniatuur in de galerij te klikken. Laten we eens kijken naar de implementatie van de next functie.

next: function () {
    current_index = current_index + 1;
    if (current_index == (image_length + 1)) {
        current_index = 1;
    }
    var current_image = document.querySelectorAll("[data-index='s" + current_index + "']");
    image_url = current_image[0].getAttribute('data-original');
    var modalbody = document.getElementsByClassName("modal-body")[0];
    var modal_img = modalbody.getElementsByTagName('img')[0];
    modal_img.setAttribute("src", image_url);
}

We gebruiken de huidige index die is gegenereerd op basis van de load_poup functie om de volgende afbeelding uit de galerij te halen. De afbeelding wordt geïdentificeerd door dedata-original attribuut en vervangen in de bestaande modale vensterafbeelding. Dit proces gaat door en zodra we het einde hebben bereikt, wordt de index ingesteld op 1 om vanaf het begin te beginnen. De implementatie van de prev functie is ook vergelijkbaar met deze en zal daarom hier niet worden opgenomen. Je kunt het vinden in de broncodemap.

Met dit laatste fragment hebben we de basisafbeeldingsgalerijcomponent met Polymer voltooid. U kunt de broncodebestanden gebruiken om te zien hoe het werkt. Ze zijn hier beschikbaar.

De afbeeldingengalerij is een veelgebruikt onderdeel op de meeste websites. Er zijn dus grote hoeveelheden pure JavaScript- en jQuery-bibliotheken die u kunt gebruiken om uw afbeeldingsgalerijen te maken. U vraagt ​​zich misschien af ​​waarom we een afbeeldingengalerij zouden moeten maken in plaats van een jQuery-afbeeldingengalerij om te zetten in een webcomponent. Het zou de gemakkelijkere en betere keuze zijn. Het probleem is echter dat veel jQuery-plug-ins niet werken met Polymer als webcomponenten. Deze plug-ins genereren vaak conflicten en daarom moeten we ze helemaal opnieuw bouwen.

Het is belangrijk om de reden te identificeren voor het niet aanbevelen van jQuery-plug-ins of jQuery-code in Polymer-webcomponenten. Er zijn twee soorten DOM-elementen, genaamd Local DOM en Shadow DOM:

  • Lokale DOM :deze elementen zijn zichtbaar voor de gebruiker. In dit scenario maken alle afbeeldingen in onze galerijcomponent deel uit van de Lokale DOM;
  • Schaduw-DOM :deze elementen zijn niet zichtbaar voor de gebruiker en gegenereerd door een webcomponent. In dit scenario is de afbeeldingsgalerijcontainer en het pop-upvenster de schaduw-DOM.

De meeste jQuery-plug-ins werken op Local DOM en verwachten dat de elementen zich in het Local DOM bevinden. Maar de elementen die door een webcomponent worden gegenereerd, worden in de Shadow DOM geplaatst, waardoor jQuery-plug-ins deze elementen niet kunnen identificeren. Om deze reden wordt het niet aanbevolen om jQuery-plug-ins of jQuery-code in webcomponenten te gebruiken. Ik raad u aan om in plaats daarvan de eenvoudige JavaScript-functie te gebruiken om de jQuery-functionaliteit te vervangen. Dit lijkt misschien een beperking gezien het aantal beschikbare jQuery-plug-ins, maar webcomponenten worden in een snel tempo gebouwd en binnenkort zullen we zien dat ze de meeste jQuery-plug-ins vervangen.

Conclusies

We verwachten dat webcomponenten de toekomst van applicatieontwikkeling zullen zijn dankzij hun krachtige manier om webpagina's te maken en te beheren met onnodige complexiteit. De implementatie ervan bevindt zich echter nog in een vroeg stadium en moet nog een strikte norm worden. Hoewel bibliotheken zoals Polymer het mogelijk maken om deze componenten in niet-compatibele browsers te gebruiken, kunt u nog steeds problemen tegenkomen, vooral in mobiele browsers.

Het is aan u en uw specifieke geval om te beslissen om ze in een echte toepassing te gebruiken of niet. Persoonlijk hoop ik dat webcomponenten zeer binnenkort op grote schaal zullen worden gebruikt.