Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 86 additions & 48 deletions iron-scroll-target-behavior.html
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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();
}
}
},

Expand Down Expand Up @@ -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;
},

/**
Expand All @@ -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;
},

/**
Expand All @@ -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;
}
},

Expand All @@ -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;
}
},

Expand All @@ -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;
}
},

Expand All @@ -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;
},
Expand All @@ -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);
}
},

Expand All @@ -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);
}

};
Expand Down