diff --git a/select2.js b/select2.js index 4ebd445a..582757e3 100755 --- a/select2.js +++ b/select2.js @@ -197,6 +197,20 @@ }; } + /** + * A simple implementation of a thunk + * @param formula function used to lazily initialize the thunk + * @return {Function} + */ + function thunk(formula) { + var evaluated = false, + value; + return function() { + if (evaluated === false) { value = formula(); evaluated=true; } + return value; + }; + }; + function installDebouncedScroll(threshold, element) { var notify = debounce(threshold, function (e) { element.trigger("scroll-debounced", e);}); element.bind("scroll", function (e) { @@ -429,7 +443,9 @@ this.enabled=true; this.container = this.createContainer(); - this.body = $("body"); // cache for future access + + // cache the body so future lookups are cheap + this.body = thunk(function() { return opts.element.closest("body"); }); if (opts.element.attr("class") !== undefined) { this.container.addClass(opts.element.attr("class")); @@ -720,7 +736,7 @@ viewportBottom = $(window).scrollTop() + document.documentElement.clientHeight, dropTop = offset.top + height, enoughRoomBelow = dropTop + dropHeight <= viewportBottom, - enoughRoomAbove = (offset.top - dropHeight) >= document.body.scrollTop, + enoughRoomAbove = (offset.top - dropHeight) >= this.body().scrollTop, aboveNow = this.dropdown.hasClass("select2-drop-above"), above, css; @@ -803,8 +819,8 @@ this.updateResults(true); - if(this.dropdown[0] !== this.body.children().last()[0]) { - this.dropdown.detach().appendTo(this.body); + if(this.dropdown[0] !== this.body().children().last()[0]) { + this.dropdown.detach().appendTo(this.body()); } this.dropdown.show();