<script>
SampleObject = function()
{
var node = document.getElementById( 'click_me' );
node.addEventListener( 'click', this.action, false );
}
SampleObject.prototype = {
variable : 123,
action : function()
{
alert( this.variable );
}
}
</script>
<body onload="new SampleObject()">
<p id="click_me">click_me</p>
</body>
При клике по click_me alert с undefined, ну ничего удивительного нет.
Бывают ситауции когда, нужно повесить обработчик на событие, но вызов должен произойти в контексте другого объекта (SampleObject).
Как это можно сделать ?
Как вариант:
- node.addEventListener( 'click', this.action, false );
+ var obj = this;
node.addEventListener( 'click', function() { obj.action() }, false );
Да, всё работает.
Но что мне передать вторым параметром в node.removeEventListener если нужно будет убрать этот обработчик ?
Идём дальше, делаем изменения в конструкторе:
SampleObject = function()
{
var obj = this;
this.action_wrapper = function()
{
obj.action();
}
var node = document.getElementById( 'click_me' );
node.addEventListener( 'click', this.action_wrapper, false );
}
Тут тоже как бы всё ok.
Но стоит немного модифицировать код, и мы сталкнёмся с проблемой, похожую на ту, над которой я сейчас и ломаю голову.
<script>
SampleObject = function(nodeID)
{
var obj = this;
this.wrappers.downHandler = function(event)
{
obj.downHandler(event);
}
this.wrappers.upHandler = function(event)
{
obj.upHandler(event);
}
this.wrappers.moveHandler = function(event)
{
obj.moveHandler(event);
}
var node = document.getElementById( nodeID );
this.captionNode = node.getElementsByClassName('caption')[0];
this.defaultCaption = this.captionNode.innerHTML;
this.dragNode = node.getElementsByClassName('drag')[0];
this.dragNode.addEventListener( 'mousedown', this.wrappers.downHandler, false );
}
SampleObject.prototype = {
defaultCaption : '',
captionNode : null,
dragNode : null,
wrappers : {},
downHandler:
function(event)
{
event.stopPropagation();
event.preventDefault();
window.addEventListener( 'mousemove', this.wrappers.moveHandler, false );
window.addEventListener( 'mouseup', this.wrappers.upHandler, false );
},
upHandler:
function(event)
{
this.captionNode.innerHTML = this.defaultCaption;
window.removeEventListener( 'mousemove', this.wrappers.moveHandler, false );
},
moveHandler:
function(event)
{
this.captionNode.innerHTML = event.pageX + 'x' + event.pageY;
}
}
</script>
<style>
.element
{
border: 1px solid red;
width: 100px;
margin: 5px;
padding: 10px;
}
.element .drag
{
background: green;
padding: 5px;
color: white;
cursor: default;
}
</style>
<div class="element" id="element_1">
<p class="caption">Element #1</p>
<p class="drag">Drag Me</p>
</div>
<div class="element" id="element_2">
<p class="caption">Element #2</p>
<p class="drag">Drag Me</p>
</div>
<script>
new SampleObject('element_1');
new SampleObject('element_2');
</script>
Суть в том что downHandler будет вызыватся в контексте нужного new SampleObject(...)
Но другие обработчики, привязанные к событиям уже в downHandler, вызываются не так как мне нужно.
Все последующие действия происходят над вторым оъектом.
Можно ли как то решить данную проблему ?