Browse Source

delay finding the body until it is needed and cache it.

Igor Vaynberg 13 years ago
parent
commit
7947803df4
1 changed files with 20 additions and 4 deletions
  1. 20 4
      select2.js

+ 20 - 4
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();