2010-06-25 3 views
0

이 참조를 확인할 수 없습니다, 생성자는이를 사용, 괜찮 내에서 그들을 호출. [기능]자바 스크립트 객체 메소드에게 내가 몇 가지 프로토 타입 기능, 내가 만든 한 JS 객체를 가지고

그러나 나중에 이벤트 처리기 함수에서 이것은 개체가 아니라 요소를 참조하며이 문제를 해결하는 방법을 잘 모르겠습니다.

AddListener가 정상적으로 처리되고 마우스 down 이벤트가 트리거되어 enable/disableDragging 잘 작동합니다. 그러나이 함수에서 "this"는 드래 거 객체가 아닌 요소이므로 WindowCenter, DraggingBool 또는 Add/RemoveListener 이벤트에 액세스 할 수 없습니다.

필자는 prototype.bind를 구현해야 할 필요가있는 것처럼 보였습니다. 그러나 이것을 수행하기 위해 기존 코드를 재정렬하는 방법을 모릅니다. 또는 함수를 반환하도록 함수 중 하나를 변경합니까?

그래, 난 그냥이 POJS :

Dragger = function(element, draggingElement) { 
    this.Element = element; 
    this.DraggingElement = element; 
    this.WindowCenter; 
    this.DraggingBool = false; 

    this.AddListener(this.DraggingElement, "mousedown", this.enableDragging); 
    this.AddListener(this.DraggingElement, "mouseup", this.disableDragging); 
} 

Dragger.prototype.AddListener = function (element, eventType, listener, bubble) { 
    if (typeof (element) != "object" || typeof (listener) != "function") 
     return; 
    if (typeof (bubble) == "undefined") 
     var bubble = false; 
    eventType = eventType.toLowerCase(); 
    if (eventType.substr(0, 2) == "on") 
     eventType = eventType.substr(2); 
    if (window.addEventListener) { // Mozilla, Netscape, Firefox 
     element.addEventListener(eventType, listener, bubble); 
    } else if (window.attachEvent) { // IE 
     element.attachEvent("on" + eventType, listener); 
    } 
} 

Dragger.prototype.RemoveListener = function (element, eventType, listener) { 
    eventType = eventType.toLowerCase(); 
    if (eventType.substr(0, 2) == "on") 
     eventType = eventType.substr(2); 
    if (window.addEventListener) { // Mozilla, Netscape, Firefox 
     element.removeEventListener(eventType, listener, false); 
    } else if (window.attachEvent) { // IE 
     element.detachEvent("on" + eventType, listener); 
    } 
} 

Dragger.prototype.enableDragging = function (e) { 
    if (!e) var e = window.event; 
    //dont move for right click 
    if (e.which && e.which == 3) 
     return; 
    else if (e.button && e.button == 2) 
     return; 

    this.DraggingBool = true; 
    this.WindowCenter = new Point(e.pageX, e.pageY); 
    this.AddListener(document.body, "mouseover", this.mouseMoveListener); 
} 

Dragger.prototype.disableDragging = function() { 
    this.DraggingBool = false; 
    this.RemoveListener(document.body, "mouseover", this.mouseMoveListener); 
} 

Dragger.prototype.mouseMoveListener = function (e) { 
    if (!this.DraggingBool) 
     return; 
    if (!e) var e = window.event; 
    e.preventDefault(); 
    var newLoc = new Point(e.pageX, e.pageY); 
    var xDif = windowCenter.X - newLoc.X; 
    var yDif = windowCenter.Y - newLoc.Y; 
    this.Element.style.left = (this.Element.offsetLeft + xDif) + "px"; 
    this.Element.style.top = (this.Element.offsetTop + yDif) + "px"; 
    this.WindowCenter = newLoc; 
} 

답변

2

addEventListener 실행 범위를 사용하는 경우 때문입니다으로가는 얻을 수 있는지 확인하기 위해 노력하고, 내가 여러 번 일을, jQuery를에서이 작업을 수행 할 수있는 알고 node.onclick = foo을 사용한 것처럼 노드에 설정됩니다. IE에서 attachEvent을 사용하면 실행 범위가 전역 실행 범위가되며 이는 창입니다.

이 문제를 해결하는 한 가지 방법은 Function.call 또는 Function.apply를 사용하여 원하는 실행 범위를 지정하는 것입니다. 많은 도서관 등이에 도움이 바인딩 함수를 선언합니다 :

function bind(fn, context) { 
    return function() { 
    return fn.apply(context, arguments); 
    }; 
} 

this.AddListener(this.DraggingElement, "mousedown", 
    bind(this.enableDragging, this)); 

당신은 또한 당신의 addListener 기능에 상황에 맞는 인수를 추가 할 수 있고, 거기에 바인딩을한다.

Ecmascript 5에는 내장 된 바인딩 방법이 있습니다.

+0

브릴리언트! 건배, 개체의 인스턴스에 전역 변수를 설정하는 해킹보다 훨씬 낫다. 함수에서 하드 코드 된 것을 호출한다. :) 이제는 IE에서 작동하도록해야한다. style.left ¬.¬을 설정하십시오. 그러나 나는 그것을 이해할 것이다 ^^ – Psytronic

0
Function.prototype.bind = function() { 
    if (arguments.length < 2 && arguments[0] === undefined) { 
    return this; 
    } 

    var thisObj = this, 
    args = Array.prototype.slice.call(arguments), 

    obj = args.shift(); 

    return function() { 
    return thisObj.apply(obj, args.concat(Array.prototype.slice.call(arguments))); 
    }; 

    }; 



    Function.bind = function() { 
    var args = Array.prototype.slice.call(arguments); 
    return Function.prototype.bind.apply(args.shift(), args); 

    } 

Dragger = function(element, draggingElement) { 
    this.Element = element; 
    this.DraggingElement = element; 
    this.WindowCenter; 
    this.DraggingBool = false; 

    this.AddListener(this.DraggingElement, "mousedown", this.enableDragging,this); 
    this.AddListener(this.DraggingElement, "mouseup", this.disableDragging,this); 
} 

Dragger.prototype.AddListener = function (element, eventType, listener, bubble,dragger_obj) { 
    if (typeof (element) != "object" || typeof (listener) != "function") 
     return; 
    if (typeof (bubble) == "undefined") 
     var bubble = false; 
    eventType = eventType.toLowerCase(); 
    if (eventType.substr(0, 2) == "on") 
     eventType = eventType.substr(2); 
    if (window.addEventListener) { // Mozilla, Netscape, Firefox 
     element.addEventListener(eventType, listener.bind(dragger_obj), bubble); 
    } else if (window.attachEvent) { // IE 
     element.attachEvent("on" + eventType, listener.bind(dragger_obj)); 
    } 
} 

Dragger.prototype.RemoveListener = function (element, eventType, listener,dragger_obj) { 
    eventType = eventType.toLowerCase(); 
    if (eventType.substr(0, 2) == "on") 
     eventType = eventType.substr(2); 
    if (window.addEventListener) { // Mozilla, Netscape, Firefox 
     element.removeEventListener(eventType, listener.bind(dragger_obj), false); 
    } else if (window.attachEvent) { // IE 
     element.detachEvent("on" + eventType, listener.bind(dragger_obj)); 
    } 
} 

Dragger.prototype.enableDragging = function (e) { 
    if (!e) var e = window.event; 
    //dont move for right click 
    if (e.which && e.which == 3) 
     return; 
    else if (e.button && e.button == 2) 
     return; 

    this.DraggingBool = true; 
    this.WindowCenter = new Point(e.pageX, e.pageY); 
    this.AddListener(document.body, "mouseover", this.mouseMoveListener,this); 
} 

Dragger.prototype.disableDragging = function() { 
    this.DraggingBool = false; 
    this.RemoveListener(document.body, "mouseover", this.mouseMoveListener,this); 
} 

Dragger.prototype.mouseMoveListener = function (e) { 
    if (!this.DraggingBool) 
     return; 
    if (!e) var e = window.event; 
    e.preventDefault(); 
    var newLoc = new Point(e.pageX, e.pageY); 
    var xDif = windowCenter.X - newLoc.X; 
    var yDif = windowCenter.Y - newLoc.Y; 
    this.Element.style.left = (this.Element.offsetLeft + xDif) + "px"; 
    this.Element.style.top = (this.Element.offsetTop + yDif) + "px"; 
    this.WindowCenter = newLoc; 
} 
관련 문제