Element: [Bug Report] el-collapse-transition: overflow not reset when switching to fast

Created on 30 May 2019  ·  3Comments  ·  Source: ElemeFE/element

Element UI version

2.9.0

OS/Browsers version

Chrome

Vue version

2.6.10

Reproduction Link

https://jsfiddle.net/aurelienlt89/mp27wuhb/10/

Steps to reproduce

Click on the "Try" button

What is Expected?

The overflow should be reset to its original value (undefined)

What is actually happening?

The overflow stays to "hidden"

This is due to the functions enter and beforeLeave not checking the state while saving the current overflow in oldOverflow.
Because of that, oldOverflow is set to "hidden" when it should be untouched because in transition already.
It is also the case for other saved styles: padding-top and padding-bottom

Most helpful comment

This fixes it

import { addClass, removeClass } from 'element-ui/src/utils/dom';

class Transition {
  beforeEnter(el) {
    addClass(el, 'collapse-transition');
    if (!el.dataset) el.dataset = {};

    if (!('oldPaddingTop' in el.dataset)) {
      el.dataset.oldPaddingTop = el.style.paddingTop;
      el.dataset.oldPaddingBottom = el.style.paddingBottom;
    }

    el.style.height = '0';
    el.style.paddingTop = 0;
    el.style.paddingBottom = 0;
  }

  enter(el) {
    if (!('oldOverflow' in el.dataset)) {
      el.dataset.oldOverflow = el.style.overflow;
    }
    if (el.scrollHeight !== 0) {
      el.style.height = el.scrollHeight + 'px';
      el.style.paddingTop = el.dataset.oldPaddingTop;
      el.style.paddingBottom = el.dataset.oldPaddingBottom;
    } else {
      el.style.height = '';
      el.style.paddingTop = el.dataset.oldPaddingTop;
      el.style.paddingBottom = el.dataset.oldPaddingBottom;
    }
    delete el.dataset.oldPaddingTop;
    delete el.dataset.oldPaddingBottom;

    el.style.overflow = 'hidden';
  }

  afterEnter(el) {
    // for safari: remove class then reset height is necessary
    removeClass(el, 'collapse-transition');
    el.style.height = '';
    el.style.overflow = el.dataset.oldOverflow;
    delete el.dataset.oldOverflow;
  }

  beforeLeave(el) {
    if (!el.dataset) el.dataset = {};
    if (!('oldPaddingTop' in el.dataset)) {
      el.dataset.oldPaddingTop = el.style.paddingTop;
      el.dataset.oldPaddingBottom = el.style.paddingBottom;
    }
    if (!('oldOverflow' in el.dataset)) {
      el.dataset.oldOverflow = el.style.overflow;
    }

    el.style.height = el.scrollHeight + 'px';
    el.style.overflow = 'hidden';
  }

  leave(el) {
    if (el.scrollHeight !== 0) {
      // for safari: add class after set height, or it will jump to zero height suddenly, weired
      addClass(el, 'collapse-transition');
      el.style.height = 0;
      el.style.paddingTop = 0;
      el.style.paddingBottom = 0;
    }
  }

  afterLeave(el) {
    removeClass(el, 'collapse-transition');
    el.style.height = '';
    el.style.overflow = el.dataset.oldOverflow;
    el.style.paddingTop = el.dataset.oldPaddingTop;
    el.style.paddingBottom = el.dataset.oldPaddingBottom;
    delete el.dataset.oldOverflow;
    delete el.dataset.oldPaddingTop;
    delete el.dataset.oldPaddingBottom;
  }
}

export default {
  name: 'ElCollapseTransition',
  functional: true,
  render(h, { children }) {
    const data = {
      on: new Transition()
    };

    return h('transition', data, children);
  }
};

All 3 comments

This fixes it

import { addClass, removeClass } from 'element-ui/src/utils/dom';

class Transition {
  beforeEnter(el) {
    addClass(el, 'collapse-transition');
    if (!el.dataset) el.dataset = {};

    if (!('oldPaddingTop' in el.dataset)) {
      el.dataset.oldPaddingTop = el.style.paddingTop;
      el.dataset.oldPaddingBottom = el.style.paddingBottom;
    }

    el.style.height = '0';
    el.style.paddingTop = 0;
    el.style.paddingBottom = 0;
  }

  enter(el) {
    if (!('oldOverflow' in el.dataset)) {
      el.dataset.oldOverflow = el.style.overflow;
    }
    if (el.scrollHeight !== 0) {
      el.style.height = el.scrollHeight + 'px';
      el.style.paddingTop = el.dataset.oldPaddingTop;
      el.style.paddingBottom = el.dataset.oldPaddingBottom;
    } else {
      el.style.height = '';
      el.style.paddingTop = el.dataset.oldPaddingTop;
      el.style.paddingBottom = el.dataset.oldPaddingBottom;
    }
    delete el.dataset.oldPaddingTop;
    delete el.dataset.oldPaddingBottom;

    el.style.overflow = 'hidden';
  }

  afterEnter(el) {
    // for safari: remove class then reset height is necessary
    removeClass(el, 'collapse-transition');
    el.style.height = '';
    el.style.overflow = el.dataset.oldOverflow;
    delete el.dataset.oldOverflow;
  }

  beforeLeave(el) {
    if (!el.dataset) el.dataset = {};
    if (!('oldPaddingTop' in el.dataset)) {
      el.dataset.oldPaddingTop = el.style.paddingTop;
      el.dataset.oldPaddingBottom = el.style.paddingBottom;
    }
    if (!('oldOverflow' in el.dataset)) {
      el.dataset.oldOverflow = el.style.overflow;
    }

    el.style.height = el.scrollHeight + 'px';
    el.style.overflow = 'hidden';
  }

  leave(el) {
    if (el.scrollHeight !== 0) {
      // for safari: add class after set height, or it will jump to zero height suddenly, weired
      addClass(el, 'collapse-transition');
      el.style.height = 0;
      el.style.paddingTop = 0;
      el.style.paddingBottom = 0;
    }
  }

  afterLeave(el) {
    removeClass(el, 'collapse-transition');
    el.style.height = '';
    el.style.overflow = el.dataset.oldOverflow;
    el.style.paddingTop = el.dataset.oldPaddingTop;
    el.style.paddingBottom = el.dataset.oldPaddingBottom;
    delete el.dataset.oldOverflow;
    delete el.dataset.oldPaddingTop;
    delete el.dataset.oldPaddingBottom;
  }
}

export default {
  name: 'ElCollapseTransition',
  functional: true,
  render(h, { children }) {
    const data = {
      on: new Transition()
    };

    return h('transition', data, children);
  }
};

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Is there any reason to not apply this patch ?

Was this page helpful?
0 / 5 - 0 ratings