Не удалось разрешить метод объекта Javascript в этой ссылке - PullRequest
0 голосов
/ 25 июня 2010

У меня есть объект JS, который я сделал, с несколькими прототипными функциями, и с помощью этого можно нормально вызывать их из конструктора. [Function]

Но в более поздней функции обработчика событий, это относится к элементу, а не к объекту, и я не уверен, как решить эту проблему:

Он проходит через штраф AddListener, срабатывает событие нажатия мыши, в результате чего enable / disableDragging работает нормально.Но в этой функции «this» - это элемент, а не объект-перетаскиватель, поэтому я не могу вызвать доступ к событиям WindowCenter, DraggingBool или Add / RemoveListener.

При чтении мне кажется, что мне может понадобитьсяреализовать prototype.bind?Но не уверен, как изменить мой существующий код, чтобы сделать это.Или я могу изменить одну из функций, чтобы она возвращала функцию?

Да, я знаю, что мог бы сделать это в jQuery, делал это много раз, просто пытаясь понять, смогу ли я запустить его с 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 ]

2 голосов
/ 25 июня 2010

Это потому, что при использовании addEventListener область выполнения устанавливается на узел, как если бы вы использовали node.onclick = foo.Когда вы используете attachEvent в IE, область выполнения становится глобальной областью выполнения, то есть окном.

Один из способов обойти это - использовать 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 голосов
/ 25 июня 2010
  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;
}
...