Статьи

Создание компонента галереи изображений с помощью полимера

Веб-компоненты становятся будущей тенденцией разработки веб-приложений. Они позволяют нам сгруппировать HTML-разметку, сценарии и стили в повторно используемый компонент. Эти компоненты являются частью браузера и, следовательно, не нуждаются во внешних библиотеках JavaScript, таких как jQuery, для обеспечения его функциональности. Как сообщает Википедия ,

Веб-компоненты — это набор стандартов, которые в настоящее время разрабатываются инженерами Google в качестве спецификации W3C, которые позволяют создавать многократно используемые виджеты или компоненты в веб-документах и ​​веб-приложениях. Их цель состоит в том, чтобы привнести компонентно-ориентированную разработку программного обеспечения в World Wide Web. Модель компонентов учитывает инкапсуляцию и взаимодействие отдельных элементов HTML.

Короче говоря, веб-компоненты разрешают сложность элементов на веб-странице и обеспечивают более простую и понятную структуру элементов. HTML уже предоставляет наборы встроенных тегов, таких как заголовки, абзацы, списки и так далее. Однако в некоторых случаях существующих тегов недостаточно, чтобы обеспечить правильную поддержку больших веб-приложений, и здесь на помощь приходят веб-компоненты. Некоторые библиотеки, особенно Polymer , делают веб-компоненты пригодными для использования в не поддерживающих браузерах с Polyfill Web Components.

В этом уроке мы узнаем, как создать компонент «Галерея изображений» с версией Polymer 1.0. Весь код, представленный в этой статье, доступен на GitHub .

Введение в Полимер

Картинные галереи обычно используются при разработке веб-сайтов. Как правило, разработчики склонны использовать существующие библиотеки галерей, и им часто приходится сталкиваться с скучной проблемой сложности структуры элементов, создаваемой этими библиотеками. Следующий код просматривает структуру очень простой галереи изображений.

<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> 

Хотя это фрагмент кода, который показывает, как выглядит структура базовой галереи изображений, ясно, что это не так просто, как могло бы быть. Возможно, нам придется повторять один и тот же набор кода для каждой галереи на веб-странице, поэтому веб-страница становится очень большой и сложной для управления.

Вот где и как Polymer предоставляет свое решение с помощью веб-компонентов. Polymer — это библиотека, созданная для создания пользовательских веб-компонентов. Существует несколько библиотек, полезных для создания веб-компонентов, но совместимость браузера — это проблема, которую большинство библиотек еще не решили. Polymer обеспечивает лучшее решение, предоставляя полифилы, которые могут управлять веб-компонентами в несовместимых браузерах. Вы можете узнать больше о Polymer и его использовании здесь .

Когда Polymer используется для построения галереи в качестве веб-компонента, наш код должен выглядеть следующим образом.

 <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> 

Как видите, наш код стал намного проще и содержит только необходимые теги. Все остальное сложное кодирование скрыто от пользователя, что делает его многократно используемым. Теперь давайте начнем строить компонент галереи с помощью Polymer.

Как установить полимер

Polymer может быть установлен со всеми его зависимостями, используя Bower, выполнив следующую команду:

 bower install --save Polymer/polymer#^1.1.0 

Это установит библиотеку Polymer и полизаполнения веб-компонента в папку с именем bower_components .

Прежде чем сделать шаг вперед, мы должны определить функции, необходимые для базовой галереи изображений. Мы планируем создать веб-компонент для галереи изображений, и нам нужно будет создать отдельный файл для компонента галереи. Ниже вы можете найти список моментов, которые мы должны принять во внимание, чтобы правильно построить нашу галерею:

  • HTML-разметка для отображения галереи изображений;
  • HTML-разметка для модального всплывающего окна с большими изображениями;
  • CSS стили для компонента галереи;
  • Кнопки для событий Next, Previous и Close;
  • JavaScript для обработки галереи открывать, закрывать и проходить.

В отличие от обычных веб-страниц, все эти вещи определены внутри одного файла компонента. Таким образом, весь код галереи не зависит от других компонентов и может быть повторно использован во многих местах. Сказал, что мы можем приступить к созданию главной веб-страницы и компонента галереи изображений.

Сначала мы должны создать главную страницу нашего сайта, чтобы включить веб-компоненты. Мы можем создать страницу index.html внутри корневой папки проекта. Затем нам нужно включить необходимые файлы для Polymer и HTML-разметку для галереи изображений. Следующий фрагмент кода показывает, как действовать:

 <!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> 

Сначала нам нужно импортировать файл bower_components/polymer папки bower_components/polymer используя элемент link . Затем нам нужно добавить файл с именем webcomponents.js из bower_components/webcomponentsjs . Этот файл отвечает за обработку пользовательских элементов в несовместимых браузерах. Если вы знакомы с Polymer 0.5, вы можете знать этот файл как platform.js . Это было заменено в последней версии 1.0, и теперь файл с именем webcomponents.js обрабатывает те же функции. Наконец, нам нужно импортировать наш пользовательский компонент галереи, используя элемент link . В нашем примере мы назвали наш пользовательский компонент simple-gallery .

Теперь мы можем начать определять структуру нашего макета, используя некоторые HTML-теги и веб-компоненты. Мы добавили пользовательский компонент simple-gallery со всеми изображениями галереи внутри открывающих и закрывающих тегов. Вы можете заметить, что мы использовали несколько атрибутов data-original называемых data-original и data-index . Эти атрибуты используются для упрощения процесса обработки URL исходных изображений и индекса изображений в галерее. Конечно, также возможно создать галерею даже без этих данных, манипулируя DOM.

Мы импортировали необходимые файлы на нашу главную страницу, и теперь мы готовы создать компонент галереи. Первым шагом является создание нового файла внутри папки проекта с именем simple-gallery.html для компонента галереи. Мы можем добавить следующий код, чтобы определить структуру нашего компонента галереи:

 <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> 

Во-первых, мы должны как обычно включить файл polymer.html . Затем мы начинаем определять компонент галереи. Polymer 1.0 использует элемент dom-module для определения новых компонентов. Имя компонента следует использовать в качестве атрибута id элемента dom-module .

Мы используем элемент style чтобы определить все стили, необходимые для нашего компонента. Даже эта версия изменилась по сравнению с версией 0.5, где мы использовали style внутри элемента template . В версии 1.0 он теперь находится вне элемента template как независимый тег. HTML-разметка для компонента галереи находится внутри элемента template . Наконец, мы можем инициализировать элемент Polymer внутри HTMLImports.whenReady обратного вызова HTMLImports.whenReady . Эта функция гарантирует, что все импортированные документы загружаются перед выполнением кода.

Мы должны использовать атрибут is с именем компонента ( simple-gallery ) для регистрации компонента Polymer. Эта процедура отличается от той, которая использовалась в версии 0.5, где у нас был следующий синтаксис:

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

Мы должны определить необходимые функции для нашего пользовательского компонента. У нас есть пять функций: ready , load_popup_ , prev , next и close . Давайте определим их функциональность один за другим:

  • ready : это функция Polymer, которая выполняется, когда объект Polymer готов. Мы используем эту функцию для инициализации любых функций нашего компонента.
  • load_popup : эта функция используется для загрузки исходного изображения в модальном всплывающем окне.
  • prev : эта функция используется для перемещения назад по галерее изображений
  • next : эта функция используется для перемещения вперед по изображениям галереи
  • close : эта функция используется для закрытия модального всплывающего окна.

В следующем разделе мы можем начать реализацию нашего компонента галереи на основе структуры, которую мы создали в этом разделе.

Шаблоны являются одними из наиболее важных частей веб-компонента. В этом разделе мы увидим, какая именно разметка отображается для конечного пользователя. Контент внутри template не виден конечному пользователю, так как пользователи увидят только тег simple-gallery в исходном коде, а другие внутренние элементы будут видны только с помощью специальных инструментов браузера.

На этом этапе мы должны реализовать как HTML для отображения изображений, так и HTML для модального всплывающего окна внутри этого тега template . Давайте посмотрим на код для нашего шаблона компонента галереи:

 <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> 

Шаблон компонента состоит из двух частей. Первый определяется элементом div содержащим slides классов. Этот контейнер будет заполнен изображениями, которые мы предоставляем из компонента simple-gallery. Эта часть шаблона видна пользователю по умолчанию. Вторая часть начинается с div с class="modal fade" . Это будет использоваться для модального всплывающего окна и, следовательно, будет скрыто от пользователя по умолчанию. У нас также есть необходимые кнопки для предыдущего, следующего и закрытия с вызовом on-click Polymer. Polymer использует синтаксис on-event для определения событий в элементах.

Теперь, когда у нас есть вся необходимая разметка для нашего шаблона, нашей следующей задачей будет стилизация наших элементов внутри тега style . При необходимости вы также можете импортировать внешние таблицы стилей в компоненты. Мы не собираемся включать все стили здесь. Вы можете найти все стили для нашего компонента в папке с исходным кодом. Следующий код содержит несколько примеров стилей для нашего компонента.


Мы использовали обычные CSS-классы и селекторы. Таким образом, эти селекторы станут потомками селектора элемента галереи. Например, класс .modal будет записан как .modal.simple-gallery . Вы можете использовать Polymer :host для нацеливания на определенные элементы компонента и его предков. Вы можете найти больше информации о том, как стилизовать компоненты здесь .

Мы определили пять функций для нашего компонента галереи в предыдущем разделе. Давайте начнем реализовывать эти функции одну за другой.

Готовая Функция

Мы используем функцию ready чтобы получить изображения, определенные внутри элемента simple-gallery, и добавить их в контейнер #links внутри нашего шаблона. Следующий код содержит реализацию этой первой функции.

 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]); } } 

Мы выбираем все изображения внутри компонента, используя функцию Polymer.dom(this) объекта Polymer.dom(this) . Затем мы просматриваем каждый элемент и добавляем его в контейнер #links одновременно определяя пользовательское событие click для вызова функции load_popup .

Функция load_popup

Эта функция используется для открытия модального всплывающего окна и отображения исходного изображения при нажатии на изображение из галереи. Следующий код показывает, как это реализовать:

 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; } 

Мы можем получить изображение по e.target используя e.target . Затем мы берем URL исходного изображения с помощью атрибута data-original и используем некоторые манипуляции с DOM, чтобы добавить изображение в модальное окно и открыть модальное окно для пользователя. Мы также можем сохранить индекс выбранного изображения, используя атрибут data-index . Как правило, мы склонны использовать библиотеки, такие как jQuery, для этого типа манипулирования DOM. Однако в этом примере мы использовали простые функции JavaScript, и я объясню причины, побудившие меня избегать использования jQuery, в следующем разделе.

Следующая функция

Эта функция используется для перемещения по галерее изображений во всплывающем окне. Когда всплывающее окно открыто, мы можем использовать кнопки «Далее» и «Предыдущий», чтобы перемещаться по галерее, вместо того, чтобы щелкать по каждой миниатюре из галереи. Давайте посмотрим на реализацию next функции.

 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); } 

Мы используем текущий индекс, сгенерированный из функции load_poup чтобы получить следующее изображение из галереи. Изображение идентифицируется атрибутом data-original и заменяется на существующее изображение модального окна. Этот процесс продолжается, и как только мы достигаем конца, для индекса устанавливается значение 1, чтобы начать с начала. Реализация функции prev также похожа на эту и, следовательно, здесь не будет включена. Вы можете найти его в папке с исходным кодом.

С помощью этого последнего фрагмента мы завершили базовый компонент галереи изображений с помощью Polymer. Вы можете использовать файлы исходного кода, чтобы увидеть, как это работает. Они доступны здесь .

Галерея изображений является распространенным компонентом на большинстве веб-сайтов. Итак, существует большое количество чистого JavaScript, а также библиотек jQuery, которые вы можете использовать для создания своих галерей изображений. Вам может быть интересно, почему мы должны создавать галерею изображений вместо преобразования галереи изображений jQuery в веб-компонент. Это был бы более легкий и лучший выбор. Однако проблема в том, что многие плагины jQuery не работают с Polymer в качестве веб-компонентов. Эти плагины часто порождают конфликты, и поэтому мы должны создавать их с нуля.

Важно определить причину отказа от использования плагинов jQuery или кода jQuery внутри веб-компонентов Polymer. Существует два типа элементов DOM, которые называются Local DOM и Shadow DOM:

  • Локальный DOM : эти элементы видны пользователю. В этом сценарии все изображения внутри нашего компонента галереи являются частью Local DOM;
  • Shadow DOM : эти элементы не видны пользователю и генерируются веб-компонентом. В этом случае контейнер галереи изображений и всплывающее окно являются теневым DOM.

Большинство плагинов jQuery работают в Local DOM и ожидают, что элементы будут в Local DOM. Но элементы, сгенерированные из веб-компонента, помещаются в Shadow DOM, поэтому плагины jQuery не могут идентифицировать эти элементы. По этой причине не рекомендуется использовать плагины jQuery или код jQuery внутри веб-компонентов. Я предлагаю вам использовать простую функцию JavaScript вместо функциональности jQuery. Это может показаться ограничением, учитывая количество доступных плагинов jQuery, но веб-компоненты создаются быстрыми темпами, и вскоре мы увидим, что они заменяют большинство плагинов jQuery.

Выводы

Мы ожидаем, что веб-компоненты станут будущим разработки приложений благодаря их мощному способу создания и управления веб-страницами с ненужной сложностью. Однако их реализация все еще находится на ранней стадии и еще не стала строгим стандартом. Несмотря на то, что такие библиотеки, как Polymer, позволяют использовать эти компоненты в несовместимых браузерах, вы все равно можете столкнуться с проблемами, особенно в мобильных браузерах.

Вам и вашему конкретному случаю решать, использовать их в реальном приложении или нет. Лично я надеюсь, что веб-компоненты очень скоро станут широко использоваться.