1

I'm just starting to write my own plugin but I'm having a bit of difficulty in storing jQuery objects as instance variables. By this I mean, for example, in the following code:

$.widget("ns.slider", {
    options: {
        "selector": "li",
        "selected": 0,
        "delay": 1000
    },
    _create: function() {
        var slider= this;
        this.element.addClass("slider");
        this.container = $("<div class=\"slider-container\"></div>");
        this.container.height($(this.element).height());
        $(this.element).wrap(this.container).css({
            "position": "absolute",
            "top": 0,
            "left": 0,
            "right": 0
        });
        this.container.css({"position": "relative", "overflow": "hidden", "backgroundColor": "#CCC"}); // Problem line
        this.container.remove(); // Also problem line
    }
}

The two lines I have marked as problem lines don't appear to execute - or rather they do, but the changes are not visible on the page. I'd expect to see the background colour to go grey on the first line and to disappear completely on the second. It seems like the wrap function actually duplicates the element and the duplicated element maintains the old properties when changes are made to the original. Yet I'm sure I've used this before, years ago, and it worked fine.

I'm using jQuery 1.8.3 with jQuery UI 1.10.4. Before anyone says it, I know there is already a jQuery UI slider - I had to rename the plugin for the purpose of this question for confidentiality reasons.

What am I doing wrong here? Please let me know if there is any additional information I should supply. Thanks in advance.

3
  • Could is be that the dom has not finished loaded when you call that? Have you tried setting a timeout to see if it makes a difference? Commented Nov 23, 2014 at 1:17
  • The call to the plugin is within $(document).ready(). I can see that this.container is being added to the DOM using dev tools - but anything called on this.container does not have any impact on the DOM element. I'll try calling a timeout in any case. Commented Nov 23, 2014 at 1:19
  • Nope - that didn't work. I tried: setTimeout(function() { slider.container.effect("highlight", 2000); }, 2000); Commented Nov 23, 2014 at 1:22

1 Answer 1

1

jQuery's wrap method clones the element. The following uses a cloned version of the container element:

$(this.element).wrap(this.container) // `this.container` is cloned first

When you try to apply the styles after the fact, those styles are applied to the non-cloned version that wasn't attached to the DOM.


You can fix this by adding the styles prior to wrapping the element:

container.css({"position": "relative", "overflow": "hidden", "backgroundColor": "#CCC"});
$(this.element).wrap(this.container)


Also note that calling remove doesn't remove anything because only the cloned container was attached to the DOM. Instead clean it up by setting it to null.

container = null;


Here is a JSFiddle: http://jsfiddle.net/0db32Lzh/

Sign up to request clarification or add additional context in comments.

1 Comment

Excellent, thanks istos. I thought that might be the case and this confirms it. I have actually found a workaround which allows me to store it as an instance variable (the purpose of this being that I can quickly reference it in other functions): this.container = $(this.element).wrap("<div class=\"slider-container\"></div>").parent();. Works a treat now :).

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.