04.05.2016, 20:11
|
Профессор
|
|
Регистрация: 16.06.2013
Сообщений: 172
|
|
Жук который ползает. Усовершенствование
Всем здравствуйте.
Есть жук еще с этой темы Жук который ползает. Возрождение
Решил добавить функционал - добавил кнопку что бы при клике добавлялся еще один жук + чтобы можно было по кликом выбирать жука который становится активным и им можно было управлять.
Посмотреть что получилось можно здесь - 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
Подскажите в чем проблема, буду признателен за помощь.
|
|
05.05.2016, 08:11
|
Кандидат Javascript-наук
|
|
Регистрация: 27.04.2015
Сообщений: 99
|
|
Как это вообще работает?!
document.getElementById("marg").innerHTML += elementBug;
присваиваем в поле #marg содержимое этого поля + содержимое этого же поля.
eventsBug() вот тут под капот хотелось бы посмотреть.
|
|
05.05.2016, 12:02
|
Профессор
|
|
Регистрация: 27.11.2015
Сообщений: 2,899
|
|
Bond,
Смотрел-смотрел, но так и не понял: Зачем это? Что оно делает?
var bug = new Bug(this.offsetTop, this.offsetLeft, '.active');
(строка 28)
|
|
05.05.2016, 13:40
|
Профессор
|
|
Регистрация: 16.06.2013
Сообщений: 172
|
|
aklis,
Да все верно мы
присваиваем в поле #marg содержимое этого поля + содержимое этого же поля только то содержимое которое было при загрузке страницы - а у нас там был код только одного жука с классом active
|
|
05.05.2016, 14:03
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,125
|
|
Bond,
попробуйте не использовать такое добавление, appendChild лучше
|
|
05.05.2016, 14:09
|
Профессор
|
|
Регистрация: 16.06.2013
Сообщений: 172
|
|
Dilettante_Pro,
У нас есть класс Bug - он управляет жуком и т.д, а этой строкой мы создаем объект вернее как бы пересоздаем иначе вообще не пашет
var bug = new Bug(this.offsetTop, this.offsetLeft, '.active');
Передаем три параметра - отступ сверху, отступ слева и html класс того блока который сейчас активный, то есть по которому мы кликнули - заметьте это все происходит при клике.
Да загвоздка именно в этом - создавать постоянно новый объект при каждом клике не годится - но как тогда поступить? Создавать объект для каждого нового жука - то есть три жука три объекта - но что бы двигался только активный?
Или нужен деструктор который будет удалять все объекты....? А потом создавать новый для активного жука?
|
|
05.05.2016, 14:38
|
Профессор
|
|
Регистрация: 27.11.2015
Сообщений: 2,899
|
|
Bond,
Причем bug у вас каждый раз переопределяется - то как глобальная, то как локальная переменная...
В результате глобальный bug как был, так и остается, а локальные, живущие в пределах функции - что с ними?
Для чего они?
|
|
05.05.2016, 15:12
|
Профессор
|
|
Регистрация: 16.06.2013
Сообщений: 172
|
|
Dilettante_Pro,
локальные не нужны, это моя грубейшая ошибка.
Но дело все равно не меняет - мы создаем объект который управляет жуком с классом active если создать еще жука и класс active переписать ему то все равно этот объект будет управлять первым жуком, а если пересоздать объект то будут двигаться два жука.
|
|
05.05.2016, 15:14
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,125
|
|
Bond,
Bug.prototype.moveTo = function (direction) {
if(!this.element.classList.contains("active")) return;
|
|
05.05.2016, 15:29
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,125
|
|
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>
|
|
|
|