Slyweb
На разработку сайта! Скидки 50%!

jQuery - самое нужное! Как сделать меню с jQuery!

Как сделать меню с jQuery. В статье содержится подробная информация по созданию меню на jQuery.

Оглавление статьи "jQuery - самое нужное! Как сделать меню с jQuery!"

Часть 1. Общее для всех меню!

Шаг 1. Начало!

В прошлых статьях я рассказывал как сделать jQuery меню основываясь на элементах li, этот же пример меню основан на элементах div, которые скрывают набор ссылок, которые будут рассматриваться как элементы подменю.

Для начала подключите jQuery библиотеку:

Шаг 2. Создайте структуру меню!

После создайте следующую структуру html:

  • Код
  • Чистый код
  1. <div id="menupush" class="menu"> <!--Первое меню-->
  2. <p class="menuh">Заголовок-1</p>
  3. <div class="menu_conteiner">
  4. <a href="#">Подменю-1</a>
  5. <a href="#">Подменю-2</a>
  6. <a href="#">Подменю-3</a>
  7. </div>
  8. <p class="menuh">Заголовок-2</p>
  9. <div class="menu_conteiner">
10. <a href="#">Подменю-1</a>
11. <a href="#">Подменю-2</a>
12. <a href="#">Подменю-3</a>
13. </div>
14. <p class="menuh">Заголовок-3</p>
15. <div class="menu_conteiner">
16. <a href="#">Подменю-1</a>
17. <a href="#">Подменю-2</a>
18. <a href="#">Подменю-3</a>
19. </div>
20. </div> <!--Конец-->

        

Если Вам нужно, чтобы меню разворачивалось при нажатии, то укажите id "menupush", если нужно чтобы меню разворачивалось по событию mouseover, то укажите id "menuover", на основе идентификаторов элементов контейнеров меню будет работать код на jQuery, о котором чуть позже, а пока подробней рассмотрим, структуру html. В обязательном порядке должен существовать основной контейнер меню - элемент div:

  • Код
  • Чистый код
  1. <div id="menupush" class="menu"> <!--Первое меню-->
  2.
  3. </div> <!--Конец-->

        

Если Вы создаете меню на основе события mouseover, то основной контейнер меню - элемент div, с id "menuover":

  • Код
  • Чистый код
  1. <div id="menuover" class="menu"> <!--Первое меню-->
  2.
  3. </div> <!--Конец-->

        

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

  • Код
  • Чистый код
  1.<p class="menuh">Заголовок-1</p>

        

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

  • Код
  • Чистый код
  1.<div class="menu_conteiner">
  2. <a href="#">Подменю-1</a>
  3. <a href="#">Подменю-2</a>
  4. <a href="#">Подменю-3</a>
  5. </div>

        

Контейнер со ссылками должен располагаться взаимосвязано с элементом заголовком, так как jQuery код связывает данные элементы вместе, поскольку в jQuery будет использован метод next() для разворота последующего меню при нажатии заголовка. Конечно, сейчас Вам не всё ясно, подробней механизм разворота подменю я объясню далее, при изучении jQuery кода. Сейчас стоит подробней рассмотреть CSS код, указанный ниже:

Шаг 3. Подключаем css стили!

  • Код
  • Чистый код
  1.<style type="text/css">
  2..menu_list {
  3. width: 150px;
  4.}
  5..menu_head {
  6. padding: 5px 10px;
  7. cursor: pointer;
  8. position: relative;
  9. margin:1px;
10. font-weight:bold;
11. background: #eef4d3 url(left.png) center right no-repeat;
12.}
13..menu_body {
14. display:none;
15.}
16..menu_body a{
17. display:block;
18. color:#006699;
19. background-color:#EFEFEF;
20. padding-left:10px;
21. font-weight:bold;
22. text-decoration:none;
23.}
24..menu_body a:hover{
25. color: #000000;
26. text-decoration:underline;
27. }
28.</style>

        

Особое внимание следует обратить на элемент с классом menuh, для него используется свойство "display" установлено как "none", в результате этого меню будет сокрыть при загрузке страницы. Для ссылок внутри меню используется свойство "display" установленное как "block", поэтому каждая ссылка будет находиться в новой строке. Элемент menuh содержит изображение, которое будет менять свою позицию, при открытии (закрытии) меню. Вы смело можете заменить его, используя собственное.

Шаг 4. Функциональность на jQuery!

Теперь, когда Вы знаете как создать меню, перейдём к jQuery.

  • Код
  • Чистый код
  1.<script type="text/javascript">
  2.$(document).ready(function()
  3.{
  4. //эта функция для выдвижения меню по событию click
  5. $("#menupush p.menuh").click(function()
  6. {
  7. $(this).css({backgroundImage:"url(down.png)"}).next("div.menu_conteiner").slideToggle(300).siblings("div.menu_conteiner").slideUp("slow");
  8. $(this).siblings().css({backgroundImage:"url(left.png)"});
  9. });
10. //эта функция для выдвижения меню по событию mouseover
11. $("#menuover p.menuh").mouseover(function()
12. {
13. $(this).css({backgroundImage:"url(down.png)"}).next("div.menu_conteiner").slideDown(500).siblings("div.menu_conteiner").slideUp("slow");
14. $(this).siblings().css({backgroundImage:"url(left.png)"});
15. });
16.});
17.</script>

        

Сложности данный код не представляет, основная функция, запускается при срабатывании обработчика события, какого - это зависит от того какой тип меню Вы выберите, если Вы выбрали меню элементы которого разворачиваются при наведении курсора, то сработает обработчик события mouseover(), иначе сработает обработчик click(). Основной код меню заключается в следующих строчках:

  • Код
  • Чистый код
  1.$(this).css({backgroundImage:"url(down.png)"}).next("div.menu_conteiner").slideDown(500).siblings("div.menu_conteiner").slideUp("slow");
  2. $(this).siblings().css({backgroundImage:"url(left.png)"});

        

Например, при наведении курсора на заголовок, будет сперва выбран текущий элемент с помощью ключевого слова $(this), будет заменено фоновое изображение с помощью метода css({backgroundImage:"url(down.png)"}), после этого мы переходим к контейнеру со ссылками, которое разворачиваем методом slideDown() - .next("div.menu_conteiner").slideDown(500), затем метод siblings(), предоставляет доступ к элементам соотносящимся как "брат и сестра", для того чтобы вернуть фоновое изображение в прежнее состояние для смежных элементов меню.

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

Шаг 5. Смотрим результат!

Меню разворачивающееся при нажатии курсора

Меню разворачивающееся при наведении курсора

Часть 2. Оптимизируем для Wordpress (для Олега Коновалова)

Следующий код пригодится для Wordpress или в других CMS. По сути, мы немного изменили существующий код, но сначала, я укажу полные листинги js и css файлов и html структуру. Итак, сердцевина меню (jQuery):

  • Код
  • Чистый код
  1.$(document).ready(function()
  2.{
  3. /* функция для выдвижения меню по событию click */
  4.
  5.
  6.
  7. $(".menu_slider_new div.menuhs").click(function()
  8. {
  9. $(this).css({"backgroundImage":"url(fon.jpg)","color":"#000","text-shadow": "0 1px 1px #F6F6F6"}); // меняем фоновое изображение при нажатии
10. $(this).children().fadeTo('slow', 1).end()
11. .next("ul.menu_conteinernew") // переходим к следующему элементу за div.menuhs
12. .slideDown(300) // разворачиваем его
13. .siblings("ul.menu_conteinernew") // переходим ко всем элементам "братьям"
14. .slideUp("slow"); // закрываем их
15. $(this).siblings(".menuhs").children().fadeTo('slow', 0);
16.
17. $(this) // переходим к текущему элементу (по которому нажали)
18. .siblings() // выбираем все элементы смежные
19. .css({backgroundImage:"url(fonclick.jpg)","color":"#b2b2b2","text-shadow": "0 -1px 1px #fff"}); // устанавливаем им фоновое изображение по умолчанию
20.
21. });
22.
23.
24. /* эффекты для ссылок */
25.
26. $(".menu_conteinernew li a").hover(
27. function(){
28. $(this).stop().fadeTo('slow', 1);
29. },
30. function(){
31. $(this).stop().fadeTo('slow', 0.5);
32. }
33. );
34.
35.
36. /*Можно удалить, это две кнопки быстрого открытия меню*/
37.
38. $("div.all, div.noall").hover(
39. function(){
40. $(this).stop().fadeTo('slow', 1);
41. },
42. function(){
43. $(this).stop().fadeTo('slow', 0.5);
44. }
45. );
46.
47. $("div.all").click(function(){
48. $("div.menuhs").css({backgroundImage:"url(fonclick.jpg)"}) // устанавливаем им фоновое изображение по умолчанию
49. .next("ul.menu_conteinernew") // переходим к следующему элементу за div.menuhs
50. .slideDown(300) // разворачиваем его
51. .end().children().fadeTo('slow', 1);
52. });
53.
54.
55. $("div.noall").click(function(){
56. $("div.menuhs").css({backgroundImage:"url(fonclick.jpg)","color":"#b2b2b2","text-shadow": "0 -1px 1px #fff"}) // устанавливаем им фоновое изображение по умолчанию
57. .next("ul.menu_conteinernew") // переходим к следующему элементу за div.menuhs
58. .slideUp(300) // разворачиваем его
59. .end().children().fadeTo('slow', 0);
60. });
61.});

        
Листинг 1.

CSS код является неотъемлемой частью меню, изменять его я рекомендую с осторожностью. Обратите особое внимание, наше усовершенствованное меню для Wordpress основывается на элементах списках, что является удобным в большинстве случае при работе с системами управления сайтом, так как большинство этих систем, меню создают на основе маркированного списка. Итак, наш код на CSS:

  • Код
  • Чистый код
  1.<style type="text/css">
  2.
  3./* Это нужно в любом случае */
  4.
  5..menu_slider_new {
  6. -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
  7. -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
  8. box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
  9. width: 250px;
10. border: 1px solid #B2B2B2;
11.}
12.div.menuhs {
13. postion:relative;
14. padding: 5px 10px;
15. cursor: pointer;
16. position: relative;
17. margin:1px;
18. font-weight:bold;
19. background: #eef4d3 url(fonclick.jpg) center right repeat-x;
20. color: #b2b2b2;
21. cursor: pointer;
22. font-weight: bold;
23. text-decoration: none;
24. text-shadow: 0 -1px 1px #fff;
25.}
26.div.menuhs .bgimg1, div.menuhs .bgimg2, div.menuhs .bgimg3 {
27. position:absolute;
28. right:5px;
29. top:5px;
30. width: 24px;
31. height: 22px;
32. opacity:0;
33. filter:Alpha("opacity=0");
34.}
35.div.menuhs .bgimg1 {
36. background: url(chat.png) center right repeat-x;
37.}
38.div.menuhs .bgimg2 {
39. background: url(eye.png) center right repeat-x;
40.}
41.div.menuhs .bgimg3 {
42. background: url(baby.png) center right repeat-x;
43.
44.}
45.
46..menu_conteinernew {
47. display:none;
48. list-style:none;
49. margin:0;
50. padding:0;
51.}
52..menu_conteinernew li{
53. display:block;
54. color:#545454;
55. background-color:#EFEFEF;
56. padding-left:10px;
57. text-decoration:none;
58.
59.}
60..menu_conteinernew li a{
61. color:#545454;
62. text-decoration:none;
63. opacity:.5;
64.
65.}
66.
67..menu_conteinernew li a:hover{
68. color: #545454;
69. text-decoration:underline;
70.}
71.
72./* Если не нужно можете удалить (кнопи быстрого открытия всего меню) */
73.
74..menu_header_new{
75. -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
76. -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
77. box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
78. width: 250px;
79. border: 1px solid #B2B2B2;
80. postion:relative;
81. background: #eef4d3 url(fonclick.jpg) center right repeat-x;
82. margin:10px 0;
83. height:35px;
84. clear:both;
85.}
86.
87.div.all, div.noall {
88. width: 24px;
89. height: 22px;
90. float:left;
91. margin:5px;
92. opacity:.5;
93. cursor:pointer;
94.}
95.
96.div.all {
97.background: url(all.png) center right repeat-x;
98.}
99.div.noall {
100.background: url(noall.png) center right repeat-x;
101.}
102.
103.</style>
104.

        
Листинг 2.

Обратите особое внимание на элемент с классом "menu_header_new", в нём мы установим две кнопки информирующие пользователя о возможном быстром раскрытии всего меню и его быстром сокрытии, то есть не меню, а элементов меню (li).

  • Код
  • Чистый код
  1. <!-- Wordpress меню-->
  2.
  3. <div class="menu_header_new">
  4.
  5. <div class="all"></div>
  6. <div class="noall"></div>
  7.
  8. </div>
  9.
10.
11. <div class="menu_slider_new">
12.
13. <div class="menuhs">Заголовок-1<div class="bgimg1"></div></div>
14. <ul class="menu_conteinernew">
15. <li><a href="#">Подменю-1</a></li>
16. <li><a href="#">Подменю-2</a></li>
17. <li><a href="#">Подменю-3</a></li>
18. </ul>
19. <div class="menuhs">Заголовок-2<div class="bgimg2"></div></div>
20. <ul class="menu_conteinernew">
21. <li><a href="#">Подменю-1</a></li>
22. <li><a href="#">Подменю-2</a></li>
23. <li><a href="#">Подменю-3</a></li>
24. </ul>
25. <div class="menuhs">Заголовок-3<div class="bgimg3"></div></div>
26. <ul class="menu_conteinernew">
27. <li><a href="#">Подменю-1</a></li>
28. <li><a href="#">Подменю-2</a></li>
29. <li><a href="#">Подменю-3</a></li>
30. </ul>
31. </div>
32. <!--Конец Wordpress меню -->
33.
34.

        
Листинг 3.

Теперь давайте разберём весь код подробней. Как и во многих платинах jQuery, начнём с привычного:

  • Код
  • Чистый код
  1.$(document).ready(function()
  2.{
  3.

        

Далее, что нам нужно уяснить, - пользователь нажимает по элементу с классом menuhs и мы должны на это как то реагировать, - на что мы и устанавливаем обработчик события "click".

  • Код
  • Чистый код
  7.$(".menu_slider_new div.menuhs").click(function()
  8. {

        

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

  • Код
  • Чистый код
  9.$(this).css({"backgroundImage":"url(fon.jpg)","color":"#000","text-shadow": "0 1px 1px #F6F6F6"}); // меняем фоновое изображение при нажатии

        

Теперь посложнее в 10 строке мы используем следующую логику - получаем текущий элемент, - элемент по которому только что нажали ($(this)), от него переходим к его элементам "детям" с помощью метода children(), у нас их - всего один, и отображаем эти элементы, устанавливая для них прозрачность в значение «1», используя метод fadeTo('slow', 1). Затем обязательно нужно указать метод end(), этот метод возвращает нас от элемента дочернего к родительскому элементу, метод end() как бы отменяет все операции jQuery, связанные с перемещением по элементам. То есть теперь мы вернулись к элементу, по которому только что нажали ($(this)). Для чего нам возвращаться назад, - для того чтобы перейти от текущего элемента ($(this)) к следующему за ним элементу контейнеру (элемент ul c классом menu_conteinernew), чтобы развернуть его используя метод анимации slideDown(300). Пока наш элемент будет разворачиваться, мы в этот момент сворачиваем другие элементы(строка 13) через метод slideUp("slow"). Аналогично и для следующей строки (15), - мы скрываем все элементы - изображения, используемые в заголовочной части. В 17 строке мы переходим обратно к текущему элементу, а от него к его "собратьям" (строка 18, метод .siblings()), для того чтобы поменять фоновое изображение в строке 19.

  • Код
  • Чистый код
  10.$(this).children().fadeTo('slow', 1).end()
  11. .next("ul.menu_conteinernew") // переходим к следующему элементу за div.menuhs
  12. .slideDown(300) // разворачиваем его
  13. .siblings("ul.menu_conteinernew") // переходим ко всем элементам "братьям"
  14. .slideUp("slow"); // закрываем их
  15. $(this).siblings(".menuhs").children().fadeTo('slow', 0);
  16.
  17. $(this) // переходим к текущему элементу (по которому нажали)
  18. .siblings() // выбираем все элементы смежные
  19. .css({backgroundImage:"url(fonclick.jpg)","color":"#b2b2b2","text-shadow": "0 -1px 1px #fff"}); // устанавливаем им фоновое изображение по умолчанию
  20.

        

С 26 по 45 строку идёт код не обязательный, но создающий определенные эффекты для текста ссылок, ссылки в элементах меню плавно меняют прозрачность при наведении на них курсора.

  • Код
  • Чистый код
  24./* эффекты для ссылок */
  25.
  26. $(".menu_conteinernew li a").hover(
  27. function(){
  28. $(this).stop().fadeTo('slow', 1);
  29. },
  30. function(){
  31. $(this).stop().fadeTo('slow', 0.5);
  32. }
  33. );
  34.
  35.
  36. /*Можно удалить, это две кнопки быстрого открытия меню*/
  37.
  38. $("div.all, div.noall").hover(
  39. function(){
  40. $(this).stop().fadeTo('slow', 1);
  41. },
  42. function(){
  43. $(this).stop().fadeTo('slow', 0.5);
  44. }
  45. );
  46.

        

C 47 строки по 52 идёт код, который разворачивает все элементы меню, если кто работал с modx, то должен знать, там есть похожие функции при работе с меню в админке.

  • Код
  • Чистый код
  47.$("div.all").click(function(){
  48. $("div.menuhs").css({backgroundImage:"url(fonclick.jpg)"}) // устанавливаем им фоновое изображение по умолчанию
  49. .next("ul.menu_conteinernew") // переходим к следующему элементу за div.menuhs
  50. .slideDown(300) // разворачиваем его
  51. .end().children().fadeTo('slow', 1);
  52. });

        

Правильно развернуть то развернули, а как свернуть наше меню, - для этого используем строки с 55 по 60.

  • Код
  • Чистый код
  55.$("div.noall").click(function(){
  56. $("div.menuhs").css({backgroundImage:"url(fonclick.jpg)","color":"#b2b2b2","text-shadow": "0 -1px 1px #fff"}) // устанавливаем им фоновое изображение по умолчанию
  57. .next("ul.menu_conteinernew") // переходим к следующему элементу за div.menuhs
  58. .slideUp(300) // разворачиваем его
  59. .end().children().fadeTo('slow', 0);
  60. });

        

Всё теперь вы гуру в создании вертикальных меню на jQuery, Вам осталось немного изучить структуру и css этого меню, которые в общем не должны вызывать сложностей, я немного приукрасил для нормальных браузеров текст, рамку основного контейнера меню (menu_slider_new) свойством box-shadow, - свойство устанавливает тень для рамки элемента, и свойством text-shadow - создаёт эффект гравировки (вдавленности) текста. Остальные свойства css существуют больше десяти лет.

Теперь вы можете посмотреть результат:

Лучше посмотреть меню в новом окне.

Лично мне нравится, удобное для пользователя меню, и всего то нужно подключить два файла ( menu.js,menu.css). Единственно "но", - для браузера Internet Explorer 6, Вам придётся немного «подрихтовать» код, так как используются картинки в png. Ну и если быть честным, то в Internet Explorer нужно заменять все эффекты прозрачности другой анимацией.

Загрузить архивом "Меню для Wordpress"

P.S. Wordoress!

Внесём некоторые изменения. Знаете или нет, но все Wordpress имеют картинку в header, вот эту картинку мы и будем динамически менять в зависимости от наведения курсора на элемент меню. Изменения нужно будет внести незначительные. Прежде всего, допустим, что у Вас есть header в Wordpress, в действительности я туда давно не лазил и точно его не воспроизведу, но Wordpress использует те же div`ы, поэтому Вам не сложно будет изменить классы, id и некоторые другие параметры. Итак, вносим следующие изменения в html структуру:

  • Код
  • Чистый код
  1. <div class="main_header_new">
  2. <div class="mainimg" id="main_header_one"></div>
  3. <div class="mainimg" id="main_header_two"></div>
  4. <div class="mainimg" id="main_header_three"></div>
  5.
  6. </div>

        

Остальной код меню тот же. Теперь в самый конец jQuery (листинг 1) добавим:

  • Код
  • Чистый код
  1. /* хидер для Олега*/
  2.$(".menu_slider_new div.menuhs").mouseenter(function(e){
  3. ind = $(".menu_slider_new div.menuhs").index(this);
  4. $('.mainimg').stop().animate({"opacity": "0"}, "slow", function(){
  5.
  6. $('.mainimg:eq('+ind+')').stop().animate({"opacity": "1"}, "slow");
  7.
  8. });
  9.
10.});
11.

        

Подробно всё объясняю. В первой строке Вы видите комментарий, во второй строке вы видите обработчик события "mouseenter", в третей строке мы получаем индекс того меню, на котрое навели курсор, в четвёртой строке мы скрываем все div, изменяя свойство opacity для всех элементов - картинок, и сразу в пятой строке отображаем изображение, индекс котрого в наборе элементов, состоящем из элементов с классом "menuhs", соответствует индексу элемента меню на которой навели курсор. Вот и всё.

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

  • Код
  • Чистый код
  1. /* хидер для Олега*/
  2.$(".menu_slider_new div.menuhs").mouseenter(function(e){
  3. ind = $(".menu_slider_new div.menuhs").index(this);
  4. $('.mainimg').css({"opacity": "0"}).stop();
  5. $('.mainimg:eq('+ind+')').animate({"opacity": "1"}, "slow");
  6.});
  7.

        
Листинг 11.

И в css:

  • Код
  • Чистый код
  1.
  2..main_header_new {
  3. position:relative;
  4. margin:0 auto;
  5. width: 500px;
  6. height: 164px;
  7.}
  8.
  9..mainimg {
10. width: 570px;
11. height: 164px;
12. margin:0 auto;
13. position:absolute;
14. top:0;
15. left:0;
16.}
17.
18.#main_header_one {
19. background: url(3.jpg) center right repeat-x;
20. opacity:1;
21.}
22.#main_header_two {
23. background: url(2.jpg) center right repeat-x;
24. z-index:2;
25.}
26.#main_header_three {
27. background: url(8.jpg) center right repeat-x;
28. z-index:3;
29.}

        

Обратите внимание на относительно позиционированный блок с "main_header_new", внутри него содержаться другие блоки с абсолютным позиционированием, сколько вам нужно изображений столько и добавляйте, здесь всего три #main_header_one, #main_header_two, #main_header_three, то есть три элемента меню и три изображения им соответствующие. Если Вам нужно десять, то по той же схеме создавайте ещё семь css правил и 7 разделов в меню. То есть, например так:

  • Код
  • Чистый код
  1.... CSS ...
  2.#main_header_four {
  3. background: url(8.jpg) center right repeat-x;
  4. z-index:3;
  5.}
  6.#main_header_five {
  7. background: url(8.jpg) center right repeat-x;
  8. z-index:3;
  9.}
10.#main_header_six {
11. background: url(8.jpg) center right repeat-x;
12. z-index:3;
13.}
14.... HTML ...
15. <div class="main_header_new">
16. <div class="mainimg" id="main_header_one"></div>
17. <div class="mainimg" id="main_header_two"></div>
18. <div class="mainimg" id="main_header_three"></div>
19. .... новые здесь указываем .....
20. <div class="mainimg" id="main_header_four"></div>
21. <div class="mainimg" id="main_header_five"></div>
22. <div class="mainimg" id="main_header_six"></div>
23. .....
24..... и т.д.
25.


Вот на этом всё! Смотрите, что мы имеем по адресу: Лучше посмотреть меню в новом окне.

Загрузить архивом "Меню для Wordpress. Для смены изображения в header"

Александр Ермаков