Javascript - вызов метода изнутри объекта (должно быть простым решением) - PullRequest
1 голос
/ 19 июня 2011

Хорошо, ребята, я уверен, что у этого есть очень простое решение, но мои поиски ничего не дают, и я уверен, что я неправильно понимаю что-то очень простое.

Все, что я хочу сделать, - это создать объект, который содержит 2 метода, например, initialise () и zoom (), в конце инициализации я хочу вызвать метод zoom, инициализировать переменные экземпляра, например, «вот так». width = 100 ', проблема в том, что я не могу вызвать zoom () из intialise (), если я объявляю zoom следующим образом

this.zoom = function() {...};

если я объявлю это так:

function zoom() {...};

Я могу вызвать его из инициализации, но когда я пытаюсь использовать переменные экземпляра, они возвращаются как неопределенные, я также пытался определить метод как прототип, но у него та же проблема, что и у первого метода, когда я вызываю их извне объект все работает, как и ожидалось, однако, когда я пытаюсь вызвать метод из другого метода, firebug просто сообщает мне, что метод не существует.

Как я уже сказал, я уверен, что есть простое объяснение, пожалуйста, смотрите список исходных кодов ниже для получения более подробной информации, любая помощь очень благодарна, спасибо.

Я уверен, что более опытные люди увидят множество проблем в этом коде, это очень полезное упражнение, чтобы попытаться выучить упор в javascript (что очень странно, если вы не возражаете, если я это говорю), но если возможно, давайте просто разберемся с этой проблемой и не будем отвлекаться на другие вопросы, без сомнения я вернусь с ними в другой теме.

function maplocation(x, y, width, height, text, id, filename, from, to, folder)
{
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
    this.text = text;
    this.id = id;
    this.canvasID = id + "canvas";
    this.containerID = id + "container";
    this.ctx;
    this.isZoomed = false;
    this.filename = filename;

    this.addLocation = function(element)
    {
        if(supports_canvas())
        {
            // insert location html
            var returnHTML = 
            '<div id="'+this.containerID+'" style="z-index:5; position:absolute; top:' + this.y + 'px; left:' + this.x + 'px">'+
                '<canvas id="' + this.canvasID + '" width="' + this.width +'" height="' + this.height + '" style="position:absolute; top:0px; left:0px">' +
                '</canvas>' +
                '<div id="' + this.id + '" style="text-align:center; padding:15px; position:absolute; top:0px; left:0px; width:' + (this.width - 30) + 'px; height:' + this.height + 'px; cursor:pointer">' +
                    text +  
                '</div>' +
            '</div>';

            $("#"+element).append(returnHTML);

            // draw into canvas
            this.ctx = document.getElementById(this.canvasID).getContext("2d");
            this.ctx.strokeStyle = "rgb(0, 0, 0)";
            this.ctx.fillStyle = "rgba(255, 255, 255, 0.65)";
            this.ctx.lineWidth = 2.2;
            this.roundRect(this.ctx, 5, 5, this.width-10, this.height -10, 15);

            // attach events
            var e = document.getElementById(this.containerID);
            e.addEventListener("click", this.onClick, false);
        }
    }

    this.zoomIn = function()
    {
        alert(this.filename); // THIS IS THE PROBLEM, I WANT TO ACCESS INSTANCE VARIABLE FROM THIS FUNCTION
        $("#theGarden").jsMovie("destroy");

        $('#theGarden').jsMovie({
            sequence: filename,
            from: from,
            to: to,
            folder : folder,  
            showPreLoader : false,
            repeat : false,
            fps: 10,
            loadParallel: 1,
            width: 960,
            height: 529
        });
        $("#theGarden").jsMovie('play',0,15);
        //$("#theGarden").jsMovie("gotoFrame",to);
        //$("#theGarden").jsMovie("pause");
    }

    this.onClick = function(f)
    {
        this.zoomIn(); // THIS IS THE INTERNAL CALL THAT FAILS
    }

    function supports_canvas() 
    {
        return !!document.createElement('canvas').getContext;
    }

    this.roundRect = function(ctx, x, y, w, h, r) 
    {
        var mid = w/2;
        var baseOff = 10;
        var offh = h - baseOff;

        ctx.beginPath();
        ctx.moveTo(x + r, y);
        ctx.lineTo(x + w - r, y);
        ctx.quadraticCurveTo(x + w, y, x + w, y + r);
        ctx.lineTo(x + w, y + offh - r);
        ctx.quadraticCurveTo(x + w, y + offh, x + w - r, y + offh);

        ctx.lineTo(x + mid + 10, y + offh);
        ctx.lineTo(x + mid, y + h);
        ctx.lineTo(x + mid - 10, y + offh);
        ctx.lineTo(x + r, y + offh);

        ctx.quadraticCurveTo(x, y + offh, x, y + offh - r);
        ctx.lineTo(x, y + r);
        ctx.quadraticCurveTo(x, y, x + r, y);
        ctx.closePath();
        ctx.fill();
        ctx.stroke();

    }
}

1 Ответ

1 голос
/ 19 июня 2011

Если вы настраиваете эту функцию "onClick" в качестве обработчика событий, с кодом примерно таким:

  someElement.onclick = thing.onClick;

тогда проблема заключается в том, что при фактическом вызове функции (когда происходит событие) браузер не сможет организовать this, чтобы она была правильной. Таким образом, когда вы устанавливаете обработчик событий, вы должны убедиться, что вы связываете функцию, которая знает контекст:

  someElement.onclick = function() { thing.onClick(); };

edit & mdash; О, хорошо, теперь я вижу код, который связывает обработчик. Это должно выглядеть так:

        // attach events
        var e = document.getElementById(this.containerID);
        var thisObject = this;
        e.addEventListener("click", function() { thisObject.onClick(); }, false);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...