diff --git a/QuickStart.en.md b/QuickStart.en.md new file mode 100644 index 0000000..4075643 --- /dev/null +++ b/QuickStart.en.md @@ -0,0 +1,277 @@ +## Quick start for static page creation with BEM + +The article describes step-by-step implementation of a static page using [BEM methodology](https://bem.info/method/). + +## Expected outcome + +A page that contains an input field, a button, and a greeting text. A value from the input field will be added to the greeting text when the user clicks the button. + + + +## First steps to start + +### Minimal requirements + +An installed platform [Node.js 0.10](http://nodejs.org). + +### A local copy and environment setting + +A [template repository](https://github.com/bem/project-stub) is the quickest and easiest way to start your BEM project. It contains the minimal configuration files and folders. + +1. Make local copy of `project-stub`. + + **NB** The document describes an installation procedure based on the revision [13ae0e18ef8f48bc552b4944f7e5971c5b5f4768](https://github.com/bem/project-stub/ commit/13ae0e18ef8f48bc552b4944f7e5971c5b5f4768). The installation procedure of next versions may differ. + + ```bash + git clone https://github.com/bem/project-stub.git start-project + cd start-project + git checkout 13ae0e18ef8f48bc552b4944f7e5971c5b5f4768 + npm install + ``` + +2. Run a server with help of [ENB](https://ru.bem.info/tools/bem/enb-bem-techs/)(this article is available only in russian language). + + ```bash + node_modules/.bin/npm start + ``` + +3. Check the result on [http://localhost:8080/desktop.bundles/index/index.html](http://localhost:8080/desktop.bundles/index/index.html). + + A page with library blocks examples should open: + +  + +## Step-by-step instruction for the project creation + +1. [Create a page](#page_creation) + 1.1 [Describe the page in BEMJSON file](#BEMJSON_declaration) +2. [Create a block](#block_creation) +3. [Implement hello block](#block_hello_modification) + 3.1 [Use JavaScript technology](#JS_modification) + 3.2 [Use BEMHTML technology](#BEMHTML_modification) + 3.3 [Use CSS technology](#CSS_modification) + +When all steps have been completed you can watch the [result](#result). + + + +### 1. Create a page + +Pages source code are stored in the `start-project/desktop.bundles` directory. The main page `index.html` contains blocks implementations of [bem-components](https://en.bem.info/libs/bem-components/) library. + +Create a new page to start your own project. + +1. Create `hello` directory in the `desktop.bundles`. +2. Add `hello.bemjson.js` file into `hello` directory. + + + +#### 1.1 Describe the page in BEMJSON file + +A [BEMJSON file](https://en.bem.info/technology/bemjson/) describes a page structure in BEM terms: blocks, elements and modifiers. + +1. Add a description of `hello` block in the `desktop.bundles/hello/hello.bemjson.js` file. + **hello** block is an entity that will contain all necessary elements for the project. + + ```js + { + block: 'page', + title: 'hello', + head: [ + { elem: 'css', url: '_hello.css' } + ], + scripts: [{ elem: 'js', url: '_hello.js' }], + mods: { theme: 'islands' } + content: [ + { + block: 'hello' + } + ] + } + ``` + +2. Place `greeting` element with the greeting text (**content** field) into `hello` block. + **greeting** element is a sub-entity, that contains the greeting phrase and ready-made blocks implementations of `bem-components` library. + + ```js + content: [ + { + block: 'hello', + content: [ + { + elem: 'greeting', + content: 'Hello, %user%!' + `bem-components` library} + ] + } + ] + ``` + +3. To create an input field and a button use `input` and `button` blocks from `bem-components` library. Add these blocks to `greeting` element. + + ```js + ({ + block: 'page', + title: 'hello', + head: [ + { elem: 'css', url: '_hello.css' } + ], + scripts: [{ elem: 'js', url: '_hello.js' }], + mods: { theme: 'islands' }, + content: [ + { + block: 'hello', + content: [ + { + elem: 'greeting', + content: 'Hello, %user%!' + }, + { + block: 'input', + mods: { theme: 'islands', size: 'm' }, + name: 'name', + placeholder: 'User name' + }, + { + block : 'button', + mods : { theme : 'islands', size : 'm', type : 'submit' }, + text : 'Click' + } + ] + } + ] + }) + ``` + +To consider that the page shows all necessary objects, open [http://localhost:8080/desktop.bundles/hello/hello.html](http://localhost:8080/desktop.bundles/hello/hello.html). + +You can provide additional changes to existing blocks on your [redefinition level](https://en.bem.info/tools/bem/bem-tools/levels/). + + + +### 2. Create a block + +To provide correct work to all object on the page, it is necessary to specify additional functionality of `hello` block on your redefinition level. + +1. Create a directory of `hello` block on `desktop.blocks` level. +2. Create [the implementation technology files](https://bem.info/method/filesystem/) (`CSS`, `JS`, `BEMHTML`) required to the block in **hello** directory. + A block directory name and its nested files must coincide with block name specified in a BEMJSON file. + + * `hello.js` – describes dynamic page functionality + * `hello.bemhtml` – a template for generation of the block HTML representation + * `hello.css` – changes a custom design on the page + + + +### 3. Implement `hello` block + +To implement the block in BEM terms, use the created technology files. + + + +#### 3.1 Implement `hello` block in JavaScript technology + +1. Describe a block reaction depending on a user action using `onSetMod` property in the `desktop.blocks/hello/hello.js` file. A click on the button adds the user name from the input field into the greeting phrase. +JavaScript code is written using [i-bem.js](https://ru.bem.info/technology/i-bem/) (this article is available only in russian language) declarative JavaScript framework. + + ```js + onSetMod: { + 'js': { + 'inited': function() { + this._input = this.findBlockInside('input'); + + this.bindTo('submit', function(e) { + e.preventDefault(); + this.elem('greeting').text('Hello, ' + this._input.getVal() + '!'); + }); + } + } + } + + ``` + +2. To represent current JavaScript code, use [YModules](https://bem.info/tools/bem/modules/) modular system . + + ```js + modules.define( + 'hello', // a block name + ['i-bem__dom'], // dependence connection + function(provide, BEMDOM) { // a function that received names of the used modules + provide(BEMDOM.decl('hello', { // a block declaration + onSetMod: { // a constructor that describes reaction on an event + 'js': { + 'inited': function() { + this._input = this.findBlockInside('input'); + + this.bindTo('submit', function(e) { // the event that causes reaction + e.preventDefault(); // prevention of event work by default (form data sending to the server with page reload) + this.elem('greeting').text('Hello, ' + this._input.getVal() + '!'); + }); + } + } + } + })); + }); + ``` + + + +#### 3.2 Implement `hello` block in BEMHTML technology + +[BEMHTML](https://bem.info/technology/bemhtml/current/rationale/) – technology that processes BEMJSON declaration to create HTML layout of a web page. + +1. Write [BEMHTML tempate](https://bem.info/technology/bemhtml/current/reference/) and specify that `hello` block has JavaScript implementation. +2. Implement `hello` block with form, adding `tag` mode. + +```js +block('hello')( + js()(true), + tag()('form') +); +``` + + + +#### 3.3 Implement `hello` block in CSS technology + +Create your own CSS rules for `hello` block. For example: + +```js +.hello +{ + color: green; + padding: 10%; +} + +.hello__greeting +{ + margin-bottom: 12px; +} + +.hello__input +{ + margin-right: 12px; +} +``` +To change the position of the block on the page and leave it in its original form in the library, mix element using the method `mix` in the input data (BEMJSON). + +```js +{ + block: 'input', + mods: { theme: 'islands', size: 'm' }, + mix: { block: 'hello', elem: 'input' }, // mix element to add CSS rules + name: 'name', + placeholder: 'User name' +} +``` +[Code sample](https://gist.github.com/4exova/683b6da16aa7aa0399f3) hello.bemjson.js. + + + +## The final result + +To see the result of the project, please refresh the page: + + http://localhost:8080/desktop.bundles/hello/hello.html + +Since the project consists only of one page, in full build was no need. Description of a more complex project is in [Starting your own project](https://bem.info/tutorials/start-with-project-stub/) article. diff --git a/QuickStart.md b/QuickStart.md index 919a4a2..033bb7d 100644 --- a/QuickStart.md +++ b/QuickStart.md @@ -1,264 +1,276 @@ -# Как создать динамическую страницу с БЭМ +## Быстрый старт по созданию статической страницы с БЭМ -В этой статье мы рассмотрим пример реализации динамической функциональности страницы по [БЭМ-методологии](http://ru.bem.info/method/). +В этой статье рассмотрен пример реализации статической страницы по [БЭМ-методологии](https://ru.bem.info/method/). -# Что должно получиться +## Что должно получиться -Итогом проделанной работы будет страница с приветствием пользователя. Страница будет состоять из поля ввода, кнопки и приветствия. После того, как пользователь введет имя в поле и нажмет кнопку, его имя автоматически подставится в приветствие. +Страница приветствия пользователя, содержащая поле ввода, кнопку и текст. При нажатии на кнопку страница обновляется и текст дополняется значением, введенным в поле. -# Установка + -**Требования к установке** +## С чего начать -Для начала работы с любым БЭМ-проектом нужен [Node.js](http://nodejs.org). +### Минимальные требования -Устанавливаем свой собственный БЭМ-проект. В этом нам поможет [шаблонный репозиторий](https://github.com/bem/project-stub), который содержит необходимый минимум конфигурационных файлов и папок. Делаем локальную копию `project-stub`. +Установленная платформа [Node.js 0.10](http://nodejs.org). - git clone https://github.com/bem/project-stub.git start-project - cd start-project - npm install +### Локальная копия и настройка окружения -Собираем проект с помощью [ENB](http://enb-make.info/): +Для быстрого и простого создания БЭМ-проекта потребуется [шаблонный репозиторий](https://github.com/bem/project-stub), содержащий необходимый минимум конфигурационных файлов и папок. - node_modules/.bin/enb make +1. Сделайте локальную копию `project-stub`. -Запускаем сервер: + **NB** В данном документе описана процедура установки для ревизии [13ae0e18ef8f48bc552b4944f7e5971c5b5f4768](https://github.com/bem/project-stub/ commit/13ae0e18ef8f48bc552b4944f7e5971c5b5f4768). Процесс установки последующих версий может отличаться. - node_modules/.bin/enb server + ```bash + git clone https://github.com/bem/project-stub.git start-project + cd start-project + git checkout 13ae0e18ef8f48bc552b4944f7e5971c5b5f4768 + npm install + ``` -При изменении конфигурации проекта нужно перезапускать сервер. Текущий процесс прерывается (`Ctrl+C`) и снова возобновляется командой запуска. +2. Запустите сервер с помощью [ENB](https://ru.bem.info/tools/bem/enb-bem-techs/): -Открываем браузер, чтобы проверить запустился ли сервер на компьютере: + ```bash + node_modules/.bin/npm start + ``` - http://localhost:8080/desktop.bundles/index/index.html +3. Проверьте результат по ссылке [http://localhost:8080/desktop.bundles/index/index.html](http://localhost:8080/desktop.bundles/index/index.html). -По умолчанию эта страница содержит примеры блоков библиотеки `bem-components`. + Должна открыться страница с примерами блоков библиотеки: -Альтернативный вариант для сборки проекта –– [bem-tools](http://ru.bem.info/tools/bem/bem-tools/). Результаты сборки в обоих случаях одинаковы. +  -Про сборку проекта при помощи `bem-tools` вы можете почитать, пройдя по это ссылке http://ru.bem.info/tools/bem/bem-tools/commands/#bem-make. +## Пошаговая инструкция по созданию проекта -# Пошаговая инструкция по созданию проекта +Процедура разработки страницы приветствия состоит из следующих этапов: -Этот раздел содержит пошаговую информацию по созданию динамической страницы. +1. [Создание страницы](#page_creation) + 1.1 [Описание страницы в BEMJSON-файле](#BEMJSON_declaration) +2. [Создание блока](#block_creation) +3. [Реализация блока hello](#block_hello_modification) + 3.1 [В технологии JavaScript](#JS_modification) + 3.2 [В технологии BEMHTML](#BEMHTML_modification) + 3.3 [В технологии CSS](#CSS_modification) -* [Создание страницы](#page_creation) –– рассмотрим варианты создания страницы. -** [Описание страницы в BEMJSON-файле](#BEMJSON_declaration) –– опишем страницу в БЭМ-терминах. -* [Создание блока](#block_creation) –– самостоятельно создадим блок. -** [Создание блока с файлом определенной технологии](#block_using_concrete_tech) –– рассмотрим возможность создавать файлы блока конкретных технологий. -* [Переопределение блока `hello`](#block_hello_modification) –– внесем необходимые изменения в файлы технологий блока. -** [Реализация блока в технологии JS](#JS_modification) –– реализуем блок в технологии JavaScript. -** [Реализация блока в технологии BEMHTML](#BEMHTML_modification) –– реализуем блок в технологии BEMHTML. -** [Реализация блока в технологии CSS](#CSS_modification) –– реализуем блок в технологии CSS. -* [Сборка проекта](#build) –– запустим сборку проекта. +После выполнения всех шагов можно смотреть [результат](#result). -## Создание страницы +### 1. Создание страницы -Макеты страниц размещаются в каталоге `desktop.bundles`. Данный каталог содержит одну директорию –– `index`. Вы можете продолжать работу с этой директорией. Для этого необходимо заменить декларацию файла `index.bemjson.js`. Пример описания BEMJSON-файла мы рассмотрим ниже. +Исходники страниц размещаются в каталоге `start-project/desktop.bundles`. Изначально в проекте присутствует главная страница `index.html` с примерами блоков библиотеки [bem-components](https://ru.bem.info/libs/bem-components/). -Альтернативный вариант –– создание новой страницы, используя команду [bem-tools](http://ru.bem.info/tools/bem/bem-tools/): +Для начала работы с собственным проектом создайте новую страницу. Разместите в `desktop.bundles` каталог с именем `hello` и добавьте в него файл `hello.bemjson.js`. - bem create -l desktop.bundles -b hello - -* `-l desktop.bundles` –– указывает на уровень переопределения `desktop.bundles`; -* `-b hello` –– определяет имя блока страницы, в нашем случае `hello`. - -Выбирайте удобный для вас вариант. Дальше мы продолжим создание проекта на основе страницы `hello`. -### Описание страницы в BEMJSON-файле - -#### Создаем свой блок - -Первым делом нам нужно добавить на страницу блок приветствия. Для того, чтобы разместить его на странице, добавим блок **hello** в файл `desktop.bundles/hello/hello.bemjson.js`. - -{ block: 'hello' } - -Дальше внутрь блока **hello** поместим элемент **greeting** с приветствием пользователя: - -``` -{ - elem: 'greeting', - content: 'Привет, %пользователь%!' -} -``` - -#### Используем готовые блоки - -Кроме приветствия на странице должно быть поле ввода и кнопка. Блоки **input** и **button** мы берем готовые из библиотеки [bem-components](http://ru.bem.info/libs/bem-components/v2/). И вкладываем их в элемент **greeting**. - -``` -{ - elem: 'greeting', - content: 'Привет, %пользователь%!' - }, - { - block: 'input', - mods: {theme: 'islands', size: 'm'}, - placeholder: 'Имя пользователя' - }, - { - block : 'button', - text : 'Нажать', - mods : { theme : 'islands', size : 'm' } - } -} -``` - -Если вы хотите внести какие-либо изменения в готовые блоки, это можно сделать на своем уровне переопределения. Подробнее об этом можно почитать, пройдя по ссылке http://ru.bem.info/tools/bem/bem-tools/levels/. +#### 1.1 Описание страницы в BEMJSON-файле + +[BEMJSON-файл](https://ru.bem.info/technology/bemjson/) – это структура страницы, описанная в терминах блоков, элементов и модификаторов. + +1. Добавьте на своем проекте описание блока `hello` в файле `desktop.bundles/hello/hello.bemjson.js`. + Блок **hello** – это сущность, которая содержит в себе все необходимые для проекта элементы. + + ```js + { + block: 'page', + title: 'hello', + head: [ + { elem: 'css', url: '_hello.css' } + ], + scripts: [{ elem: 'js', url: '_hello.js' }], + mods: { theme: 'islands' } + content: [ + { + block: 'hello' + } + ] + } + ``` -Все необходимые блоки добавлены. Так будет выглядеть полный код страницы `desktop.bundles/hello/hello.bemjson.js`: +2. Поместите элемент `greeting` с текстом приветствия пользователя (поле **content**) в блок **hello**. + Элемент **greeting** – это подсущность, в которую вкладывается фраза приветствия и готовые реализации блоков. -``` -({ - block: 'page', - title: 'hello', - head: [ - { elem: 'css', url: '_hello.css' } - ], - scripts: [{ elem: 'js', url: '_hello.js' }], + ```js content: [ - { - block: 'content', - content: [ - { - block: 'hello', - name: 'BEMHTML', - content: [ - { - elem: 'greeting', - content: 'Привет, %пользователь%!' - }, { - block: 'input', - mods: {theme: 'islands', size: 'm'}, - placeholder: 'Имя пользователя' - }, { - block : 'button', - text : 'Нажать', - mods : { theme : 'islands', size : 'm' } - } - ] - } - ] - } - ] -}) -``` + { + block: 'hello', + content: [ + { + elem: 'greeting', + content: 'Привет, %пользователь%!' + } + ] + } + ] + ``` + +3. Чтобы создать поле ввода и кнопку возьмите готовые реализации блоков `input` и `button` из библиотеки `bem-components` и добавьте их в элемент `greeting`. + + ```js + ({ + block: 'page', + title: 'hello', + head: [ + { elem: 'css', url: '_hello.css' } + ], + scripts: [{ elem: 'js', url: '_hello.js' }], + mods: { theme: 'islands' }, + content: [ + { + block: 'hello', + content: [ + { + elem: 'greeting', + content: 'Привет, %пользователь%!' + }, + { + block: 'input', + mods: { theme: 'islands', size: 'm' }, + name: 'name', + placeholder: 'Имя пользователя' + }, + { + block : 'button', + mods : { theme : 'islands', size : 'm', type : 'submit' }, + text : 'Нажать' + } + ] + } + ] + }) + ``` -Чтобы проверить запустился ли файл, откройте браузер по адресу: +Чтобы убедиться, что страница отображает все необходимые объекты, откройте [http://localhost:8080/desktop.bundles/hello/hello.html](http://localhost:8080/desktop.bundles/hello/hello.html). - http://localhost:8080/desktop.bundles/hello/hello.html +Если вы хотите внести какие-либо изменения в существующие блоки, это можно сделать на своем [уровне переопределения](https://ru.bem.info/tools/bem/bem-tools/levels/). -## Создание блока - -На уровне `desktop.blocks` создаем директорию блока **hello**. По умолчанию блок будет представлен набором файлов для всех технологий реализации (`CSS/STYL`, `JS`, `BEMHTML`). - - bem create -l desktop.blocks -b hello - -* `-l desktop.blocks` –– указывает на уровень переопределения `desktop.blocks`; -* `-b hello` –– задает имя директории блока, в нашем случае `hello`. +### 2. Создание блока -Другой способ –– создание блока вручную. Для этого на уровне `desktop.blocks` создадим папку **hello** и разместим в ней необходимые для проекта файлы технологий реализации блока. +Чтобы элементы на странице работали должным образом необходимо прописать дополнительную функциональность блока `hello` на своем уровне переопределения. - +1. Создайте вручную каталог блока `hello` на уровне `desktop.blocks`. +2. Разместите в нем необходимые для проекта [файлы технологий реализации блока](https://ru.bem.info/method/filesystem/) (`CSS`, `JS`, `BEMHTML`). Название каталога блока и вложенных в него файлов должны совпадать с именем блока, которое прописано в BEMJSON-файле. -### Создание блока с файлом определенной технологии - -Блок можно создавать с файлом определенной технологии. Более подробную информацию об этом можно найти в командах [bem-tools](http://ru.bem.info/tools/bem/bem-tools/commands/#Создание-блока-в-определённой-технологии). + * `hello.js` – описывает динамическую функциональность страниц; + * `hello.bemhtml` – шаблоны для генерации HTML-представления блока; + * `hello.css` – изменяет внешний вид объектов на странице. -## Переопределение блока `hello` -Чтобы наш проект заработал должным образом, нужно переопределить файлы технологий реализации. +### 3. Реализация блока hello + +Для представления блока в терминах БЭМ необходимо описать его в файлах технологий реализации. -### Реализация блока в технологии JS +#### 3.1 Реализация блока в технологии JavaScript -В файле `desktop.blocks/hello/hello.js` описываем реакцию блока на выполнение действия, в нашем случае нажатие кнопки, с помощью специального свойства `onSetMode`. При нажатии кнопки в приветствие будет автоматически подставляться имя пользователя, введенное в поле **input**. +1. Опишие в файле `desktop.blocks/hello/hello.js` реакцию блока на действие пользователя с помощью специального свойства `onSetMode`. При нажатии кнопки в текст приветствия будет подставляться имя пользователя, введенное в поле input. + JavaScript-код написан с использованием декларативного JavaScript-фреймворка – [i-bem.js](https://ru.bem.info/technology/i-bem/). -``` -onSetMod: { - 'js': { - 'inited': function() { - this._input = this.findBlockInside('input'); - this._button = this.findBlockInside('button'); - - this._button.on('click', function() { - this.elem('greeting').text('Hello, ' + this._input.getVal() + '!'); - }, this); + ```js + onSetMod: { + 'js': { + 'inited': function() { + this._input = this.findBlockInside('input'); + + this.bindTo('submit', function(e) { + e.preventDefault(); + this.elem('greeting').text('Привет, ' + this._input.getVal() + '!'); + }); + } } } -} - -``` -Данный JavaScript заворачиваем в [модульную систему YModules](http://ru.bem.info/tools/bem/modules/): -``` -modules.define( - 'hello', - ['i-bem__dom'], - function(provide, BEMDOM) { - provide(BEMDOM.decl('hello', { - onSetMod: { - 'js': { - 'inited': function() { - this._input = this.findBlockInside('input'); - this._button = this.findBlockInside('button'); - - this._button.on('click', function() { - this.elem('greeting').text('Hello, ' + this._input.getVal() + '!'); - }, this); + ``` + +2. Используйте модульную систему [YModules](https://ru.bem.info/tools/bem/modules/), чтобы представить данный JavaScript-код: + + ```js + modules.define( + 'hello', // имя блока + ['i-bem__dom'], // подключение зависимости + function(provide, BEMDOM) { // функция, в которую передаются имена используемых модулей + provide(BEMDOM.decl('hello', { // декларация блока + onSetMod: { // конструктор для описания реакции на события + 'js': { + 'inited': function() { + this._input = this.findBlockInside('input'); + + this.bindTo('submit', function(e) { // событие, на которое будет реакция + e.preventDefault(); // предотвращение работы события по умолчанию (отправка данных формы на сервер с перезагрузкой страницы) + this.elem('greeting').text('Привет, ' + this._input.getVal() + '!'); + }); + } } } - } - })); - }); -``` + })); + }); + ``` -### Реализация блока в технологии BEMHTML +#### 3.2 Реализация блока в технологии BEMHTML -Для того, чтобы наш JavaScript применился пишем BEMHTML-шаблон, в котором указываем, что наш блок **hello** имеет JavaScript-реализацию: +[BEMHTML](https://ru.bem.info/technology/bemhtml/current/rationale/) – технология, которая преобразует входные данные из BEMJSON-файла в HTML. -``` -block hello, js: true +1. Напишите [BEMHTML-шаблон](https://ru.bem.info/technology/bemhtml/current/reference/) и укажите в нем, что блок `hello` имеет JavaScript-реализацию. +2. Оберните блок `hello` в форму, добавив моду `tag`. + +```js +block('hello')( + js()(true), + tag()('form') +); ``` -### Реализация блока в технологии CSS +#### 3.3 Реализация блока в технологии CSS -Для блока **hello** создаем свои CSS-правила. К примеру, такие: +Для блока `hello` создайте свои CSS-правила. Например, такие: -``` +```js .hello - color: green -``` - - -## Сборка проекта - -При обновлении страницы сервер пересобирал только ту часть проекта, которую затронули наши изменения. Для сборки всего проекта целиком воспользуемся командой `ENB`: +{ + color: green; + padding: 10%; +} - $ node_modules/.bin/enb make +.hello__greeting +{ + margin-bottom: 12px; +} -# Результат +.hello__input +{ + margin-right: 12px; +} +``` +Чтобы изменить положение блока на странице используйте метод и при этом оставить его в первоначальном виде в библиотеке, подмешайте элемент с помощью метода `mix` во входных данных (BEMJSON). -Обновляем страницу в браузере с адресом +```js +{ + block: 'input', + mods: { theme: 'islands', size: 'm' }, + mix: { block: 'hello', elem: 'input' }, // подмешиваем элемент для добавления CSS-правил + name: 'name', + placeholder: 'Имя пользователя' +} +``` +[Полный код](https://gist.github.com/4exova/981a36cedceffa472742) BEMJSON-файла. - http://localhost:8080/desktop.bundles/hello/hello.html + -и видим страницу приветствия: +## Результат -*скрин* +Чтобы увидеть итог проделанной работы обновите страницу: -Заполняем поле ввода любым именем, например, Вася, нажимаем кнопку и получаем результат: + http://localhost:8080/desktop.bundles/hello/hello.html -*скрин* +Поскольку проект состоял всего из одной страницы, то необходимость в полной сборке отсутствует. Информация о том, как написать более сложный проект приведена в статье [Создаем свой проект на БЭМ](https://ru.bem.info/tutorials/start-with-project-stub/). diff --git a/RationaleForJS.md b/RationaleForJS.md new file mode 100644 index 0000000..853dd70 --- /dev/null +++ b/RationaleForJS.md @@ -0,0 +1,315 @@ +## БЭМ для JavaScript + +В разработке интерфейсов важно помнить, что сайт – это растущий организм. +Ситуации, когда в коде сайта нет определенной структуры и фиксированных правил написания, приводят к сложностям в процессе разработки и поддержки. Чтобы обеспечить долгую и безоблачную жизнь вашему проекту следует начать с общего подхода, с методологии. + +### Зачем в JavaScript компонентный подход + +Те времена, когда веб-сайты состояли из статического контента и нескольких скриптов для обработки, остались позади. + +Современные пользователи становятся все требовательнее: веб должен быть быстрыми, динамическим, удобным, интерактивным и уметь адаптироваться под запросы потребителя. Сайты уже не представляют собой несколько страниц текста с картинками и ссылками; сейчас они обрабатывают информацию и решают многие задачи. Возрастание роли веб-приложений очевидны – они не требуют установки у пользователя и их гораздо проще настраивать под этого самого пользователя. Программами «из коробки» теперь все чаще можно воспользоваться непосредственно в вашем любимом браузере. +Разработка становится все сложнее и интереснее: сайты увеличиваются в объемах, растет количество постоянных пользователей, владельцы сайта хотят угодить всем, так как напрямую от этого зависит их прибыль, повышается конкуренция. Сайт должен быть очень мобильным и уметь реагировать на все изменения окружающей среды практически мгновенно. А что же в таком случае остается делать разработчику? Ответ один: чтобы выжить, ему необходимо учиться оптимизировать разработку, умело пользоваться всем своим кодом и быстро отыскивать проблемные места, устраняя ошибку локально, не затрагивая никакие другие части кода. + +Как все это воплотить в жизнь? Типичный человеческий подход к преодолению сложной проблемы — дробление ее на более простые части. Идея разделения на компоненты не нова. Она в полном объеме реализована в ООП. Нам остается только перенять этот богатый опыт. + +Будущее (кажется, что это уже настоящее) веб-приложений – за переходом на компонентную структуру. + +Компонентный подход в JavaScript позволяет объединять сущности по общему признаку и организовывать их в соответствии с определенными правилами и ограничениями. Не имеет значения, как этот подход реализован, потому что у каждого компонента есть свои методы, которые знают все о себе. [Общение с внешними блоками](#independent-blocks) происходит либо через родителя, либо через каких-то посредников. + +Компонентная структура обеспечивает гибкость контроля версий и помогает избежать конфликтов во время ведения параллельной разработки. Перенос логики, связанной с конкретными блоками, в отдельные файлы, улучшает читаемость кода и ускоряет процесс создания и корректировки проекта. Именно эту задачу решает БЭМ. + +## Применение методологии БЭМ к JavaScript + +В процессе эволюции технологий написания сайтов появился БЭМ. Суть данного подхода – разбиение страницы на блоки и элементы. Определение свойств, их значений и дополнительного функционала блоков и элементов выполняется с помощью модификаторов. Еще одно ключевое понятие БЭМа – [уровни переопределения](https://ru.bem.info/tools/bem/bem-tools/levels/). Они позволяют расширять и дополнять поведение одного и того же блока. + +Изначально перед разработчиками ставились задачи отображения внешнего вида страницы, поэтому методология БЭМ применялась больше для именования классов в CSS. Как и CSS JavaScript пишется к каждому блоку отдельно и располагается непосредственно в самом блоке. Блок становится независимым и в функциональном плане. JavaScript приводит в действие какие-то модификаторы и это те самые модификаторы, которые приводят в действие какие-то CSS свойства. Они напрямую связаны и разделять их нет смысла, поскольку JavaScript и CSS оперирует одними терминами. + +Как же применить БЭМ-методологию к JavaScript? БЭМ вводит единую семантику на всех уровнях (HTML, CSS, JavaScript, шаблоны, дизайн интерфейсов) и предоставляет единый гибкий API поверх разнообразного набора методов работы с DOM. А на уровне файловой системы все про одну сущность складывает в одну папку, предназначенную для повторного использования и расширения. + +Чтобы на деле понять как работает подход БЭМ, понадобиться разобраться в следующих определениях, особенностях подхода и принципах: + +* [декларативный подход](#declaration) +* [взаимодействие блоков](#independent-blocks) +* [модификатор](#modifier) +* [метод](#method) +* [событие](#event) +* [изменение поведения блока](#customization) +* [инициализация](#initialization) + + + + +### Декларативный подход + +Важной особенностью БЭМ технологии является декларативный принцип. Подобно работе декларативных языков программирования, JavaScript-код содержит не последовательный алгоритм работы блока, а набор действий и условий, при которых эти действия необходимо выполнять. + +Декларативность проявляется в объявлении того, к каким блокам или их модификациям применим код компонента. При декларировании какой-то сущности известно, что она имеет определенные состояния и при переходе в эти состояния с ней происходят конкретные действия, а при возвращении к предыдущему состоянию с ней случаются обратные действия. + +<Пример> + +<Расшифровка примера> + + + +### Способы взаимодействия блоков + +Блок в БЭМ – это независимый компонент, который можно переместить в любое место на странице, в том числе и в другой блок или же на другой проект. Блок может поддерживать разные технологии – HTML, CSS, JavaScript и т.п. БЭМ-методолгия позволяет на уровне проекта изменить внешний вид или поведение существующего блока, добавить новые блоки. Однако, несмотря на независимость блоков, на уровне JavaScript они обязаны общаться друг с другом. + +### Написание JavaScript-кода с сохранением независимости блоков + +Простой пример поможет понять как происходит взаимодействие блоков. + +**Описание** + +Есть форма, перед отправкой которой необходимо проверить, что введено корректное значение, и в случае ошибки показать попап с предупреждением. + +Выглядит это следующим образом: + +```html +
+``` + +```css +.popup { + display: none; +} + +.popup_visible { + display: block; +} +``` +Чтобы описанная конструкция заработала необходимо написать JavaScript-код. + +### Реализация в старом стиле + +Приведенный пример показывает, как делать **не надо**. + +```js +$('.button').on('click', function(e) { + if (!/\S+@\S+\.\S+/.test($('.input').val())) { + $('.popup').addClass('popup_visible'); + return false; + } +}); +``` +Согласно представленному коду, кнопка «знает» про поле ввода и попап, кроме того явно предполагается, что она находится внутри формы. + +Однако реальность такова, что проекты не стоят на месте, они развиваются. Приходит момент, когда необходимо что-то добавить, переместить или изменить. Процесс реорганизации внутренней структуры в представленном коде, будь то удаление одного из компонентов или появление новых элементов, приведет к его поломке. При возможном переиспользовании такой кнопки, обязательно придется применить все компоненты с такими же классами и гарантировать, что больше нигде на странице они не встретятся. + +**Результат**