samentic 在IE9 不支持 transition 的解决方案

本文原文链接为:http://www.cnblogs.com/jying/p/6377696.html  ,转载请注明出处。

在使用samentic过程中遇到 IE9 下报如下错误:

查阅了好多资料终于功夫不负有心人,找到一篇对于 IE9 下bug 的解释:https://github.com/Semantic-Org/Semantic-UI/pull/1781 

由此可知 samentic 中的动画效果使用 CSS3 transition 进行过渡,而通过 http://www.w3school.com.cn/cssref/pr_transition.asp 可确认 IE9 并不支持 transition ,导致在 IE9 中samentic 的许多控件都无法使用。

走投无路时去看看源文件吧,查看 components/dropdown.js 文件得知 samentic 通过 

if ($.fn.transition !== undefined && $module.transition('is supported'))

判断浏览器是否支持 transition ,原代码(绿色注释是我自己加的)如下:

show: function(callback, $subMenu) {
            var
              $currentMenu = $subMenu || $menu,
              start = ($subMenu)
                ? function() {}
                : function() {
                  module.hideSubMenus();
                  module.hideOthers();
                  module.set.active();
                },
              transition
            ;
            callback = $.isFunction(callback)
              ? callback
              : function(){}
            ;
            module.verbose('Doing menu show animation', $currentMenu);
            module.set.direction($subMenu);
            transition = module.get.transition($subMenu);
            if( module.is.selection() ) {
              module.set.scrollPosition(module.get.selectedItem(), true);
            }
            if (module.is.hidden($currentMenu) || module.is.animating($currentMenu)) {
                //以下是重点判断 --------
                if (transition == 'none') {
                    // transition 为 none
                    start();
                    $currentMenu.transition('show');
                    callback.call(element);
                }
                else if ($.fn.transition !== undefined && $module.transition('is supported')) {
                    // 浏览器支持 transition
                    $currentMenu.transition({
                        animation: transition + ' in',
                        debug: settings.debug,
                        verbose: settings.verbose,
                        duration: settings.duration,
                        queue: true,
                        onStart: start,
                        onComplete: function () {
                            callback.call(element);
                        }
                    });
                }
                else {
                    // 否则报错
                    module.error(error.noTransition, transition);
                }
            }
          },
dropdown显示的源代码

通过加断点追踪发现,在 IE9 下 $module.transition('is supported') 为 false,即不支持 transition。

注意到

if (transition == 'none') {
    //transition 为 none
    start();
    $currentMenu.transition('show');
    callback.call(element);
}

心想这是否是在无 transition 情况下的运行呢?死马当活马医试试吧,给以上代码加上 !$module.transition('is supported') 判断如下:

if (transition == 'none' || !$module.transition('is supported')) {
    start();
    $currentMenu.transition('show');
    callback.call(element);
}

运行!哇塞,神奇的事情发生了!不报错而且dropdown效果出现啦!!!仅仅是加了一个 !$module.transition('is supported') 判断就解决了!!!以上为show方法,然后为hide方法也加上该判断,一切正常!

举一反三,马上看看其它控件,拿popup验证下,其源代码如下:

show: function(callback) {
            callback = $.isFunction(callback) ? callback : function(){};
            if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
              module.set.visible();
              $popup
                .transition({
                  animation  : settings.transition + ' in',
                  queue      : false,
                  debug      : settings.debug,
                  verbose    : settings.verbose,
                  duration   : settings.duration,
                  onComplete : function() {
                    module.bind.close();
                    callback.call($popup, element);
                    settings.onVisible.call($popup, element);
                  }
                });
            }
            else {
              module.error(error.noTransition);
            }
          },
显示popup 的源代码

发现popup 的show方法中无 transition == "none" 的判断,所以直接为其添加 !$module.transition('is supported') 判断,并对内部实现进行稍加改进,顺利运行,修改后的代码如下:

        animate: {
          show: function(callback) {
            callback = $.isFunction(callback) ? callback : function(){};
            if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
              module.set.visible();
              $popup
                .transition({
                  animation  : settings.transition + ' in',
                  queue      : false,
                  debug      : settings.debug,
                  verbose    : settings.verbose,
                  duration   : settings.duration,
                  onComplete : function() {
                    module.bind.close();
                    callback.call($popup, element);
                    settings.onVisible.call($popup, element);
                  }
                });
            }
            //此处为新加
            else if (!$module.transition('is supported')) {
                module.set.visible();
                module.bind.close();
                $popup.transition('show');
                callback.call(element);
            }
            //以上为新加
            else {
              module.error(error.noTransition);
            }
          },
          hide: function(callback) {
            callback = $.isFunction(callback) ? callback : function(){};
            module.debug('Hiding pop-up');
            if(settings.onShow.call($popup, element) === false) {
              module.debug('onShow callback returned false, cancelling popup animation');
              return;
            }
            if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
                $popup.transition({
                    animation: settings.transition + ' out',
                    queue: false,
                    duration: settings.duration,
                    debug: settings.debug,
                    verbose: settings.verbose,
                    onComplete: function () {
                        module.reset();
                        callback.call($popup, element);
                        settings.onHidden.call($popup, element);
                    }
                });
            }
            //此处为新加
            else if (!$module.transition('is supported')) {
                module.reset();
                $popup.transition('hide');
                callback.call(element);
            }
            //以上为新加
            else {
              module.error(error.noTransition);
            }
          }
        },
popup修改后的代码

  

目前验证dropdown和popup 控件一切正常,其它控件有用到的同学请自行验证。

其实问题的解决过程并非像上面描述的这么简单,走了不少弯路,假如先看的是popup.js 可能就不会有这个问题的解决了,所以有时候人真的也得靠一点点运气活着O(∩_∩)O,也希望大家转发时标明出处,谢谢阅读~~

原文地址:https://www.cnblogs.com/jying/p/6377696.html