0

Can someone shed some light as to why this doesn't work the way I think it should (or what I'm overlooking).

function Pane(data) {
    var state = {
        show: function(data) {
            var pane = document.querySelector('.pane[data-content='+data.target+']');
            pane.classList.add('active');
        },
        hide: function(data) {
            var pane = document.querySelector('.pane[data-content='+data.target+']');
            var paneSibling = $(pane.parentNode.childNodes);
            paneSibling.each(function(sibling) {
                if(check.isElement(sibling)) {
                    var isActive = sibling.classList.contains('active');
                    if(sibling != pane && isActive) {
                        sibling.classList.remove('active');
                    };
                };
            });
        }
    }
    return state;
}

So I can console log Pane(arg).show/hide and it'll log it as a function, so why is it when I call Pane(arg).show it doesn't do anything? The functions in the object work (outside of the constructor function in their own functions).

1
  • looks like you always return the whole state object, wich wont execute Commented Dec 21, 2013 at 20:27

2 Answers 2

1

The function is returning the state object, so it will never return the constructed object, even when used with new. Since state contains those methods, you can just call the function and immediately invoke one of the methods on the returned object.

Now, if you're expecting show and hide to automatically have access to data via closure, it's not working because you're shadowing the variable by declaring the method parameters. You can do this instead:

function Pane(data) {
    var state = {
        show: function() {
            var data = data || arguments[0];
            var pane = document.querySelector('.pane[data-content='+data.target+']');
            pane.classList.add('active');
        },
        hide: function() {
            var data = data || arguments[0];
            var pane = document.querySelector('.pane[data-content='+data.target+']');
            var paneSibling = $(pane.parentNode.childNodes);
            paneSibling.each(function(sibling) {
                if(check.isElement(sibling)) {
                    var isActive = sibling.classList.contains('active');
                    if(sibling != pane && isActive) {
                        sibling.classList.remove('active');
                    };
                };
            });
        }
    }
    return state;
}

Then you can use it like this:

Pane({}).show();

Or like this:

var p = Pane();
p.show();

Or force a new argument when needed:

p.show({foo:'bar'});
Sign up to request clarification or add additional context in comments.

Comments

1

You are overriding the original argument in each function. So what you are doing is to find elements with the attribute data-content='undefined'

This obviously doesn't work.

So to fix this you should just remove the data argument in the show/hide function.

Here is a plnkr showing the problem and fix.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.