Жук который ползает. Усовершенствование
Всем здравствуйте.
Есть жук еще с этой темы http://javascript.ru/forum/misc/6274...rozhdenie.html Решил добавить функционал - добавил кнопку что бы при клике добавлялся еще один жук + чтобы можно было по кликом выбирать жука который становится активным и им можно было управлять. Посмотреть что получилось можно здесь - http://1.top-start.ru/bug/ Что бы реализовать задуманное создал новый класс который создает жуков Писал на TypeScript, а вот код который уже сгенерирован в JS var CreateBug = (function () { function CreateBug() { this.elemBug = document.getElementById("marg").innerHTML; this.create(); this.eventsBug(); } //Метод добавление жука при клике на кнопку CreateBug.prototype.create = function () { var elementBug = this.elemBug; //Вешаем клик на кнопку document.getElementById("create").addEventListener("click", function () { //Удаляем класс active так как новый жук уже будет с этим классом document.getElementsByClassName("active")[0].classList.remove("active"); //Вставляем нового жука в поле #marg document.getElementById("marg").innerHTML += elementBug; //запускаем метод eventsBug который переназначает клик на всех жуков el.eventsBug(); var bug = new Bug(100, 100, '.active'); }, false); }; //Метод переключения между жуками CreateBug.prototype.eventsBug = function () { var removeClass = function () { //Функция которая срабатывает при клик //Удаяем класс active с жука у торого этот класс есть document.getElementsByClassName("active")[0].classList.remove("active"); // Добавляем класс active для жука по котором кликнули this.classList.add("active"); var bug = new Bug(this.offsetTop, this.offsetLeft, '.active'); }; var elements = document.getElementsByClassName("bug"); //Вешаем событие на всех жуков for (var i = elements.length - 1; i >= 0; i--) { elements[i].addEventListener('click', removeClass); } }; return CreateBug; }()); var bug = new Bug(100, 100, '.active'); var el = new CreateBug(); Жуки добавляются как было задумано, новый жук становится активным, им можно управлять остальные жуки не двигаются, а вот при переключении между жуками есть проблема - жуки двигаются все на которые кликнул не смотря на то что класс active нормально переключается. А если добавить еще жука то все становится как надо - все жуки стоят на месте - активный двигается. Все писал в стиле ООП так как цель всего действа именно для изучения ООП + TypeScript а еще чтобы поближе познакомится именно с JS, потому как все время сидел на jQuery Подскажите в чем проблема, буду признателен за помощь. |
Как это вообще работает?!
document.getElementById("marg").innerHTML += elementBug; присваиваем в поле #marg содержимое этого поля + содержимое этого же поля. eventsBug() вот тут под капот хотелось бы посмотреть. |
Bond,
Смотрел-смотрел, но так и не понял: Зачем это? Что оно делает? var bug = new Bug(this.offsetTop, this.offsetLeft, '.active'); (строка 28) |
aklis,
Да все верно мы присваиваем в поле #marg содержимое этого поля + содержимое этого же поля только то содержимое которое было при загрузке страницы - а у нас там был код только одного жука с классом active |
Bond,
попробуйте не использовать Цитата:
|
Dilettante_Pro,
У нас есть класс Bug - он управляет жуком и т.д, а этой строкой мы создаем объект вернее как бы пересоздаем иначе вообще не пашет var bug = new Bug(this.offsetTop, this.offsetLeft, '.active'); Передаем три параметра - отступ сверху, отступ слева и html класс того блока который сейчас активный, то есть по которому мы кликнули - заметьте это все происходит при клике. Да загвоздка именно в этом - создавать постоянно новый объект при каждом клике не годится - но как тогда поступить? Создавать объект для каждого нового жука - то есть три жука три объекта - но что бы двигался только активный? Или нужен деструктор который будет удалять все объекты....? А потом создавать новый для активного жука? |
Bond,
Причем bug у вас каждый раз переопределяется - то как глобальная, то как локальная переменная... В результате глобальный bug как был, так и остается, а локальные, живущие в пределах функции - что с ними? Для чего они? |
Dilettante_Pro,
локальные не нужны, это моя грубейшая ошибка. Но дело все равно не меняет - мы создаем объект который управляет жуком с классом active если создать еще жука и класс active переписать ему то все равно этот объект будет управлять первым жуком, а если пересоздать объект то будут двигаться два жука. |
Bond,
Bug.prototype.moveTo = function (direction) { if(!this.element.classList.contains("active")) return; |
Bond,
мысли вслух ... <!DOCTYPE html> <html lang="ru"> <head> <meta charset="utf-8" /> <title>Заголовок</title> <meta name="description" content="" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" href="http://1.top-start.ru/bug/css/main.css" /> </head> <body> <h3>Управление стрелками</h3> <button id="create">Добавить еще одного жука</button> <div id="marg"> <div class="bug active"> <div class="limb_left1"> <span></span> </div> <div class="limb_left2"> <span></span> </div> <div class="limb_left3"> <span></span> </div> <div class="limb_right1"> <span></span> </div> <div class="limb_right2"> <span></span> </div> <div class="limb_right3"> <span></span> </div> </div> </div> <script>var Bug = (function () { function Bug(top, left, element) { //this.controlBug = control; this.step = 4; this.rotation = 0; this.direction = 'top'; this.top = top; this.left = left; this.element = document.querySelector(element); this.bindKeys(); this.limb1 = new Limb(element + ' ' + '.limb_left1', -5, -35, 17, 11); this.limb2 = new Limb(element + ' ' + '.limb_left2', 0, 0, 50, 11); this.limb3 = new Limb(element + ' ' + '.limb_left3', -10, -15, 37, 11); this.limb4 = new Limb(element + ' ' + '.limb_right1', 38, -15, 38, 11); this.limb5 = new Limb(element + ' ' + '.limb_right2', 0, -48, 0, 11); this.limb6 = new Limb(element + ' ' + '.limb_right3', -10, -35, 5, 11); this.moveTo('top'); } Bug.prototype.bindKeys = function () { var keyNav = { 38: 'top', 39: 'right', 37: 'left', 40: 'bottom' }; var bug = this; document.addEventListener('keydown', function (e) { if (e.keyCode in keyNav) e.preventDefault() bug.moveTo(keyNav[e.keyCode]); }, false); }; Bug.prototype.update = function () { var style = this.element.style; // if (this.left < 0) { this.left = 1; return; } // if (this.top < -25) { this.top = -24; return; } style.top = this.top + 'px'; style.left = this.left + 'px'; style.transform = 'rotate(' + this.rotation + 'deg)'; }; Bug.prototype.moveTo = function (direction) { if(!this.element.classList.contains("active")) return; this.direction = direction; var angle = { top: 0, left: 270, right: 90, bottom: 180 }[direction]; var diff = angle - (this.rotation % 360); if (diff > 180) diff = diff - 360; else if (diff < -180) diff = diff + 360; this.rotation += diff; if (diff == 0) { this.advance(); } this.update(); //this.update(); this.limb1.rotateLimb(); this.limb2.rotateLimb(); this.limb3.rotateLimb(); //left limb this.limb4.rotateLimb(); this.limb5.rotateLimb(); this.limb6.rotateLimb(); //right limb }; Bug.prototype.advance = function () { switch (this.direction) { case 'top': this.top -= this.step; break; case 'bottom': this.top += this.step; break; case 'left': this.left -= this.step; break; case 'right': this.left += this.step; break; } }; return Bug; }()); var Limb = (function () { function Limb(limb, start, ltop, bottom, step) { this.limb = document.querySelector(limb); this.start = start; //Стартовое положение лапы this.ltop = ltop; // Крайнее верхнее положение лапы this.bottom = bottom; // Крайнее нижнее пложение лапы this.lstep = step; // Шаг движения лапы } Limb.prototype.rotateLimb = function (e) { this.style_limb = this.limb.style; if (this.start <= this.ltop) this.flag = true; if (this.start >= this.bottom) this.flag = false; if (this.flag) { this.start += this.lstep; } else { this.start -= this.lstep; } this.style_limb.transform = 'rotate(' + this.start + 'deg)'; }; return Limb; }()); (function () { var marg = document.querySelector("#marg"), elemBug = marg.removeChild(document.querySelector(".bug")), but = document.querySelector("#create"); but.addEventListener("click", function () { var act = document.querySelector(".active") act && act.classList.remove("active"); marg.appendChild(elemBug.cloneNode(true)); var bug = new Bug(100, 100, '.active'); bug.element.addEventListener('click', function () { document.querySelector(".active").classList.remove("active"); this.classList.add("active"); }); }, false); but.click() }()); </script> </body> </html> |
рони,
Все верно, все пашет http://1.top-start.ru/bug/, в принципе как и задумывалось. Только вот вопрос - мы и при создании нового жука и при переключении жуков создаем или пересоздаем объект - что вообще происходит? объекты множатся или пересоздаются? Это вообще адекватный подход? Да и кстати appendChild думал использовать но получается более громоздко по коду - создать блок, записать классы, вписать в DOM создать лапы, а потом все равно ему надо клик назначать Это получается то же самое что я одной строкой перепишу через innerHTML а потом всем жукам переназначу клик. |
рони,
неплохие мысли вслух ) Спасибо Этот поход покруче моего будет - посижу посмотрю что происходит в новом коде, я немного по другому представлял как это сделать через appendChild |
Bond,
смотрите код выше ... какие мысли были они там ... и appendChild одной строкой и переназначать ненадо ничего. |
рони,
Спасибо, я выше отписался, предыдущее сообщение писал еще не видел Ваши мысли в слух ) |
код переписать с использованием WebGL:lol:
|
Rise,
ИМХО JS более абстрактнее TS - пишем function а говорим что это класс, объявляем свойства - имитируем типа конструктор который запускается один раз при инициализации, пишем вне функции .prototype и называем это методом. Короче сплошная имитация имитации. Абстракция абстракции )) Странно что массив по нормальному назвали Array а не к примеру var или еще хуже тоже function как и класс. А в остальном по сути чем TypeScript отличается от JavaScript? - может он как то по другому с масивами работает? или с DOM? нет все то же - все взято с JS, да чего там взято - это и есть JS - просто TS более логично описывает классы и методы, реализовывает наследование и пр. - а не как JS - имитацией. Так что не вижу проблем в изучении JS кодируя в TS - тем более ходят слухи что TS это будущий JS. А С два креста думаю неудачное сравнение. |
Rise,
Ну почему же отдельный язык - это надмножество JS - если JS широко начнет поддерживать то что реализовывает TS - то TS попросту умрет. Но за ним плакать никто не будет - потому что, то что учили в TS пригодится в новом JS. По крайнем мере так говорят в Майкрасофт, которые собственно и создали TS. Хотя может и не умрет, но по крайней мере JS програмеры его использовать не будут за ненадобностью. Я учу JS не только ООП а и все остальное - до этого сидел на jQuery - да так сидел что на чистом JS не мог даже клик повесить на кнопку или c DOM-а что то выбрать - привык писать click(), и $("#"). Вот и хочу все это делать на JS а не на jQuery + знать и уметь работать с предопределенными объектами методами функциями - а C++ в этом мне не помощник. А TS, как раз подходит - мало того что TS это один в один JS, так еще и TS это JS в будущем. Почему в таком случае не чистый JS юзаю? Убиваю - трех зайцев - кодируя в TS учу JS, учу TS, учу более классическое ООП. + в дальнейшем есть желание познакомится с Angular 2 который юзает TS |
Rise,
Не понял что значит не похоже? Все один в один - и классы и методы и конструктор и наследование - просто в TypeScript нужно указывать тип свойств и переменных так как это строго типизированный язык. Вот я и говорил - новый стандарт JS ES6 начнет широко поддерживаться и TS пропадет в реке забвения ), по крайней мере для JS разрабов. Но навыки с TS пригодятся для нового JS |
Цитата:
|
Цитата:
https://nodejs.org/en/docs/es6/ |
Цитата:
|
destus,
Нет ждать не буду, уже не жду - вот учу TS как альтернативу, но возрадуюсь тому моменту когда не надо будет компиляторы использовать. Так же возрадуюсь как в свое время радовался когда все меньше и меньше заказчиков требовали поддержку IE7-8 в верстке. Хотя может к тому времени ES обрастет еще какими нить фичами и опять будем новые плагины вешать и компиляторы юзать. :) В любом случае ждать нет смысла... А про Babel надобно почитать, слышал только краем уха... |
Rise,
Ну есть трансляция с ES6 в ES5 - а есть компиляция с TS в тот же ES5 - просто надо задаться вопросом что удобнее (я не задавался, просто начал TS юзать) - ведь на выходе получаем одно и то же. |
Цитата:
|
Кому легко, а кому не очень.:)
Я работаю старым дедовским способом - в одном окне открыт в редакторе файл TS, в другом браузер в котором открыт локальный файл html, что то написал в TS файл - нажал ctrl+b и enter, редактор скомпилировал все в js а браузер автоматом обновил страницу с новыми результатами. Без никаких серверов и т.д А потом готовые файлы заливаю на сервер также как они были на локалке. А как происходит процесс разработки если использовать сервер? |
destus, если я прикрутила Babel (обычный и поллифилы) через npm, то ES2015 будет работать у меня на машине? Где следует разместить код с промисами и поллифилами, по отношению к Babel чтоб мой код заработал? Неправильно выбранные дирректории расположения файлов вроде node modules, gulp и т.п. может привести к неработоспособнсти кода?
|
Еще один плюс юзания TS а не ES6 через Babel - при компиляции я вижу скомпилированный файл JS и вижу что в нем происходит и что я получаю на выходе
К примеру объявил функцию через стрелку в TS let inc = x => x + 1; А после компиляции получил var inc = function (x) { return x + 1; }; Нагляднее примера не бывает - ни один учебник не заменит того что видишь своими глазами. Для разработки это не плюс, а вот для обучения как раз в тему. |
Цитата:
|
Цитата:
|
Установил Babel, поюзал немного - на мой дилетантский взгляд различий с TS не заметил - да в компилированных файлах некоторые дела по другому реализовываются к примеру наследование, но результат работы тот же.
Что выдающегося есть в Babel что бы использовать именно его? |
|
Часовой пояс GMT +3, время: 16:35. |