Показать сообщение отдельно
  #1 (permalink)  
Старый 24.08.2009, 01:58
Интересующийся
Отправить личное сообщение для Diem Посмотреть профиль Найти все сообщения от Diem
 
Регистрация: 24.07.2009
Сообщений: 15

this и обработка события
<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, вызываются не так как мне нужно.
Все последующие действия происходят над вторым оъектом.

Можно ли как то решить данную проблему ?

Последний раз редактировалось Diem, 24.08.2009 в 02:01.
Ответить с цитированием