google / material-design-lite

Material Design Components in HTML/CSS/JS
https://getmdl.io
Apache License 2.0
32.28k stars 5.03k forks source link

scroll event does not work #5075

Open rtwk opened 7 years ago

rtwk commented 7 years ago

It seems that scroll event does not work with MDL. For example following code (From MDN) does not work:

`var last_known_scroll_position = 0; var ticking = false;

function doSomething(scroll_pos) { // do something with the scroll position console.log("abcdefghi"); }

window.addEventListener('scroll', function(e) { last_known_scroll_position = window.scrollY; if (!ticking) { window.requestAnimationFrame(function() { doSomething(last_known_scroll_position); ticking = false; }); } ticking = true; });` Is there a way around? Or I am missing something?

jstgermain commented 6 years ago

It seems that scroll event does not work with MDL. For example following code (From MDN) does not work:

`var last_known_scroll_position = 0; var ticking = false;

function doSomething(scroll_pos) { // do something with the scroll position console.log("abcdefghi"); }

window.addEventListener('scroll', function(e) { last_known_scroll_position = window.scrollY; if (!ticking) { window.requestAnimationFrame(function() { doSomething(last_known_scroll_position); ticking = false; }); } ticking = true; });` Is there a way around? Or I am missing something?

I am having the same issue. I am wanting the transparent nave to add a background color when scrolling beyond the 0 Y position, and it doesn't fire off with material design lite. I confirmed that the code works without material design lite being added. Not sure why it would break, but it is very frustrating and have been looking for a fix for 2 days now.

window.onscroll = function() {
  handleScroll();
}

function handleScroll() {
  var element = document.querySelector(".mdl-layout__header");
  if (window.pageYOffset <= 0 || window.pageYOffset <= 0) {
    element.classList.remove("scrolled");
  } else {
    element.classList.add("scrolled");
  }
};

see it in action from my screen recording... https://youtu.be/oo2p9HZ5msA

jstgermain commented 6 years ago

I even updated the code, following the instructions here Making-your-first-JS-component, and still no luck...

function HandleNav(element) {
    this.element_ = element;
    this.init();
};

HandleNav.prototype.init = function() {
    window.addEventListener('scroll', this.handleNavOnScroll.bind(this));
};

HandleNav.prototype.handleNavOnScroll = function(event) {
  var gbNav = this.element_.querySelector('.' + this.CssClasses_.HEADER_TRANSPARENT);
  if (window.pageYOffset <= 0 || window.pageYOffset <= 0) {
    gbNav.classList.remove("scrolled");
  } else {
    gbNav.classList.add("scrolled");
  }
};

HandleNav.prototype.CssClasses_ = {
    HEADER_TRANSPARENT: 'mdl-layout__header--transparent'
};

componentHandler.register({
    constructor: HandleNav,
    classAsString: 'HandleNav',
    cssClass: 'js-handlenav'
});
Garbee commented 6 years ago

if (window.pageYOffset <= 0 || window.pageYOffset <= 0) {

The root issue is in MDL we don't scroll on body/window. The layout creates an inner node and moves the content into that. This was due to older IE support we needed to hit. You need to check for the scroll of that container.

It should be noted, MDL is no longer maintained. Work internally has shifted to Material Components for Web which evolved from the MDL v2 efforts. So, best to try and convert to that if you can for ongoing maintenance and support.

jstgermain commented 6 years ago

if (window.pageYOffset <= 0 || window.pageYOffset <= 0) {

The root issue is in MDL we don't scroll on body/window. The layout creates an inner node and moves the content into that. This was due to older IE support we needed to hit. You need to check for the scroll of that container.

It should be noted, MDL is no longer maintained. Work internally has shifted to Material Components for Web which evolved from the MDL v2 efforts. So, best to try and convert to that if you can for ongoing maintenance and support.

thanks for the info. I have been using material-ui.org for a react project, so this is the first time messing with this one. I will look at moving over to the new MDC instead. Thanks. In the mean time, while that is being reviewed, is there a way to accomplish what I am trying to do with the older version?

jstgermain commented 6 years ago

@rtwk I was able to come up with a solution based on @Garbee response. Since mdl-layout is doing some funky stuff with body/window, if you attach a class and register it with the component on the mdl-layout__content, you can make it work...

function HandleNav(element) {
  this.element_ = element;
  this.init();
};

HandleNav.prototype.init = function() {
  this.element_.addEventListener('scroll', this.handleNavOnScroll.bind(this));
};

HandleNav.prototype.handleNavOnScroll = function (event) {
  var gbNav = document.querySelector('.' + this.CssClasses_.HEADER_TRANSPARENT);
  if (this.element_.scrollTop <= 0 || this.element_.scrollTop <= 0) {
    gbNav.classList.remove("scrolled");
  } else {
    gbNav.classList.add("scrolled");
  }
};

HandleNav.prototype.CssClasses_ = {
  HEADER_TRANSPARENT: 'mdl-layout__header--transparent'
};

componentHandler.register({
  constructor: HandleNav,
  classAsString: 'HandleNav',
  cssClass: 'js-handlenav'
});
  <div class="mdl-layout mdl-js-layout mdl-layout--fixed-header">
    <header class="mdl-layout__header mdl-layout__header--transparent">
      <div class="mdl-layout__header-row">
        ...
      </div>
    </header>
    <main class="mdl-layout__content js-handlenav">
      ...
    </main>
  </div>