Простая карусель. Как создать карусель используя только HTML и CSS. Динамический блок «Отзывы клиентов»

Существует две азбучные истины, с которых начитается собственно дело. Это перво-наперво сказать себе «поехали!» и составить бизнес-план. Который определял бы направление развития, предполагаемые затраты и прибыль, учитывал риски и дополнительные доходы. Но если с первой проще – схватили со стены дедовскую шашку и вперёд по огороду с целью нарубить капусты. То со вторым – всё очень сложно,- порой замах на рубль, а эффект на копейку. Дело то в итоге оказывается, что не распланировано и даже нет предположения, что же сделать сейчас и завтра.
Стоит иметь в виду, что существуют два вида бизнес-планов: простой это который составляется скорее для себя и сложный под инвестиции и банковские займы. Но при составлении любого из них приходит понимание, что же мне любимому нужно, что смогу осилить, а где придётся обращаться за помощью или вообще отказаться от какой-то части направления в деятельности.

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

В качестве примера возьмём желание любого блоггера стать собственником портала. «Нет такого солдата, в ранце бы которого не лежал маршальский жезл». То есть вырастить своё крохотное предприятие, где сам является редактором, журналистом, дизайнером, оптимизатором, программистом, админом, модератором, кашеваром и привратником в одном лице – до размеров грандиозного ресурса с приличным штатом сотрудников. И именно бизнес-план поможет ему очень быстро перейти от нормального течения к развитию, подсказав пути: на что именно посетители обращают внимание, какие собственные навыки удобнее и легче использовать, как оптимизировать свой собственный бизнес. И речь не только о необходимости оптимизировать собственный ресурс, а какое время на него тратить – какие усилия, насколько всерьёз воспринимать. Он может способствовать развитию простых продажи расходов, возможно даже прогнозировать прибыль и убытки. – На основе этого легко планировать, как распоряжаться своими ресурсами и как использовать оперативные средства.

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

И всё же не каждый стартап прост как хотелось бы. Некоторые из них требуют привлечения инвестиций, более подробного обдумывания и соответственно планирование, что невозможно сделать без достаточной аналитической работы. Мне предлагали как-то переделать старый уже работающий инвестиционный проект под новый, но заурядным способом – отрерайтить и немного подправить цифры в технико-экономическом обосновании (ТЭО) чтобы получить кредит под раскрутку. Но в банках хоть и заседают клерки, но и у них иногда бывают мозги – они бы с лёгкостью бы раскусили, что это наполовину фальшивка без исследования соответствующего вопросу инвестиционного проекта. Поставленные перед собой вопросы некоторой сложности – требует и несколько подробного подхода.
В любом случае, даже в простом плане стратапа должны быть сведения достаточные для привлечения партнёров и спонсоров, расшифровка направленности интернет-ресурса. Зарабатывать в сети с использованием ресурса можно несколькими способами и смешивать их не стоит, потому что одно направление будет мешать другому – бригада сантехников с трудом сможет совмещать работу в супермаркете.

Вот примерный шаблон из которых может состоять бизнес-план стартапа:
План Тема Суть График
1 Резюме Важнейшее
1,1 Цели
1,2 Способы достижения
2 Резюме ресурса запуск запуск
3 Описание деятельности
4,1 Сегментация рынка
4,2 Целевой рынок сегмента стратегии
4,3 Специфика сегмента
5 Осуществление стратегии и резюме
5,1 Конкурентные преимущества
5,2 Стратегия конкуренции Sales Forecast
6 Управление резюме
7 Финансовый план
7,1 Определение точки безубыточности
7,2 Прогнозирование о прибылях и убытках
7,3 Прогноз финансового результата

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

  • Некоторые моменты из простого бизнес-плана могут сложиться в голове владельца, но каждый бизнес имеет план. Любой может извлечь выгоды из создания документа, если идеи записаны, потому что процесс подготовки плана является полезным и ценным.
  • Как только другой человек интересуется, необходимыми параметрами уже составленного плана - он имеет решающее значение для передачи понимания целей, стратегии и детального осуществления.
  • Как только кто-либо из внешней среды интересуется особенностями стартапа, хотя это и не предусматривалось в начале, то вы должны предоставить дополнительную информацию. Когда план только для внутреннего использования, вы не можете описать историю стратапа, особенностях ресурса, например. Не отступайте от темы, которые создают прибавочную стоимость,- это в конечном итоге поможет добиться цели. Когда вы привлекаете людей, парнёров, спонсоров, то необходимо предоставить более подробную справочную информацию в рамках этого плана.
  • Для целей обсуждения перспектив достаточно получить начальный план. Попробуйте описать ваши цели, пути достижения, целевой рынок, конкурентные преимущества, и основные стратегии. Насколько хорошо это перекрывает бизнес-идею?
  • Даже если вы в состоянии в уме заниматься финансовой аналитикой связанной с деятельностью вашего стартапа - тем не менее, это гораздо проще при использовании некоторых инструментов, которые могут поставить перед вами чёткую очерёдность действий, и складывать и вычитать их автоматически. Вот в чём план помогает.
  • Вы действительно знаете, рынок на котором выбрали для себя нишу? Хороший анализ рынка может помочь вам увидеть возможности, которые могли бы не быть очевидными. Понять, почему люди обращаются к другим и посещают именно их ресурсы. Каковы потребности посетителей? Сколько их там, в качестве потенциальных клиентов?

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

Каждый из предпринимателей, придумавший новую идею для бизнеса, мечтает вырастить из нее «единорога», который изменит мир. Но по статистике, взлетает только 1 из 10 проектов, остальные — прогорают. Почему так происходит и что можно сделать на старте проекта, чтобы минимизировать риск его неудачи — рассказал Владимир Лысиков, инвестиционный аналитик Capital Times .

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

Владимир Лысиков
Инвестиционный аналитик Capital Times

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

Еще 30 лет назад цикл разработки нового решения занимал 5-10-15 лет, и даже в случае ошибки в проектировании у пользователей все равно не было другого выбора, как пользоваться предложенным продуктом.

Сейчас же цикл разработки и запуска сократился до нескольких месяцев.

Приведу пример. Версию программного обеспечения 1.0 принято считать ключевым этапом разработки. Как правило, именно с момента выхода первой версии считается, что продукт готов и может быть продан широкому кругу пользователей. Wargaming презентовали версию World of tanks 1.0 лишь 20 марта 2018 года, хотя выпуск онлайн-релиза состоялся еще в 2011 году. С того времени разработчиком выпущено 45 обновлений клиента, полных настроек, дополнений, улучшений. При этом монетизация проекта фактически началась еще в бета-версии продукта.

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

Почему стартапы прогорают

На мой взгляд, основных причин провала стартапов три:

1. Слепая любовь основателей к своему проекту.

2. Неспособность сконцентрироваться на проблеме, которую должен решать проект.

3. Неготовность тщательно проработать жизнеспособность идей.

И если с любовью предпринимателя к своему детищу практически ничего нельзя поделать, то с остальными причинами (концентрация на проблеме и всесторонняя проработка жизнеспособности идеи) не так уж и сложно разобраться.

Традиционно бизнес использует для оценки жизнеспособности такие инструменты, как экономическое моделирование и проектирование детальной «дорожной карты» в форме бизнес-плана. Но для стартапов такая форма оценки не оправдана ни с точки зрения затрат, ни с точки зрения ценности. Да и сам по себе бизнес-план - это не столько отражение реальности, сколько отражение «фантазий и ожиданий» автора. Именно по этой причине даже идеально сбалансированный на бумаге бизнес-план с великолепными показателями может быть не реализован.

Крупная клетка вместо бизнес-плана

Альтернативой традиционному бизнес-плану в этом случае может быть составление своеобразного «скриншота» основных концепций будущего бизнеса в виде концепта, разработанного по технологии Business Model Canvas или Lean Canvas


Иллюстрация из книги Business Model Generation Александр Остервальдер, Ив Пинье

Технология бизнес-моделирования Business Model Canvas (авторы — Александр Остервальдер, Ив Пинье) представляет собой шаблон стабильной структуры любого бизнеса, состоящий из 9 основных элементов.

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

2. Продукты (ценностное предложение). Здесь вы должны описать, почему клиенты должны выбрать ваш продукт, а не продукт конкурентов.

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

4. Каналы продаж. Это система взаимодействия компании с потребителем, точки контакта продавца и клиента.

5. Доходы. Вы должны спросить себя: за что будут готовы платить ваши клиенты? Правильный ответ на этот вопрос позволит создать один или несколько потоков поступления доходов, при этом каждый поток может иметь свой механизм ценообразования.

6. Ключевая деятельность. Действия компании, которые необходимы для реализации ее бизнес-модели. Так, среди ключевых видов деятельности Microsoft - разработка программного обеспечения. А в перечень ключевых видов деятельности компании Dell входит управление отношениями с поставщиками.

7. Ключевые партнеры. Сеть поставщиков и партнеров и типы отношений с ними, например, стратегическое сотрудничество или соконкуренция.

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

9. Затраты. В этом блоке необходимо описать наиболее существенные затраты проекта и их виды.

Описанная технология позволяет совместить и увидеть внутренние взаимосвязи и смысловые цепочки в процессе создания прибыли. Например, какие инструменты (ресурсы) необходимо использовать для того, чтобы осуществлять деятельность по производству продукта, сколько стоят эти ресурсы и как можно их удешевить.

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

В итоге мы получаем одностраничную четко структурированную бизнес-идею. Однако Business Model Canvas бывает сложно применять для стартапов, так как в некоторые ячейки нечего вписать (у проекта может не быть партнеров или совершенно непонятны будущие каналы сбыта).

Предприниматель Аш Моря переосмыслил технологию Business Model Canvas и предложил свою технологию — Lean Canvas.

Нажмите на изображение, чтобы увеличить его


Иллюстрация с сайта leanstack.com

Заполнять блоки нужно в последовательности, указанной на схеме.

1. Определяем целевую аудиторию — кто клиент. Сначала определяем целевую аудиторию. Чем точнее это сделано, тем лучше удается понять и решить проблемы клиентов. Соответственно, тем успешнее будет продукт.

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

3. Источники доходов. Продукт создается не ради реализации предпринимательской идеи, а для генерации денежного потока. Необходимо определить, как это будет происходить, готовы ли клиенты платить за решение своей проблемы. На этом этапе следует сделать модель и протестировать ее на реалистичность.

4. Описание решения. Следует акцентировать внимание на ключевых возможностях своего решения, но с учетом описания механизма решения этих проблем.

5. Уникальное предложение. В этом блоке важно сформулировать в краткой форме, максимум 140 символов, уникальность нашего продукта, отличие продукта от конкурентных решений.

6. Каналы продаж. Здесь необходимо определить способы, с помощью которых клиент будет узнавать о продукте.

7. Ключевые метрики проекта. В этом блоке стоит записать критерии, по которым вы собираетесь следить за проектом: каким будет продукт на горизонте до 3-х лет, какой финансовый результат будет генерировать продукт, темпы роста.

8. Структура затрат. Затраты следует разделить на две категории: первоначальные затраты на продукт и регулярные затраты на развитие.

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

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

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

В качестве резюме

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

То иногда приходится решать задачи, связанные с фронтэндом, несмотря на то, что я его недолюбливаю 🙂

О моём отношению к всему, что связано с «прекрасным» вы, собственно говоря, могли оценить по дизайну данного сайта, который разрабатывался мною единолично 🙂

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

Вызвана данная необходимость была тем, что в результате должен был получиться JS скрипт, который через сторонний сервис подключался бы на сайт. Следовательно, готовые карусели на JavaScript сразу отпадали, т.к. для их интеграции нужно было в HTML код сайта добавлять подключение библиотеки через тэг script и копировать сами файлы либы на сервер или тянуть их по cdn, но для этого снова потребовалось бы править код ресурса.

Как сделать JavaScript слайдер: начало

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

Заказчикам всегда наплевать на то, как код написан, какая у него архитектура, главное — видеть результат!

В итоге, как вы поняли, перед тем, как написать слайдер на JavaScript без jQuery, я решил подыскать готовый и доработать его под свои нужды. Почему без jQuery? Да потому что на целевом ресурсе, куда я планировал подключать свой слайдер через сервис, вызов jQuery в коде был расположен позже скрипта, подключаемого сервисом. Поэтому jQuery конструкции в моём коде просто не воспринимались.

В качестве основы я взял этот JavaScript слайдер изображений — https://codepen.io/gabrieleromanato/pen/pIfoD.

Остановиться я решил именно на нём, т.к. его JS код был написан с применением принципов ООП и классы в нём основываются на прототипах, а не на банальных функциях.

Честно говоря, я глубоко не понимаю и не признаю сегодняшнюю шумиху вокруг JavaScript с использование ООП, фреймворков и прочих архитектурных штук в языке, который изначально задумывался как простенький язык динамических сценариев. Равно как и сам JS я откровенно недолюбливаю с его синтаксическим винегретом, позволяющим одни и те же конструкции писать несколькими способами.

Но, к сожалению, в современном мире мои позиции мало кто разделяет, т.к. данный язык развивается сумасшедшими темпами и предпринимает даже попытки завоевать умы бэкенд разработчиков с помощью Node.js как альтернативы Java, PHP, C#, Ruby и других монстров.

В итоге, чтобы банально не остаться без работы, приходится по-тихоньку с JavaScript разбираться. А в выбранной мною реализации слайдера на чистом JavaScript я встретил то, что, как вы поняли, презираю в данном языке. Поэтому я её и выбрал, чтобы был хоть какой-то повод поработать и разобраться с JavaScript ООП и прототипными классами — иначе я бы к ним добровольно никогда в жизни не прикоснулся бы 🙂

На базе найденного мною кода мне необходимо было разработать слайдер на чистом JS во всплывающем окне (такую штуку ещё называют popup, попап и т.д.), который имел бы кнопки переключения слайдов и кликабельные индикаторы текущего слайда. Также нужно было сделать кнопку для закрытия данного окна.

Вот, что у меня получилось в итоге.

Делаем библиотеку JS слайдера

Сперва я решил всё реализовать по уму и сделать JavaScript слайдер для сайта в виде библиотеки, подключаемой на сайт одним-единственным скриптом, в котором будут вызываться компоненты слайдера, разбитые по подкаталогам. Назвать её я решил popupSlider.js в честь её изначального предназначения.

Её код можно найти на GitHub по этому адресу — https://github.com/Pashaster12/popupSlider.js

Структура библиотеки вышла следующая:

Папка slides предназначена для картинок слайдов. В controls размещены картинки элементов управления JS каруселью (кнопки закрытия слайдера и переключения слайдов). А в assets — статические элементы JS слайдера: HTML разметка и файл с CSS стилями.

Ну, а файл popupSlider.js — это и есть сердце самой библиотеки, в котором прописаны действия JavaScript карусели и устанавливается связь с остальными файлами. Именно его мы и будем подключать на сайте, а он уже будет вызывать остальные.

Я решил начать с HTML разметки нашей JS карусели картинок, которая в моём случае выглядит так:

Text 1 Text 2 Text 3

Для оформления слайдера на JavaScript в виде попапа я использовал следующие стили:

#slider { margin: auto; width: 600px !important; overflow: hidden; } #slider-wrapper { width: 9999px; height: 343px; position: relative; transition: left 400ms linear; } .slide { float: left; width: 600px; position: relative; overflow: hidden; } .caption { width: 600px; height: 110px; line-height: 1.5; font-size: 15px; font-weight: 300; text-align: center; color: #000; display:table; } .caption-container { display: table-cell; vertical-align: middle; padding: 0 20px; } #slider-nav { position: absolute; bottom: -36px; text-align: center; left: 50%; transform: translateX(-50%); } #slider-nav a { width: 8px; height: 8px; text-decoration: none; color: #000; display: inline-block; border-radius: 50%; margin: 0 5px; background-color: #fafafa; } #slider-nav a.current { background-color: #337ab7; } .horizontal-controls { position: absolute; display: inline-block; width: 12px; height: 20px; top: 50%; margin-top: -10px; } #prev { background: url(../controls/arrow_left_inactive.png); left: -40px; } #prev:hover { background: url(../controls/arrow_left_active.png); } #next { background: url(../controls/arrow_right_inactive.png); right: -40px; } #next:hover { background: url(../controls/arrow_right_active.png); } #cq-popup { width: 600px; z-index: 23; left: calc(50%); top: calc(50%); position: fixed !important; background-repeat: no-repeat; background-position: right; background-color: #fff; font-family: "Roboto","Segoe UI","Helvetica","Georgia","Calibri","Verdana"; transform: translate(-50%, -50%) scale(1); } #cq-popup .header { display: inline-block; font-size: 17px; font-weight: 500; } #cq-popup > div { width: 500px; font-size: 22px; line-height: 36px; } #cq-popup-btclose { text-decoration: none; position: absolute; right: -40px; top: 0; background: url(../controls/btn_delete_inactive.png); height: 16px; width: 16px; } #cq-popup-btclose:hover { background: url(../controls/btn_delete_active.png); } #cq-popup-bg { position: fixed; top:0; width: 100%; height: 100%; background: rgba(51,51,51,0.8); z-index: 22; }

В результате применения данных стилей JS карусель выглядит следующим образом:

И HTML разметку, и CSS стили я вынес в отдельные файлы popupSlider.html и popupSlider.css, которые расположены в директории assets библиотеки слайдера на JavaScript. Я сделал это специально, чтобы пользователи при использовании данного кода могли без проблем корректировать разметку и оформление, не лазя в JS коде, где вынесенное нужно было бы прописать напрямую.

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

В итоге, я решил просто подключать готовые файлы в главном файле библиотеки popupSlider.js, который для моей постановки задачи принял следующий вид:

Function Slider(element) { this.loadStatic(); this.el = document.querySelector(element); this.init(); } Slider.prototype = { init: function () { this.links = this.el.querySelectorAll("#slider-nav a"); this.wrapper = this.el.querySelector("#slider-wrapper"); this.nextBtn = this.el.querySelector("#next"); this.prevBtn = this.el.querySelector("#prev"); this.navigate(); }, navigate: function () { var self = this; for (var i = 0; i < this.links.length; ++i) { var link = this.links[i]; link.addEventListener("click", function (e) { self.slide(this); }); } self.prevBtn.style.display = "none"; self.nextBtn.addEventListener("click", function (e) { var currentSlideNumber = document.querySelector("#slider-nav a.current").getAttribute("data-slide"); var nextSlide = document.querySelector(""); nextSlide.click(); }, false); self.prevBtn.addEventListener("click", function (e) { var currentSlideNumber = document.querySelector("#slider-nav a.current").getAttribute("data-slide"); var prevSlide = document.querySelector(""); prevSlide.click(); }, false); self.close(); }, slide: function (element) { this.setCurrentLink(element); var index = parseInt(element.getAttribute("data-slide"), 10) + 1; var currentSlide = this.el.querySelector(".slide:nth-child(" + index + ")"); this.wrapper.style.left = "-" + currentSlide.offsetLeft + "px"; if (index < this.links.length) this.nextBtn.style.display = "block"; else if (index == this.links.length) this.nextBtn.style.display = "none"; if (index > 1) this.prevBtn.style.display = "block"; else if (index == 1) this.prevBtn.style.display = "none"; }, setCurrentLink: function (link) { var parent = link.parentNode; var a = parent.querySelectorAll("a"); link.className = "current"; this.currentElement = link; for (var j = 0; j < a.length; ++j) { var cur = a[j]; if (cur !== link) { cur.className = ""; } } }, loadStatic: function () { var self = this; var link = document.createElement("link"); link.rel = "stylesheet"; link.href = "assets/popupSlider.css"; document.head.appendChild(link); var sliderHTML = ""; var xhr = new XMLHttpRequest(); xhr.open("GET", "assets/popupSlider.html", false); xhr.send(); if (xhr.status != 200) { alert("Can not load the popupSlider.html. Got the error " + xhr.status + ": " + xhr.statusText); } else { sliderHTML = xhr.responseText; } var div = document.createElement("div"); div.innerHTML = sliderHTML; document.body.appendChild(div); }, close: function () { document.getElementById("cq-popup-btclose").onclick = function () { document.getElementById("cq-popup-bg").remove(); document.getElementById("cq-popup").remove(); } } };

Немного комментариев по поводу приведённого кода. Содержимое файла popupSlider.js является одним JavaScript классом Slider, который, как и в PHP, содержит конструктор и методы класса. Только в JS определение конструктора, в отличие от PHP, является обязательным.

Конструктор определяется с помощью следующей конструкции:

Function Slider(element) { //код конструктора }

Внутри конструктора должны быть прописаны действия, которые будут выполняться при создании объекта класса.

Сами методы класса будут находиться внутри прототипа и будут доступны для всех экземпляров данного JavaScript класса. JS прототип в моём случае описывается следующей конструкцией:

Slider.prototype = { //методы }

Вызываться за пределами тела класса они будут следующим образом:

Var slider = new Slider(); slider.class_method();

А внутри самого кода класса доступен следующий способ:

This.class_method();

Главное только не забывать, что в JavaScript значение this зависит от контекста вызова, поэтому в телах некоторых методов, в которых нужно было вызывать методы и свойства класса, присутствует такая конструкция:

Var self = this; self.class_method(); //чтобы обратиться к методу, находящемся на уровень выше кода описываемого метода

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

loadStatic()

Самый первый метод, вызывающийся при создании экземпляра класса в конструкторе. Отвечает за добавление в HTML кода страницы сайта HTML разметки слайдера и файла со стилями.

Сначала в памяти создаётся новый тэг link с помощью JavaScript функции document.createElement() и ему присваиваются значения всех необходимых атрибутов, в том числе и путь к CSS файлу со стилями JS слайдера. И, в конце-концов, он добавляется в HTML страницы с помощью JavaScript метода appendChild() в конец секции head, где и должны стилей.

Далее мы делаем то же самое для файла с HTML разметкой нашего слайдера на чистом JavaScript. Вот только здесь есть маленький нюанс: просто так HTML файл внутри такого же подключить нельзя, как мы сделали это с CSS файлом. Для этого есть специальные библиотеки, например, для того, чтобы подключить HTML в HTML, отлично подходит либа от w3.org — https://www.w3schools.com/howto/howto_html_include.asp

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

В итоге, я решил получать содержимое HTML файла внутри JavaScript кода и загружать его в новый div элемент, создаваемый в памяти, как я делал это ранее для подключения CSS файла в JavaScript. Сгенерированный элемент подключается в самый конец секции body HTML кода страницы сайта.

Если хотите вставить div с разметкой слайдера не просто в конец body, а в какой-то конкретный контейнер, то можете вместо следующего кода:

Var div = document.createElement("div"); div.innerHTML = sliderHTML; document.body.appendChild(div);

Прописать следующее, указав нужный идентификатор целевого контейнера (в моём случае HTML JS слайдера будет расположен в элементе с id popupSlider):

Var target = document.querySelector("#popupSlider"); target.innerHTML = sliderHTML;

Метод, который вызывается в конструкторе после loadStatic(), и нужен для инициализации свойств класса, соответствующих основным HTML элементам, к которым мы будем обращаться в следующем коде.

В конце вызывается метод navigate().

navigate()
В данном методе происходит указание действий, происходящих при клике на кнопки переключения слайдов и элементы навигации, расположенные под самим слайдером, в виде кружочков.

Сам JavaScript код смены слайдов для удобства я вынес в отдельный метод slide(), а в данном я только навешиваю его на событие click для каждой круглой кнопки в цикле.

При клике на кнопки «предыдущий слайд»/»следующий слайд» я, как видите, решил всего лишь эмулировать нажатие на соответствующий кружочек, определяя нужный относительно текущего, у которого имеется CSS класс current.

slide(element)

Метод, «отвечающий за магию» самой JavaScript карусели, в котором содержится код, меняющий слайды местами. В самом начале вызывается метод setCurrentLink(), о котором мы поговорим чуточку позже.

В качестве входного параметра в него передаётся объект кнопки навигации JS слайдера в виде кружочка.

Само переключение слайдов работает следующим образом:

  • Все слайды у нас оформлены в виде блоков одинаковых размеров, идущих друг за другом. Окно слайдера — это лишь видимая часть элемента, содержащего все слайды.
  • Мы определяем смещение левого края текущего слайда от левого края родительского элемента с помощью свойства offsetLeft.
  • И сдвигаем родительский элемент на это значение, чтобы в окне слайдера у нас отображался необходимый элемент.
  • В конце метода описано поведение для кнопок «предыдущий слайд»/»следующий слайд», оформленных в виде стрелок влево/вправо соответственно. Если текущий слайд — первый из всего списка, то кнопка перехода к предыдущему слайду скрывается. Если последний, то убираем кнопку перехода к следующему слайду.

    setCurrentLink(link)

    Данный метод нашего класса JavaScript слайдера отвечает за подсветку навигационной круглой кнопки, соответствующей текущему элементу. Т.е. если у нас выбран второй слайд, то будет подсвечиваться вторая кнопочка.

    В качестве входного параметра в функцию передаётся объект кнопки, которая должна быть выделена как текущая.

    Логика выделения текущего элемента проста:

  • Получаем объект родительского элемента, которым в нашем случае выступает контейнер с идентификатором slider-nav .
  • Получаем все навигационные элементы в виде массива ссылок.
  • Выделяем элемент, полученный на входе, путём добавления ему классу current .
  • В цикле перебираем все навигационные элементы и у всех, кроме текущего, очищаем значение класса. Это нужно для того, чтобы снять выделение с элемента, которым был текущим до данного вызова функции.
  • Самый последний метод класса, в котором определяется действие при нажатии на кнопку закрытия слайдера в виде крестика. Здесь, собственно говоря, код самый понятный из всего, содержащегося в классе JS слайдера.

    При нажатии на кнопку закрытия, доступ к которой получается по её идентификатору, происходит удаление со страницы элемента слайдера и элемента, задающего полупрозрачный фон. Они также, в свою очередь, получаются по уникальным идентификаторам.

    Сам метод вызывается внутри описанного ранее navigate(), который содержит в себе все сценарии действий, происходящих на нашем JavaScript слайдере.

    Кстати, если вы захотите сделать закрытие слайдера при клике за его пределами, то достаточно в данный метод добавить следующий код:

    Document.getElementById("cq-popup-bg").onclick = function () { document.getElementById("cq-popup-bg").remove(); document.getElementById("cq-popup").remove();

    JavaScript слайд шоу на базе разработанной библиотеки

    Иногда на практике может потребоваться сделать JS карусель с прокруткой, которую часто называют слайд шоу. В моём случае этого не требовалось, но я всё же решил сделать такую на базе итогового кода библиотеки для случая, когда это может пригодиться.

    На самом деле, реализация JavaScript слайд шоу отличается от обычного слайдера совсем незначительно. Разница заключается лишь в том, что в слайд шоу слайды переключаются автоматически с заданным временным интервалом, а в случае обычной JS карусели они меняются вручную с помощь элементов навигации.

    SlideShow: function (timeout) { var sliderCount = this.links.length; var self = this; this.slideCycle = setInterval(function () { var currentSlideNumber = document.querySelector("#slider-nav a.current").getAttribute("data-slide"); var slideId = parseInt(currentSlideNumber, 10) + 1; self.slide(document.querySelector("")); }, timeout); }

    Что здесь происходит — думаю, понятно. Для создания данного метода я скопировал код из события клика на кнопки ручного переключения слайдов и разместил его внутри вызова JavaScript функции setInterval(), которая выполняет указанное действие через заданный промежуток времени.

    Сценарий действия передаётся первым аргументом в виде анонимной функции, а временной интервал — вторым, который я решил сделать в виде переменной, значение которой передаётся при вызове slideShow().

    Единственная модификация кода внутри setInterval(), которая потребовалась, — это определение количества слайдов и сравнение с ним индекса текущего слайда для зацикленности автоматического переключения.

    Ну, и для того, чтобы данный код заработал, сам метод необходимо вызвать. Я решил сделать это всё в том же navigate(), который как раз и является сборником всяких сценариев. Вызов я разместил в самом конце, передав в качестве аргумента значение временного интервала для автоматической смены слайдов в нашем JS слайд шоу (я выбрал 2000 милисекунд или 2 секунды, вы можете по необходимости изменять это число):

    Self.slideShow(2000);

    После этого проверяйте работу JavaScript слайдера, не забыв при этом почистить и браузера.

    По идее, всё должно работать. Если нет — изучайте ошибки в консоли браузера и делитесь ими в комментариях.

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

    При работе с различными библиотеками JS каруселей картинок и отзывов я заметил, что данную практику разработчики активно применяют, но с некоторым дополнением. Во всех увиденных мною решениях автоматический показ слайдов прерывается, если пользователь сделал ручное переключение. Поэтому я решил сделать подобное и в своей библиотеке.

    Для прерывания автоматического показа слайдов JavaScript карусели я решил воспользоваться стандартной JS функцией clearInterval(), которой в качестве аргумента передаю идентификатор временного интервала, возвращаемого функцией setInterval() при его установке.

    В итоге, получился следующий код, который я решил не оформлять отдельным методом:

    ClearInterval(self.slideCycle);

    И разместил его в местах описания действий при кликах на различные элементы навигации, т.е. в следующих:

    Link.addEventListener("click", function (e) {...}); self.prevBtn.addEventListener("click", function (e) {...}); self.nextBtn.addEventListener("click", function (e) {...});

    Вызов clearInterval() лучше делать поближе к самому событию клика, главное, чтобы перед ним, а не после.

    Интеграция JavaScript слайдера на сайт

    Итак, наш слайдер на чистом JS готов. Осталось теперь только подключить его на сайт.

    Для этого необходимо выполнить последовательно следующие шаги, которые являются стандартными действиями при интеграции каких-либо сторонних JavaScript библиотек вообще.

    Шаг 1 . Копируем файлы библиотеки к себе на сайт в отдельный каталог.
    Шаг 2 . Добавляем следующий код в HTML страниц, на которых необходимо будет отображение слайдера, разместив его перед закрывающимся тэгом body:

    Шаг 3 . Размещаем следующий код вызова JS карусели в каком-либо существующем JavaScript файле, который подключается на странице после подключения самого слайдера:

    Var aSlider = new Slider("#slider");

    Как видите, данный код, — это, по сути, создание объекта класса Slider, который содержится в popupSlider.js. Именно поэтому его вызов должен быть только после подключения самого файла класса на страницу.

    Добавление новых слайдов в JavaScript карусель

    Здесь всё очень просто. Поскольку слайды у нас берутся из отдельной директории библиотеки slides , то при добавлении новых картинок нужно будет просто закинуть в неё нужные файлы, задав им предварительно такой же размер, как и у других.

    А затем в коде файла assets/popupSlider.html добавить новый блок в контейнер с id slider-wrapper :

    Text

    В принципе, можете просто скопировать аналогичный существующий и изменить в нём путь к файлу изображения и текст подписи (если она вообще будет нужна).

    Также необходимо будет добавить новый элемент навигации в виде кружочка, т.к. на данный момент автоматическое его добавление пока не реализовано. Для этого нужно будет добавить следующий код в контейнер с id slider-nav , прописав его в самом конце:

    Значение атрибута data-slide должно быть больше самого большого у остальных элементов. Достаточно всего лишь увеличить максимальное текущее на единицу.

    Упаковка JS карусели в единый скрипт

    Всё, слайдер на JavaScript готов и подключен. Я лично рекомендую использовать данный вариант на практике, если он вам вообще пригодится 🙂

    Для ускорения работы его, кстати, можете ещё дополнительно сжать статические компоненты: CSS, HTML и JavaScript файлы. Я не стал этого делать и предлагать вам минифицированный код, потому что систем сборок фронтэнда сейчас очень много: Gulp, Grunt, Webpack и другие. И у каждой из них свои алгоритмы сжатия и подключения файлов.

    К тому же, минифицированные результаты на разных ОС могут работать по-разному. В общем, причин много.

    Да и сами исходники у меня вышли, я считаю, не такие уж тяжеловесные, что нуждаются в данной процедуре. Но если же вам они будут необходимы, то настройте минификацию самостоятельно с учётом вашей ОС и сборщика.

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

    Тогда вариант единого скрипта JavaScript карусели вам придётся как нельзя кстати, т.к. весь контент будет содержаться прямо в нём, в том числе и HTML/CSS код, который в случае библиотеки хранится в отдельных файлах.

    Скрипт в моём случае состоит из двух частей. В первой части располагалось содержимое файла popupSlider.js, которое я второй раз не буду приводить. Вставьте его самостоятельно, убрав из кода класса описание метода loadStatic() и его вызов, т.к. они нам не понадобятся.

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

    Там у нас будет происходить добавление на страницу HTML/CSS кода JS карусели и создание объекта класса Slider, что равносильно активации самого слайдера.

    Схематично код выглядит следующим образом:

    /* содержимое popupSlider.js без описания метода loadStatic() и его вызова */ document.addEventListener("DOMContentLoaded", function(){ var str = "\ \ /*css код*/ \ /* html код */ "; var div = document.createElement("div"); div.innerHTML = str; document.body.appendChild(div); var aSlider = new Slider("#slider");

    Поскольку в моём случае вариант загрузки файлов на сервер был вообще закрыт, мне пришлось загрузить файлы картинок элементов управления JavaScript каруселью на облако и вместо путей к ним в HTML и CSS коде прописать ссылки, сгенерированные при сохранении.

    Если у вас таких сложностей нет, то можете ничего не менять, но не забыть скопировать каталоги slides и controls библиотеки на сервер и указать правильные пути к ним.

    Самописный JS слайдер — перспективы развития

    Честно скажу, что заниматься целенаправленной поддержкой и развитием созданного мною решения я заниматься не планирую 🙂 На данный момент подобных слайдеров существует вагон и маленькая тележка, которые, в отличие от моего имеют свою историю, тщательно оттестированы и поддерживаются обширным комьюнити пользователей и разработчиков.

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

    Так что если вам, как и мне, нужна будет кодовая база для экспериментов и вы располагаете хоть каким-то лишним свободным временем — копируйте себе код описанного мною JavaScript слайдера или присоединяйтесь к контрибьюторам на GitHub. Репозиторий открытый, а ссылку на него я предоставил в начале статьи.

    Если вы хотите прокачать свои фронтэнд скилы на моём творении, могу вам даже подкинуть небольшой список правок и доработок, в которых нуждается код и которые, возможно, будут интересны вам в плане их реализации:

  • сделать внешний конфиг, чтобы можно было удобно настраивать слайдер;
  • сделать возможность встраивания слайдера внутрь страницы (сейчас оформлен только в виде попапа);
  • асинхронная загрузка HTML кода (сейчас сделана синхронная, которая многими браузерами помечается как устаревший вариант);
  • оформить библиотеку в виде пакета, NPM, Bower или другого пакета, чтобы его можно было устанавливать и оперировать зависимостями с помощью пакетных менеджеров;
  • сделать вёрстку адаптивной для использования JS карусели на различных устройствах;
  • сделать переключение слайдов по событию Swipe для мобильных пользователей.
  • Приведённый мною список правок, естественно, не конечный и может быть дополнен. Пишите о своих предложениях, мыслях и пожеланиях в комментариях под статьёй и делитесь со своими друзьями через социальные сети, чтобы их также привлечь к разработке.

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

    Вступайте в сообщества проекта, подписывайтесь на обновления и можете даже помочь мне материально с помощью формы прямо под самой статьёй, если я чем-то смог вам помочь или вам просто нравится то, чем я занимаюсь 🙂

    У меня всё! Всем добра! 🙂

    P.S. : если вам нужен сайт либо необходимо внести правки на существующий, но для этого нет времени и желания, могу предложить свои услуги.

    Более 5 лет опыта профессиональной разработки сайтов. Работа с PHP , OpenCart , WordPress , Laravel , Yii , MySQL , PostgreSQL , JavaScript , React , Angular и другими технологиями web-разработки.

    Опыт разработки проектов различного уровня: лендинги , корпоративные сайты , Интернет-магазины , CRM , порталы . В том числе поддержка и разработка HighLoad проектов . Присылайте ваши заявки на email [email protected] .

    /* Тут начинается наша карусель. Блок.carousel-wrapper спозиционирован относительно, абертки.carousel-item абсолютно. . */ .carousel-wrapper{ position:relative; /* Абсолютно спозиционированные блоки получают высоту и ширину от родителя. Мы сделали их прозрачными по умолчанию, и потом они будут плавно появляться по нажатию на ссылки.arrow-prevи.arrow-next. */ .carousel-item{ position:absolute; top:0; bottom:0; left:0; right:0; padding:25px50px; opacity:0; transition:all0.5sease-in-out; /* Заметили padding слева и справа по 50px? Таким способом мы можем позиционировать наши ссылки! Каждая будет по 50px шириной. Кроме того, я использую пустые ссылки с фоновым рисунком таким образом, что ссылки выглядят как стрелки. Проверьте, поменяли ли вы URL ссылок с оригинальным URL, чтобы ваши ссылки не были просто прозрачными прямоугольниками. */ .arrow{ position:absolute; top:0; display:block; width:50px; height:100%; -webkit-tap-highlight-color:rgba(0,0,0,0); background:url("/carousel-arrow-dark.png")50%50%/20pxno-repeat; /* Давайте вернем нашу стрелку налево. */ &.arrow-prev{ left:0; } /* А вторую направо. Поскольку я использую одно и то же изображение для стрелки, я поворачиваю его на 180 градусов. */ &.arrow-next{ right:0; -webkit-transform:rotate(180deg); transform:rotate(180deg); } } /* Мне очень нравится, как слайды карусели смотрятся на темном фоне, и если блок.carousel-itemимеет класс "light", мы изменим его текст на белый и используем белые стрелки вместо серых. Проверьте еще раз, правильно ли указан путь к изображению стрелки */ &.light{ color:white; .arrow{ background:url("/carousel-arrow-light.png")50%50%/20pxno-repeat; } } /* Напишем медиа-запрос для изменения размера стрелок на устройствах с меньшим размером экрана.*/ @media(max-width:480px){ .arrow,&.light.arrow{ background-size:10px; background-position:10px50%; } } } /* Установим целям для ссылок значение display: none; Таким образом, мы избавляемся от постоянного перепрыгивания браузера в самый верх карусели при каждом нажатии на стрелки. Это свойство действует для любых элементов, чей идентификатор начинается на "target-item". */ { display:none; } /* Выше мы сделали все наши слайды карусели прозрачными, а это значит, что во время загрузки карусели мы будем получать вместо нее большое пустое поле. Изменим значение прозрачности для первого слайда на 1 для отображения. Так же устанавливаем z-index значение 2, позиционируя его выше остальных слайдов. */ .item-1{ z-index:2; opacity:1; } /* Но нам не нужно, чтобы первый слайд всегда имел значение прозрачностиopacity: 1; в противном случае нам придется пробираться через этот слайд, во время ротации остальных. */ *:target~.item-1{ opacity:0; } /* ..но если #target-item-1 в фокусе, и мы хотим показать первый слайд, тогда выбираем его с помощью значка ~ и устанавливаем прозрачность опять в 1:-) */ #target-item-1:target~.item-1{ opacity:1; } /* Если другие target-item-# в фокусе, выбираем их используя ~ селектор, плавно показываем, и размещаем их сверху с помощьюz-index: 3. Тут вы можете добавить дополнительные spanс идентификатором target-item, если их у вас будет больше трех. Может сразу и добавить 10 штук.. */ #target-item-2:target~.item-2,#target-item-3:target~.item-3{ z-index:3; opacity:1; } }



    
    Top