Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

on-lower-threshold is only triggered at page load #23

Open
doughaase opened this issue Feb 21, 2017 · 25 comments
Open

on-lower-threshold is only triggered at page load #23

doughaase opened this issue Feb 21, 2017 · 25 comments

Comments

@doughaase
Copy link

doughaase commented Feb 21, 2017

Description

I'm trying to use the iron-scroll-threshold combined with iron-list.
When I open up the page that has the list, on-lower-threshold is fired. Nothing happens as I scroll the list.

I have the following file structure:

  • index.html (has a body tag that encapsulates <my-app> element).
  • my-app.html (has an app-drawer layout + app-header-layout and the declared <iron-pages> inside it).
  • person-list.html (one of the previously declared iron-pages. Has the iron-ajax the populates the iron-list that its encapsulated by iron-scroll-threshold.

index.html:

<style>
      body {
        margin: 0;
        font-family: 'Roboto', 'Noto', sans-serif;
        line-height: 1.5;
        height: 100vh;
        background-color: #eeeeee;
      }
    </style>
  </head>
  <body>
    <my-app></my-app>    
  </body>

my-app.html has nothing specific regarding css heights or layouts, only the display:block value:

 :host {
        --app-primary-color: #002F5B;
        --app-secondary-color: black;
        display: block;        
      }   

person-list.html:

:host {     
          padding: 10px;           
          display: block; 
          @apply(--paper-font-common-base);
      }
      iron-list {
        height: 90vh;    
    }
    <iron-scroll-threshold id="threshold"                           
                           lower-threshold="100"
                           on-lower-threshold="loadMoreData"
                           lower-triggered="{{nearBottom}}">

      <iron-list id="personlist" scroll-target="threshold" items="[[persons]]" as="item" hidden$="[[!storedUser.loggedin]]" selection-enabled>
        <template>
          <div>
              <div class$="[[getClassForItem(item, selected)]]" tabindex$="[[tabIndex]]">                
                  <div class="pad">                      
                      <div class="primary-text" hidden$="[[item.apelido]]">[[item.nome]]</div>
                  </div>
              </div>
          </div>           
        </template>
      </iron-list>
    </iron-scroll-threshold>
 loadMoreData: function() {
         console.log('test');
       }

I didn't declared any div for the iron-scroll-threshold. It's just: dom > template > style > ajax > iron-scroll > iron-list.

Expected outcome

The scroll to the near bottom of the list should fire the function loadMoreData.

Actual outcome

The function is fired when I load the page, and nothing else happens. The scroll is not triggering the on-lower-threshold.

I'm following the documentation:
https://www.webcomponents.org/element/PolymerElements/iron-scroll-threshold
... and as far as I know, the example matches what I just coded.

@cmevawala
Copy link

You need to clear the triggers: this.$.scrollTheshold.clearTriggers();
check this link: https://github.com/PolymerElements/iron-list/blob/master/demo/scroll-threshold.html

@blasten
Copy link
Contributor

blasten commented Mar 3, 2017

Yep.

@blasten blasten closed this as completed Mar 3, 2017
@doughaase
Copy link
Author

The clearTriggers function was already on that code the whole time. Why is this issue closed? That was not the solution.

@blasten
Copy link
Contributor

blasten commented Mar 3, 2017

@doughaase are you able to send a complete jsbin?

@blasten blasten reopened this Mar 3, 2017
@karthik-hande
Copy link

karthik-hande commented Mar 27, 2017

Even I'm facing the same issue!! on-lower-threshold="loadMoreData" is not triggering function

@Mika83AC
Copy link

I'm facing the same issue. The on-xxx-threshold functions are triggered on page load, but not when scrolling to the top or bottom of the defined area.

I'm using it with a dom-repeat:

<ul id="movies" class="grid" on-scroll="_onScroll" scroll-target="scrollThreshold">
   <template id="moviesList" is="dom-repeat" items="[[state.visibleList]]">
      <li>
         <mmc-list-item movie="[[item]]"></mmc-list-item>
      </li>
   </template>
</ul>

<iron-scroll-threshold id="scrollThreshold" on-upper-threshold="_onUpperThreshold" on-lower-threshold="_onLowerThreshold">
</iron-scroll-threshold>
_onUpperThreshold: function() {
   this.$.scrollThreshold.clearTriggers();
},
_onLowerThreshold: function() {
   this.$.scrollThreshold.clearTriggers();
},

Regards,
Michael

@marko911
Copy link

I'm facing exact same issue. The lower-threshold is only triggered on page load and it seems like the iron-scroll-threshold element isn't even listening to scroll events. When I scroll to the bottom o the list it never fires. I also cleared triggers after the inital fire and still same thing. My host element is set to height:100vh and the code for this element is

 </style>

    <iron-scroll-threshold on-lower-threshold="loadMoreData" lower-threshold="500" id="threshold">
      <template is="dom-repeat" items="[[list]]" scroll-target="document">
        <paper-icon-item class="article">
          <div item-icon>
            <div class="number">{{getIndex(index)}}</div>
          </div>
          <paper-ripple class="article"></paper-ripple>
          <div class="inner"><a href="[[item.url]]" target="_blank">[[item.title]]</a>
            <template is="dom-if" if="[[showComments]]">
              <div class="comments">[[item.domain]]<a href="https://www.reddit.com[[item.permalink]]" target="_blank">[[item.num_comments]]
                comments</a></div>
            </template>
          </div>
          <paper-icon-button on-tap="toggleFave" class="favorite" icon="{{getStarType(item)}}"></paper-icon-button>
        </paper-icon-item>
      </template>
    </iron-scroll-threshold>
  </template>
  <script>
    class Articles {
      beforeRegister() {
        this.is = "gd-articles"
        this.properties = {
          list: {
            type: Array,
            value: [],
            observer: 'isReddit'
          },
          themeColor: {
            type: String,
            value: "",
            observer: 'getTheme'
          },
          showComments: {
            type: Boolean,
            value: "",
          }
        }
      }

      getIndex(index) {
        return index + 1;
      }

      loadMoreData() {
        console.log('fire!');
      }

@chwzr
Copy link

chwzr commented May 22, 2017

hey i have also the same issue with iron-scroll-threshold, using the app-toolbox basic app-template(from the tutorial on the polymer page). The function gets fired on pageload, and after this never again, even when i clear the triggers..
I think its an issue with the scroll-target property.
if i use it as in the demo "scrolling region" it is working fine. But if i set this to 100% hight and 100%width, there are two scrollbars. and the original scrollbar of the iron page element is not used. -->looks ugly

then I've tried to use the dom modul view itself: "my-view3" as scroll-target. --> also not working
then i've seen this and i am thinking this is causing the issue, as this element has its own scroller and this scroller i want to use as scroll-target. i think then it should work as aspected. ive added an ID to the app-header-layout element like so:

and then i used this at my page:

<iron-scroll-threshold id="scrollThreshold" lower-threshold="500" on-lower-threshold="loadMoreData" scroll-target="[[target]]"> </iron-scroll-threshold>

and in the script section of the page i tried to use something this

          constructor() {
              this.scrollTarget = Polymer.dom(this.root).querySelector('#scrollHeader').scrollTarget;
          }

but it console it says: Polymer.dom(...).querySelector(...) is null

does anyone know how to adress this element in a propper way? i think it is null because it is in the my-app.html file, and i am doing this in the my-view3.html file which is included via iron-pages.

it would be a breeze if someone knows a way of adding iron-scroll-threshold to a iron page of the default app-toolbox template 👍

kind regards

chwzr

@dshukertjr
Copy link

I'm also facing similar problem. Waiting for responce...

@chwzr
Copy link

chwzr commented May 26, 2017

I found out if i use the app-header without "has-scrolling-region" it work as aspected.
So please tell us a way how to make it working with the has-scrolling-region activated.. i guess we just have to set a propper scroll target. but how and which target?

in the documentation of the app-header layout, its mentioned that it uses the document as scroll target for the has-scrolling-region, but it dont think so/ when i define document as scroll target for the iron-scrolling-threshold it only triggers once for obvious reasons.

so in the meantime i do not use the has-scrolling-region ( but I think it looks better with this.. ).

kind regards :)

@dshukertjr
Copy link

When I removed the "has-scrolling-region" attribute from the app-header element, the on-lower-threshold event started firing every time I scroll the document no matter how close I am to the bottom or which direction I am scrolling.

@marko911
Copy link

One thing Ive noticed is to make sure to put the scroll target as the element that actually does the scrolling. In some cases it might be a parent element.

@dshukertjr
Copy link

dshukertjr commented May 26, 2017

So this is what I have:

My app-header-layout has an id of "appHeaderLayout" like the following
<app-header-layout id="appHeaderLayout" has-scrolling-region>
and along with that, I have the iron-scroll-threshold element as app-header-layout element's parent's sibling element
<iron-scroll-threshold on-lower-threshold="_loadMoreQuestions" lower-threshold="400" id="threshold" lower-triggered="{{nearBottom}}" scroll-target="appHeaderLayout"> </iron-scroll-threshold>

I have its scroll-target attribute set to the id of app-header element, but the on-lower-threshold event is triggered only once when the page first loads. Yes, I have called the clearTriggers() method as following:
_loadMoreQuestions: function(){ console.log('load more questions fired'); var threshold=this.$.threshold; threshold.clearTriggers(); },

@marko911
Copy link

I ended up writing my own infinite scroll functions because this element is broken at the moment.

@dshukertjr
Copy link

I guess that is what I would do too then

@jurerick
Copy link

jurerick commented Jun 9, 2017

I have the same problem

@dheerajsarwaiya
Copy link

@marko911 - Is it possible for you to share your solution. I am stuck at the same place. Thanks.

@marko911
Copy link

marko911 commented Sep 5, 2017

Rough version here so play with it to accommodate your own use. @dheerajsarwaiya

Basically add this behavior to the
element where your scroll container lives and then set the property scrollTarget to that container ie. `this.set('scrollTarget', this.$.scrollingContainer) or use Polymer dom api etc.

Also on the same element you add this behavior, add a 'scroll-trigger' listener so you can fire what you need to when scroll threshold is reached.

<link rel="import" href="../../bower_components/polymer/polymer.html">

<script>
  window.GdBehaviors = window.GdBehaviors || {};
  GdBehaviors.GdInfiniteScrollBehavior = {
    properties: {

      scrollTarget: {
        type: Object,
        observer: '_scrollTargetChanged'
      },

      lowerThreshold: {
        type: Number,
        value: 80
      },

      lowerTriggered: {
        type: Boolean,
        value: false,
        notify: true,
        readOnly: true
      }
    },

    _scrollTargetChanged(target) {
      if (target) {
        this._toggleScrollListener(target);
      }
    },


    scrollHandler: function () {
      const THROTTLE_THRESHOLD = 200;
      if (!this.isDebouncerActive('_checkThreshold')) {
        this.debounce('_checkThreshold', function () {
          this.checkScrollThresholds();
        }, THROTTLE_THRESHOLD);
      }
    },

    checkScrollThresholds: function () {
      const lowerScrollValue = this.scrollTarget.scrollHeight - this.scrollTarget.offsetHeight - this.scrollTarget.scrollTop;
      if (lowerScrollValue <= this.lowerThreshold && !this.lowerTriggered) {
        this._setLowerTriggered(true);
        this.fire('scroll-trigger');
      }
    },

    _toggleScrollListener: function (target) {
      this.set('scrollTarget', target);
      target.addEventListener('scroll', this.scrollHandler.bind(this));
    },

    clearTrigger: function () {
      this._setLowerTriggered(false);
    }
  }

</script>

@jonadeline
Copy link

jonadeline commented Oct 4, 2017

+1.
2 days I'm facing the problem, finally ending here.

@jonadeline
Copy link

jonadeline commented Nov 9, 2017

I've finally make it work. In my case, I'm using the <iron-scroll-threshold> on a <paper-dialog-scrollable> element. After many tests I noticed that I had to wait the <paper-dialog> to be opened in order <iron-scroll-threshold> can get the correct height of the scrollable target. If not <iron-scroll-threshold> fires the lower-threshold event at loading as the scrollable target doesn't exist yet. It's like <iron-scroll-threshold> understands that behavior as the scroll is at the bottom of the scrollable target.

So I decided to put the <iron-scroll-threshold> in a <dom-if> binded to the open state of the paper-dialog.

Roughly here is what I've done :

HTML :

<paper-dialog with-backdrop auto-fit-on-attach on-iron-overlay-opened="_handleOverlayOpening">
      <paper-dialog-scrollable id="scroll">
        <div class="layout vertical">
          <template is="dom-repeat" items="[[items]]">
            <paper-checkbox >
              [[item]]
            </paper-checkbox>
          </template>
        </div>
      </paper-dialog-scrollable>
</paper-dialog>

<dom-if if="[[_isOpen]]">
      <template>
        <iron-scroll-threshold id="scrollTheshold" scroll-target="scroll" on-lower-threshold="_loadMoreData"></iron-scroll-threshold>
      </template>
</dom-if>

JS :

_handleOverlayOpening() {
   this._isOpen = true;
}

_loadMoreData(e) {
    console.log('yihaaaa');
}

Hope this can help in your use cases. Probably you have juste to wait an other element to be fully ready before to init your <iron-scroll-threshold>

@derhuebiii
Copy link

I've finally make it work. In my case, I'm using the <iron-scroll-threshold> on a <paper-dialog-scrollable> element. After many tests I noticed that I had to wait the <paper-dialog> to be opened in order <iron-scroll-threshold> can get the correct height of the scrollable target. If not <iron-scroll-threshold> fires the lower-threshold event at loading as the scrollable target doesn't exist yet. It's like <iron-scroll-threshold> understands that behavior as the scroll is at the bottom of the scrollable target.

So I decided to put the <iron-scroll-threshold> in a <dom-if> binded to the open state of the paper-dialog.

Roughly here is what I've done :

HTML :

<paper-dialog with-backdrop auto-fit-on-attach on-iron-overlay-opened="_handleOverlayOpening">
      <paper-dialog-scrollable id="scroll">
        <div class="layout vertical">
          <template is="dom-repeat" items="[[items]]">
            <paper-checkbox >
              [[item]]
            </paper-checkbox>
          </template>
        </div>
      </paper-dialog-scrollable>
</paper-dialog>

<dom-if if="[[_isOpen]]">
      <template>
        <iron-scroll-threshold id="scrollTheshold" scroll-target="scroll" on-lower-threshold="_loadMoreData"></iron-scroll-threshold>
      </template>
</dom-if>

JS :

_handleOverlayOpening() {
   this._isOpen = true;
}

_loadMoreData(e) {
    console.log('yihaaaa');
}

Hope this can help in your use cases. Probably you have juste to wait an other element to be fully ready before to init your <iron-scroll-threshold>

This is not working for me unfortunately. And isn't it the same effect als calling clearTriggers? The problem also is, when #scrollThreshold is inside the dom-if, I cannot access it for clearTriggers anymore...

@cipheroth
Copy link

It does not work with Polymer 3 !!!!!! or what the fuck ???

@dheerajsarwaiya
Copy link

I worked on Polymer from 2016 to mid of 2018 .. and then I started learning React .. It would not be wrong to say that React is far superior than polymer. Leave polymer before google shut it down. (they are planning to )

@cipheroth
Copy link

Nah, I am going to push and support the idea of WebComponents, and I have used React for many other projects. Im just going to create my own Element/Component. Thanks

@ptytb
Copy link

ptytb commented May 8, 2019

Solved with switching to alicorn-scroll-watcher, seems to work just fine. Install yarn add alicorn-scroll-watcher-p3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests