aventic
aventic

Reputation: 1514

Bind event listener from outside function

How can I from the outside of my init function, fire off the reset function within init.

I want my reset function to reset all variables set from the collection of the images (3 in this case) which is bound 3 times. My example here isn't working I'm aware.

Here's my code:

    document.getElementsByClassName('zoomer-start')[0].addEventListener('click', init);

    document.getElementsByClassName('zoomer-reset')[0].addEventListener('click', reset);

    function init() {
        var images = document.querySelectorAll('.zoomer-img');

        for (var i = 0; i < images.length; i++) {
            (function() {
                var image = images[i];

                var zoomer = new Hammer(image);

                zoomer.get('pinch').set({enable: false});
                zoomer.get('pan').set({enable: false});

                var clicked = false;

                var adjustScale = 1;
                var adjustDeltaX = 0;
                var adjustDeltaY = 0;

                var currentScale = null;
                var currentDeltaX = null;
                var currentDeltaY = null;

                zoomer.on('tap', function (e) {
                    if (!clicked) {
                        zoomer.get('pinch').set({enable: true});
                        zoomer.get('pan').set({enable: true, direction: Hammer.DIRECTION_ALL});
                        clicked = true;
                    } else {
                        zoomer.get('pinch').set({enable: false});
                        zoomer.get('pan').set({enable: false});
                        clicked = false;
                    }

                    if (currentScale > 1) {
                        adjustScale = 1;
                        adjustDeltaX = 0;
                        adjustDeltaY = 0;
                    } else {
                        adjustScale = 2;
                    }

                    currentScale = adjustScale * e.scale;
                    currentDeltaX = adjustDeltaX + (e.deltaX / currentScale);
                    currentDeltaY = adjustDeltaY + (e.deltaY / currentScale);

                    image.style.transform = 'scale(' + currentScale + ') translate3d(' + currentDeltaX + 'px, ' + currentDeltaY + 'px, 0)';
                });

                zoomer.on('pan pinch', function (e) {
                    currentScale = Math.max(1, Math.min(adjustScale * e.scale, 4));
                    currentDeltaX = adjustDeltaX + (e.deltaX / currentScale);
                    currentDeltaY = adjustDeltaY + (e.deltaY / currentScale);

                    var scaledX = ((((image.width * currentScale) / 2) - (image.width / 2)) / currentScale);
                    if (currentDeltaX > scaledX)
                        currentDeltaX = scaledX;
                    if (currentDeltaX < -scaledX)
                        currentDeltaX = -scaledX;

                    var scaledY = ((((image.height * currentScale) / 2) - (image.height / 2)) / currentScale);
                    if (currentDeltaY > scaledY)
                        currentDeltaY = scaledY;
                    if (currentDeltaY < -scaledY)
                        currentDeltaY = -scaledY;

                    image.style.transform = 'scale(' + currentScale + ') translate3d(' + currentDeltaX + 'px, ' + currentDeltaY + 'px, 0)';
                });

                zoomer.on('panend pinchend', function () {
                    adjustScale = currentScale;
                    adjustDeltaX = currentDeltaX;
                    adjustDeltaY = currentDeltaY;
                });

                function reset() {
                    zoomer.get('pinch').set({enable: false});
                    zoomer.get('pan').set({enable: false});

                    clicked = false;

                    adjustScale = 1;
                    adjustDeltaX = 0;
                    adjustDeltaY = 0;

                    currentScale = null;
                    currentDeltaX = null;
                    currentDeltaY = null;

                    image.style.transform = 'scale(' + 1 + ') translate3d(' + 0 + 'px, ' + 0 + 'px, 0)';
                }
            })();
        }
    }

Upvotes: 0

Views: 737

Answers (4)

aventic
aventic

Reputation: 1514

Thanks guys, I learned something today! Here's my working example. Really really neat:

    var resets = [];

    document.getElementsByClassName('zoomer-start')[0].addEventListener('click', init);

    document.getElementsByClassName('zoomer-reset')[0].addEventListener('click', function () {
        var images = document.querySelectorAll('.zoomer-img');

        for (var i = 0; i < images.length; i++) {
            resets[i]();
        }
    });

    function init() {
        var images = document.querySelectorAll('.zoomer-img');

        for (var i = 0; i < images.length; i++) {
            (function(i) {
                var image = images[i];

                var zoomer = new Hammer(image);

                zoomer.get('pinch').set({enable: false});
                zoomer.get('pan').set({enable: false});

                var clicked = false;

                var adjustScale = 1;
                var adjustDeltaX = 0;
                var adjustDeltaY = 0;

                var currentScale = null;
                var currentDeltaX = null;
                var currentDeltaY = null;

                zoomer.on('tap', function (e) {
                    if (!clicked) {
                        zoomer.get('pinch').set({enable: true});
                        zoomer.get('pan').set({enable: true, direction: Hammer.DIRECTION_ALL});
                        clicked = true;
                    } else {
                        zoomer.get('pinch').set({enable: false});
                        zoomer.get('pan').set({enable: false});
                        clicked = false;
                    }

                    if (currentScale > 1) {
                        adjustScale = 1;
                        adjustDeltaX = 0;
                        adjustDeltaY = 0;
                    } else {
                        adjustScale = 2;
                    }

                    currentScale = adjustScale * e.scale;
                    currentDeltaX = adjustDeltaX + (e.deltaX / currentScale);
                    currentDeltaY = adjustDeltaY + (e.deltaY / currentScale);

                    image.style.transform = 'scale(' + currentScale + ') translate3d(' + currentDeltaX + 'px, ' + currentDeltaY + 'px, 0)';
                });

                zoomer.on('pan pinch', function (e) {
                    currentScale = Math.max(1, Math.min(adjustScale * e.scale, 4));
                    currentDeltaX = adjustDeltaX + (e.deltaX / currentScale);
                    currentDeltaY = adjustDeltaY + (e.deltaY / currentScale);

                    var scaledX = ((((image.width * currentScale) / 2) - (image.width / 2)) / currentScale);
                    if (currentDeltaX > scaledX)
                        currentDeltaX = scaledX;
                    if (currentDeltaX < -scaledX)
                        currentDeltaX = -scaledX;

                    var scaledY = ((((image.height * currentScale) / 2) - (image.height / 2)) / currentScale);
                    if (currentDeltaY > scaledY)
                        currentDeltaY = scaledY;
                    if (currentDeltaY < -scaledY)
                        currentDeltaY = -scaledY;

                    image.style.transform = 'scale(' + currentScale + ') translate3d(' + currentDeltaX + 'px, ' + currentDeltaY + 'px, 0)';
                });

                zoomer.on('panend pinchend', function () {
                    adjustScale = currentScale;
                    adjustDeltaX = currentDeltaX;
                    adjustDeltaY = currentDeltaY;
                });

                resets[i] = function reset() {
                    zoomer.get('pinch').set({enable: false});
                    zoomer.get('pan').set({enable: false});

                    clicked = false;

                    adjustScale = 1;
                    adjustDeltaX = 0;
                    adjustDeltaY = 0;

                    currentScale = null;
                    currentDeltaX = null;
                    currentDeltaY = null;

                    image.style.transform = 'scale(' + 1 + ') translate3d(' + 0 + 'px, ' + 0 + 'px, 0)';
                }
            })(i);
        }
    }

Upvotes: 0

Koder
Koder

Reputation: 474

To call function(s) from withinn scope you have to pass it somehow to the surronding scope. One possible example for Your code:

var resets = [];
function init() {
[...]
    for (var i = 0; i < images.length; i++) {
        (function() {
            [...]
            resets[i]=function reset() {
            [...]
            })

And then call them naively:

resets[0](); resets[1](); resets[2];

Or via:

resets.forEach(function(f) { f(); } );

Upvotes: 1

T.J. Crowder
T.J. Crowder

Reputation: 1074258

With the code as written, you can't. The reset function is entirely private to the code in the anonymous function inside init. Even other code in init can't access it, much less code outside init.

I say "it" above, but really, you have multiple reset functions, one for each image.

You could, of course, move your code trying to use it as a click handler into that anonymous function inside init. That's basically your only real option, other than creating an array or similar of reset functions that you expose outside init.

Upvotes: 1

Bug
Bug

Reputation: 528

Having your functions inside the init function gives them Private SCOPE only (can only be accessed from within the init function) To give them global scope you will have to move them outside of the init function which will require some code restructuring.

Upvotes: 1

Related Questions