如果页面包含 css 转换,功能检测器(如 Modernizr)是否有可能在脚本加载时中断页面呈现?

Is it possible for a feature detector such as Modernizr to break a page rendering upon script load if the page contains css transformations?

问题

如果页面包含 css 转换,Modernizr 等特征检测器是否可以在脚本加载时中断页面呈现?

摘要

我正在尝试使用 css transform 创建动画,其中箭头沿着一条看不见的线向下移动。在我加载 modernizr 库之前,一切都很好。此时所有元素都旋转 45 度并剥离成一条细线(很可能元素被钩到动画箭头的角度),就像这样。

如果我删除对 modernizr 的脚本调用,页面将像这样正确呈现。

无论是否加载 modernizr,动画都完美无缺 - 只是页面的显示似乎中断了。顺便说一下,作为脚本的 Modernizr 加载时似乎没有错误 - 它只会混淆视觉输出。

注意: 在片段查看器中尝试以下这些代码行似乎可以按应有的方式呈现所有内容,但上面的图像证明了一些不同的东西。可见文字与图片不同,但所有代码都是相同的。

动画 css 看起来像这样(灵感来自 Joshua MacDonald - https://codepen.io/JoshMac/pen/MaYEmJ)。

$(document).ready(function() {
  var config = {
    elements: {
      navheader: "header",
      navheadstyle: "header h1"
    },
    identifiers: {},
    classes: {
      parallaxtop: ".parallax-1"
    }
  };

  $(function() {
    $(config.elements.navheader).data("size", "big");
  });

  $(window).scroll(function() {
    if ($(document).scrollTop() > 0) {
      if ($(config.elements.navheader).data("size") === "big") {
        $(config.elements.navheader).data("size", "small");
        $(config.elements.navheadstyle).stop().animate({
            "font-size": "2.0em"
          },
          200
        );
      }
    } else {
      if ($(config.elements.navheader).data("size") === "small") {
        $(config.elements.navheader).data("size", "big");
        $(config.elements.navheadstyle).stop().animate({
            "font-size": "2.5em"
          },
          200
        );
      }
    }
  });

  (function() {
    var parallax = document.querySelectorAll(".parallax"),
      speed = 0.5;

    $(window).scroll(function() {
      [].slice.call(parallax).forEach(function(el, i) {
        var windowYOffset = window.pageYOffset,
          elBackgrounPos = "0 " + windowYOffset * speed + "px";

        el.style.backgroundPosition = elBackgrounPos;
      });
    });
  })();
});
/*! HTML5 CSS3 Styles v1.0.0 */

html,
body,
ol,
ul,
li,
p {
  font: normal normal normal 15px/normal 'Titillium Web', 'Montserrat', 'Raleway', 'Gudea', 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  text-align: left;
  text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.05), 0px 2px 8px rgba(0, 0, 0, 0.05), 0px 2px 4px rgba(0, 0, 0, 0.15);
}

body {
  background: #fff;
  color: #606060;
}

nav {
  background: rgb( 255, 255, 255);
  /* Fall-back for browsers that don't
                                    support rgba */
  background: rgba(255, 255, 255, 0.9);
}


/* Desktop styles */

@media (min-width: 300px) {
  header nav li:first-child {
    display: none;
  }
  header.wrapper {
    display: block;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
  }
  header nav ul {
    margin: 10px auto;
    width: 100%;
    text-align: center;
  }
  header nav li {
    display: inline-block;
    list-style-type: none;
    font-weight: bold;
    padding: 0 10px;
  }
  header .container h1 {
    font: normal normal normal 2.5em/normal 'Gudea', Helvetica, Arial, sans-serif;
  }
  header .container>div {
    padding: 10px;
    text-align: center;
    text-transform: uppercase;
  }
  nav .floatright {
    /* This should be replaced with something more convenient. Mobiles don't use this - better remove it from the code stack. */
    float: right;
  }
}

header:after,
nav:after,
.floatright:after,
.arrowcontainer>div:after {
  content: '';
  display: block;
  clear: both;
}


/* ============================================================
  SECTIONS
============================================================ */

section.module:last-child {
  margin-bottom: 0;
}

section.module h2 {
  font-family: 'Playfair Display', serif;
  width: 25%;
  margin: 0 auto 40px auto;
  font-size: 2.8em;
  text-align: center;
}

section.module p {
  font-family: 'Open Sans Condensed', sans-serif;
  margin-bottom: 40px;
  font-weight: 300;
}

section.module p:last-child {
  margin-bottom: 0;
}

section.module.content {
  padding: 40px 0;
}

section.module.parallax {
  padding: 0;
  background-position: 0 0;
}

section.module.parallax h1 {
  font-family: 'Playfair Display', serif;
  width: 50%;
  margin: 0 auto;
  font-size: 4em;
  text-align: center;
}

section.module.parallax-1 {
  background: #c0c0c0;
}

footer.module.parallax-2 {
  background: #555;
}

section.module.parallax-3 {
  background: #0000ff;
}

@media all and (min-width: 600px) {
  section.module h2 {}
  section.module p {}
  section.module.parallax {
    padding: 350px 0;
  }
  section.module.parallax h1 {}
}

@media all and (min-width: 960px) {
  section.module.parallax h1 {}
}

.arrowcontainer {
  position: relative;
  width: 100%;
  bottom: -5em;
  text-align: center;
}

.arrowtext {
  font-weight: bold;
}

.arrow,
.arrow:before {
  position: absolute;
  left: 0;
  bottom: 0;
  text-align: center;
}

.arrow {
  fill: none;
  width: 20px;
  height: 20px;
  top: 20%;
  left: 50%;
  -webkit-transform: rotate(45deg);
  -ms-transform: rotate(45deg);
  transform: rotate(45deg);
  border-left: none;
  border-top: none;
  border-right: 1px transparent solid;
  border-bottom: 1px transparent solid;
}

.arrow:before {
  content: '';
  width: 20px;
  height: 20px;
  top: 50%;
  border-left: none;
  border-top: none;
  border-right: 1px #000 solid;
  border-bottom: 1px #000 solid;
  /*-webkit-animation-delay: 2s;
  -ms-animation-delay: 2s;
  animation-delay: 2s;*/
  -webkit-animation-duration: 2s;
  -ms-animation-duration: 2s;
  animation-duration: 2s;
  -webkit-animation-iteration-count: infinite;
  -ms-animation-iteration-count: infinite;
  animation-iteration-count: infinite;
  -webkit-animation-fill-mode: none;
  -ms-animation-fill-mode: none;
  animation-fill-mode: none;
  -webkit-animation-timing-function: ease-in-out;
  -ms-animation-timing-function: ease-in-out;
  animation-timing-function: ease-in-out;
  -webkit-animation-name: arrow;
  -ms-animation-name: arrow;
  animation-name: arrow;
}

@keyframes arrow {
  0% {
    opacity: 0;
  }
  50% {
    opacity: 1;
  }
  100% {
    opacity: 0;
    -webkit-transform: translate(40px, 40px);
    -ms-transform: translate(40px, 40px);
    transform: translate(40px, 40px);
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://www.gisslen.net/framework/core/client/modernizr-3.5.0-custom.min.js"></script>
<header class="wrapper">
  <nav>
    <div class="container">
      <!-- Start: Navigation -->
      <div>
        <h1>Main title</h1>
        <ul>
          <li>Link 1</li>
          <li>Link 2</li>
          <li>Link 3</li>
          <li>Link 4</li>
          <li>Link 5</li>
        </ul>
      </div>
      <!-- End: Navigation -->
    </div>
  </nav>
</header>
<!-- Start: Page content -->
<main>
  <section class="module parallax parallax-1">
    <div class="container">
      <h1>Block title</h1>
      <div class="arrowcontainer">
        <div class="arrowtext">Supportive text</div>
        <div class="arrow"></div>
      </div>
    </div>
  </section>
  <section class="module content">
    <a name="concept"></a>
    <div class="container">
      <h2>Block subtitle</h2>
    </div>
  </section>
  <section class="module content">
    <a name="news"></a>
    <div class="container">
      <h2>Block subtitle</h2>
    </div>
  </section>
</main>
<!-- End: Page content -->
<!-- Start: Footer -->
<footer class="module parallax parallax-2">
  <div class="container">
    <div class="footer-bottom">
      <ul>
        <li>Link 1</li>
        <li>Link 2</li>
        <li>Link 3</li>
      </ul>
    </div>
  </div>
</footer>
<footer class="wrapper">
  Last updated span
</footer>
<!-- End: Footer -->

上面的 HTML-snippet 被这些代码行包​​围(因为它们不应添加到 snippets texteditor 中)。

<!DOCTYPE html>
<html class="no-js">
<head id="Head1">
  <meta charset="utf-8" />
  <title>Testing</title>
  <meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>
  <form name="form1" method="post" action="./" id="form1">
    <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMjEwNDQyMTMxMw9kFgJmD2QWAgIDD2QWAgIDDw8WAh4EVGV4dAUVcmV2aXNlZCAxNjAxLjEuMS4wMTAwZGRkfaEsWaMfAzoF2J+iiXEZuLql9BHgAUKPamIAH6P8sG0=" />
    <div>
    </div>

    The snippet above...

    <div>
      <input type="hidden" name="__VIEWSTATEGENERATOR" id="__VIEWSTATEGENERATOR" value="CA0B0334" />
    </div>
  </form>
</body>
</html>

我正在使用 modernizr-3.5.0-custom.min.js 并选中所有功能和选项,并且 jquery-3.2.1.min.js(片段查看器中可用的最新 jQuery 版本是 2.1.1,但它们的工作原理完全相同在这件事上)。

您遇到的问题是由于 .arrow class。 modernizr 所做的是将 classes 添加到您的 html 标签中。这些 class 旨在供您在 CSS 代码中使用,因此您可以添加后备样式以防浏览器不支持某个功能。

运行 页面然后请检查 modernizr 在 google 开发工具中添加的 html classes,如果您找到关键字箭头,那么您会发现在 html 标签中添加了一个 class 同名箭头,因为您正在为箭头使用相同的 class 名称。这也将所有动画 classes 应用到 html 标签,因此它呈现箭头动画的效果。

为了解决这个问题,请将您的 .arrow class 名称更改为其他名称,例如 .arrow-animation 或尝试在 .arrowcontainer 声明为嵌套在父 class 下,如下所示:

.arrowcontainer .arrowtext {...}

.arrowcontainer .arrow,
.arrowcontainer .arrow:before {...}

.arrowcontainer .arrow {...}

.arrowcontainer .arrow:before {...}

这将解决您遇到的渲染问题。

希望这能解释问题并帮助您继续。

编码愉快:)