Вот рабочая версия, как я бы ее написал:
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
<circle cx="250" cy="250" r="50" fill="red" />
<script type="text/javascript"><![CDATA[
var KEY = { w:87, a:65, s:83, d:68 };
var moveSpeed = 5;
var circle = document.getElementsByTagName("circle")[0];
var x = circle.getAttribute('cx')*1,
y = circle.getAttribute('cy')*1;
document.documentElement.addEventListener('keydown',function(evt){
switch (evt.keyCode){
case KEY.w:
circle.setAttribute('cy',y-=moveSpeed);
// Alternatively:
// circle.cy.baseVal.value = (y-=moveSpeed);
break;
case KEY.s:
circle.setAttribute('cy',y+=moveSpeed);
break;
case KEY.a:
circle.setAttribute('cx',x-=moveSpeed);
break;
case KEY.d:
circle.setAttribute('cx',x+=moveSpeed);
break;
}
},false);
]]></script>
</svg>
Некоторые примечания:
Не возвращать ссылку на круг сноваи опять.Создание кода DRY делает его более надежным, менее печатным и (в данном случае) более быстрым.
Редактировать : Если вы не можете понять, как это сделатьучитывая мой код выше, отправьте любой код, который не работает для вас.
Не полагайтесь на глобальный event
объект;это старая ерунда IE.Используйте объект события, переданный в ваш обработчик событий.
Редактировать : Если вы ссылаетесь на event
в своем коде без параметра или локальной переменной с этим именем, вы предполагаете, что будетглобальный event
набор объектов.Вместо этого посмотрите код, который я написал для вас, который показывает, что обработчику событий передается объект event
.Давая этому имени, например, как я дал ему имя evt
, вы получаете объект события, специфичный для вашего обработчика событий.
Поскольку вы изменяете x
иy
переменных, нет необходимости повторно получать атрибуты cx
и cy
при каждом нажатии клавиши.
Редактировать : в своем исходном коде и принятом ответе вы объявили var x
вне вашего обработчика событий, и у вас есть x = ...
в начале вашего обработчика событий, изатем x++
в одном из обработчиков событий.Вы можете либо повторно получить текущее значение x
каждый раз (как вы это сделали), а затем setAttribute(...,x+1)
, либо (как я это сделал) вы можете получить значение атрибута только один раз дообработчики событий, а затем предположим, что это значение является правильным при каждой обработке ключевого события.
Не размещайте обработчики событий JavaScript на своих элементах, присоединяйте их программно.
Редактировать : В вашей разметке SVG у вас есть: <svg ... onkeypress="move()">
.Смешивать ваше поведение с разметкой - это действительно плохая идея в HTML и плохая идея в SVG.Вместо использования onfoo="..."
атрибутов для описания того, что должно происходить, когда событие происходит с элементом, вместо этого используйте addEventListner()
, чтобы присоединить обработчики событий с помощью кода, без редактирования разметки SVG.
Нет необходимости приводить числа к строкам перед установкой их в качестве атрибутов.
Используйте keydown
и коды событий ASCII, которые я предоставил выше, вместо keypress
и нечетных чисел, которые выиспользовали, если хотите, чтобы он работал во всех браузерах.
Редактировать : Вы жаловались в еще одном посте , что вы не можете сделать это, потому что вы хотите, чтобы обработчик событий былобрабатывается многократно, когда нажата клавиша.Обратите внимание, что желаемое поведение достигается с помощью моего примера кода в Chrome, Safari, Firefox и IE (у меня нет Opera для тестирования).Другими словами, keydown
работает так, как вы хотели, несмотря на то, как вы думали, что он должен вести себя.
Редактировать 2 : если вы хотите включить блок скрипта вВ верхней части документа, прежде чем все элементы будут обязательно созданы, вы можете сделать что-то вроде следующего:
<svg ...>
<script type="text/javascript">
window.addEventListener('load',function(){
var circle = ...;
document.rootElement.addEventListener('keydown',function(evt){
...
},false);
},false);
</script>
...
</svg>
Внешняя функция будет работать только после загрузки страницы, поэтому вы можете быть уверены, что элементысуществуют, чтобы ссылаться на них.