diff --git a/iron-scroll-target-behavior.html b/iron-scroll-target-behavior.html
index 7674611..1332ce6 100644
--- a/iron-scroll-target-behavior.html
+++ b/iron-scroll-target-behavior.html
@@ -74,17 +74,23 @@
],
/**
- * True if the event listener should be installed.
+ * True if the scroll handler should be called during scroll.
*/
- _shouldHaveListener: true,
+ _scrollHandlerEnabled: true,
_scrollTargetChanged: function(scrollTarget, isAttached) {
- var eventTarget;
+ var eventTarget = this.__eventTarget;
- if (this._oldScrollTarget) {
- this._toggleScrollListener(false, this._oldScrollTarget);
- this._oldScrollTarget = null;
+ if (eventTarget) {
+ this._toggleScrollListener(false, eventTarget);
+
+ if (eventTarget.__scrollListeners.length === 0) {
+ eventTarget.__scrollListeners = null;
+ eventTarget.removeEventListener('scroll', this.__scrollHandler);
+ }
+ this.__eventTarget = null;
}
+
if (!isAttached) {
return;
}
@@ -98,12 +104,28 @@
this.scrollTarget = this.domHost ? this.domHost.$[scrollTarget] :
Polymer.dom(this.ownerDocument).querySelector('#' + scrollTarget);
- } else if (this._isValidScrollTarget()) {
+ } else if (scrollTarget instanceof HTMLElement) {
+ eventTarget = this._getEventTarget(scrollTarget);
+ this.__eventTarget = eventTarget;
- this._boundScrollHandler = this._boundScrollHandler || this._scrollHandler.bind(this);
- this._oldScrollTarget = scrollTarget;
- this._toggleScrollListener(this._shouldHaveListener, scrollTarget);
+ if (eventTarget.__scrollListeners) {
+ eventTarget.__scrollListeners.push(this);
+ } else {
+ eventTarget.__scrollListeners = [this];
+ eventTarget.addEventListener('scroll', this.__scrollHandler);
+ }
+ }
+ },
+ __scrollHandler: function() {
+ // Clear cache.
+ this.__scrollTop = null;
+ this.__scrollLeft = null;
+ var i, listeners = this.__scrollListeners;
+ for (i = 0; i < listeners.length; i++) {
+ if (listeners[i]._scrollHandlerEnabled) {
+ listeners[i]._scrollHandler();
+ }
}
},
@@ -139,10 +161,14 @@
* @type {number}
*/
get _scrollTop() {
- if (this._isValidScrollTarget()) {
- return this.scrollTarget === this._doc ? window.pageYOffset : this.scrollTarget.scrollTop;
+ var target = this.__eventTarget;
+ if (!target) {
+ return 0;
}
- return 0;
+ if (target.__scrollTop == null) {
+ target.__scrollTop = target === window ? window.pageYOffset : target.scrollTop;
+ }
+ return target.__scrollTop;
},
/**
@@ -151,10 +177,14 @@
* @type {number}
*/
get _scrollLeft() {
- if (this._isValidScrollTarget()) {
- return this.scrollTarget === this._doc ? window.pageXOffset : this.scrollTarget.scrollLeft;
+ var target = this.__eventTarget;
+ if (!target) {
+ return 0;
}
- return 0;
+ if (target.__scrollLeft == null) {
+ target.__scrollLeft = target === window ? window.pageXOffset : target.scrollLeft;
+ }
+ return target.__scrollLeft;
},
/**
@@ -163,10 +193,15 @@
* @type {number}
*/
set _scrollTop(top) {
- if (this.scrollTarget === this._doc) {
+ var target = this.__eventTarget;
+ if (!target) {
+ return;
+ }
+ target.__scrollTop = null;
+ if (target === window) {
window.scrollTo(window.pageXOffset, top);
- } else if (this._isValidScrollTarget()) {
- this.scrollTarget.scrollTop = top;
+ } else {
+ target.scrollTop = top;
}
},
@@ -176,10 +211,15 @@
* @type {number}
*/
set _scrollLeft(left) {
- if (this.scrollTarget === this._doc) {
+ var target = this.__eventTarget;
+ if (!target) {
+ return;
+ }
+ target.__scrollLeft = null;
+ if (target === window) {
window.scrollTo(left, window.pageYOffset);
- } else if (this._isValidScrollTarget()) {
- this.scrollTarget.scrollLeft = left;
+ } else {
+ target.scrollLeft = left;
}
},
@@ -191,11 +231,17 @@
* @param {number} top The top position
*/
scroll: function(left, top) {
- if (this.scrollTarget === this._doc) {
+ var target = this.__eventTarget;
+ if (!target) {
+ return;
+ }
+ target.__scrollTop = null;
+ target.__scrollLeft = null;
+ if (target === window) {
window.scrollTo(left, top);
- } else if (this._isValidScrollTarget()) {
- this.scrollTarget.scrollLeft = left;
- this.scrollTarget.scrollTop = top;
+ } else {
+ target.scrollLeft = left;
+ target.scrollTop = top;
}
},
@@ -205,8 +251,8 @@
* @type {number}
*/
get _scrollTargetWidth() {
- if (this._isValidScrollTarget()) {
- return this.scrollTarget === this._doc ? window.innerWidth : this.scrollTarget.offsetWidth;
+ if (this.__eventTarget) {
+ return this.__eventTarget === window ? window.innerWidth : this.__eventTarget.offsetWidth;
}
return 0;
},
@@ -217,31 +263,23 @@
* @type {number}
*/
get _scrollTargetHeight() {
- if (this._isValidScrollTarget()) {
- return this.scrollTarget === this._doc ? window.innerHeight : this.scrollTarget.offsetHeight;
+ if (this.__eventTarget) {
+ return this.__eventTarget === window ? window.innerHeight : this.__eventTarget.offsetHeight;
}
return 0;
},
- /**
- * Returns true if the scroll target is a valid HTMLElement.
- *
- * @return {boolean}
- */
- _isValidScrollTarget: function() {
- return this.scrollTarget instanceof HTMLElement;
+ _getEventTarget: function(scrollTarget) {
+ return scrollTarget === this._doc ? window : scrollTarget;
},
- _toggleScrollListener: function(yes, scrollTarget) {
- if (!this._boundScrollHandler) {
- return;
- }
- var eventTarget = scrollTarget === this._doc ? window : scrollTarget;
+ _toggleScrollListener: function(yes, eventTarget) {
+ var sidx = eventTarget.__scrollListeners.indexOf(this);
- if (yes) {
- eventTarget.addEventListener('scroll', this._boundScrollHandler);
- } else {
- eventTarget.removeEventListener('scroll', this._boundScrollHandler);
+ if (yes && sidx == -1) {
+ eventTarget.__scrollListeners.push(this);
+ } else if (!yes && sidx >= 0) {
+ eventTarget.__scrollListeners.splice(sidx, 1);
}
},
@@ -251,8 +289,8 @@
* @param {boolean} yes True to add the event, False to remove it.
*/
toggleScrollListener: function(yes) {
- this._shouldHaveListener = yes;
- this._toggleScrollListener(yes, this.scrollTarget);
+ this._scrollHandlerEnabled = yes;
+ this._toggleScrollListener(yes, this.__eventTarget);
}
};