1

I'm writing a jQuery plugin that starts off like this:

$.fn.kewTip = (function() {
    var $kewtip = $('<div></div>').css({'position':'absolute','zIndex':2147483647}).attr({'class':'kewtip'}).hide().appendTo('body');

You will notice that it immediately appends an element to the page body, but it can't do that until the DOM is ready, which means the plugin can't be defined until the DOM is ready either.

However, I'd ideally like calls to $('xxx').kewTip() to not fail if they try calling it outside of $(document).ready({ ... }). So how do I get around this?

My plugin depends on this element existing, so how do I define it before the DOM is ready?

Charles
  • 50,943
  • 13
  • 104
  • 142
mpen
  • 272,448
  • 266
  • 850
  • 1,236
  • 1
    Can't you just add a `document ready callback` inside the plugin, and do your stuffs inside that? I am not sure if that's the best way but that should work. – Prasenjit Kumar Nag Jun 20 '12 at 16:16
  • @Joy: Yeah, I guess that's plausible. I just have to set the 1 var as soon as the DOM's ready. – mpen Jun 20 '12 at 16:18
  • 2
    *"However, I'd ideally like calls to `$('xxx').kewTip()` to not fail if they try calling it outside of `$(document).ready({ ... })`."* ... Why shouldn't it? It's the user's obligation to call the plugin at the right moment. Does it make sense at all to call this method if `xxx` does not exist yet? Or is the element appended as soon as the plugin is loaded? It's not clear only from the part you posted and you seem to refer to both, the definition of the plugin (first paragraph) and calling the plugin (second paragraph). – Felix Kling Jun 20 '12 at 16:18
  • @FelixKling: Absolutely. The plugin just binds some events. The events won't work until the DOM is ready, but they should be able to bind at any time. – mpen Jun 20 '12 at 16:20
  • I agree with @FelixKling. You shouldn't do all the job to secure the developer's calls. – Grigor Jun 20 '12 at 16:20

2 Answers2

4

If all you want to do is to be certain that the div exists when the plugin method is called the first time, then just create it. In order to work with the element (append elements, event handlers) it does not have to be added to the DOM.

Then, independently, add the element to body when the DOM is loaded.

For example:

$.fn.kewTip = (function() {
    // create element
    var $kewtip = $('<div />', {
        'class': 'kewtip',
        'style': 'position:absolute;zIndex:2147483647;display:none'
     });

    // add to DOM once it is ready
    $(function() {
        $kewtip.appendTo('body');
    });

    return function() {
        // here you can do whatever with `$kewtip` no matter whether it was 
        // already appended to body or not
    }
}());

(I assume you have a self invoking function there)

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
0

Based on Joy's suggestion, I came up with this:

$.fn.kewTip = (function() {
    var $kewtip = $();
    $(function() {
        $kewtip = $('<div></div>').css({'position':'absolute','zIndex':2147483647}).hide().appendTo('body');
    });

$() just gives an an empty jQuery object so the rest of the code doesn't fail catastrophically before it's ready.

Community
  • 1
  • 1
mpen
  • 272,448
  • 266
  • 850
  • 1,236