【问题标题】:Simple Responsive page causes Chrome process to freeze简单响应页面导致 Chrome 进程冻结
【发布时间】:2014-04-09 07:18:30
【问题描述】:

Chrome 正在使用以下代码锁定。在几次调整大小事件甚至 1 次之后,Chrome 将进入无限旋转并停止登录到控制台。有时我不得不终止 Chrome 进程。我无法在 FF 或 IE 中重现它。我也无法重现 similar code 翻转 div 背景颜色而不是样式表的问题。

这三个样式表只是改变了background-color

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <link id="size-stylesheet"  rel="stylesheet" href="/Content/wide.css" />
    <script src="https://code.jquery.com/jquery-2.1.0.min.js"></script>
</head>
<body>
    <h1>This page is Responsive!</h1>
            <script type="text/javascript">
                function adjustStyle(width) {
                    console.log('adjusting style...');
                    width = parseInt(width);                                        
                    if (width < 1283) {
                        $("#size-stylesheet").attr("href", "/Content/narrow.css");
                    } else if ((width >= 1283) && (width < 1419)) {
                        $("#size-stylesheet").attr("href", "/Content/medium.css");
                    } else {
                        $("#size-stylesheet").attr("href", "/Content/wide.css");
                    }
                }

                $(function () {
                    adjustStyle($(this).width());
                    $(window).resize(function () {
                        console.log('resize fired...');
                        adjustStyle($(this).width());
                    });
                });
        </script>
</body>
</html>

注意,我需要支持非 HTML5 浏览器,例如 IE8 和 IE7。所以任何解决方案都需要考虑到这一点。

【问题讨论】:

  • 为什么不简单地使用 CSS 媒体查询而不是 JavaScript?
  • 媒体查询不支持旧版浏览器(IE8 及以下)。我必须确保这些浏览器也能正常工作。
  • 可以从响应式网站中受益的手机有多少运行 IE 8 或更早版本?
  • (换句话说,IE中的“工作”并不总是意味着与其他浏览器“工作相同”。给IE用户不同的体验通常是可以的)
  • 您也可以导入 html5 脚本并仍然使用媒体查询?

标签: javascript jquery css google-chrome


【解决方案1】:

使用媒体查询。

然后,如果您支持

<![if lte IE 8]>
<script src="IEsucks.js"></script>
<![endif]-->

这样你就不会用额外的 JS 来惩罚优秀的浏览器,而且你的网站已经是未来的证明。

(话虽如此:我会质疑您的响应式网站必须在旧版本的 IE 中运行的要求。您的网站真的有很多用户坚持在他们的手机上使用旧版本的 IE ?)

【讨论】:

  • 我使用响应作为一种技术,以一种易于支持的方式支持屏幕分辨率的变化和笨重的宽数据。此应用程序适用于 IE8 和 windows XP 相当普遍的医疗行业。但是,其他用户也运行最新的浏览器。
  • 悲伤但真实......我们的医疗行业在 IE 和 XP 上运行。 :) 也就是说,这个建议应该仍然有效。利用“适当的”媒体查询,然后根据需要返回并为 IE 应用 JS。
  • 最终这是唯一有效的方法。好答案。我发布了一个答案,以准确说明我如何使用媒体查询来解决问题。
【解决方案2】:

应用媒体查询,将您在 css 文件中的规则放入其中:

@media only screen and (max-width: 1283px) {
    /* narrow */
}

@media only screen and (max-width: 1419px) {
    /* medium */
}

@media only screen and (min-width: 1419px) {
    /* wide */
}

【讨论】:

  • 但为了获得更好的响应解决方案,请尝试使用引导程序:getbootstrap.com
  • 我有引导程序。这对于我在页面上来自他们的 UI 库的一个控件非常有用。我也需要其余的内容做出响应。另外,我需要一个适用于 IE8 和 IE7 的解决方案。
【解决方案3】:

如果使用JS,可以使用matchMedia设置媒体查询条件:

if (window.matchMedia("(min-width: 400px)").matches) {
  /* the view port is at least 400 pixels wide */
} else {
  /* the view port is less than 400 pixels wide */
}

https://developer.mozilla.org/en-US/docs/Web/API/Window.matchMedia

这里是an article on CSS media queries(在JS中也用作matchMedia的参数)。

如需更多实际示例,请查看一些 CSS 框架的代码,例如Twitter Bootstrap 或 Foundation。

在 JavaScript 中有一个用于 兼容 IE 的 polyfill:paulirish / matchMedia.js。您只需将它包含在其他脚本之前,也许在 MS 条件注释中。

或者只是编写 CSS 并为此使用 JS polyfill:scottjehl / Respond

【讨论】:

    【解决方案4】:

    以下代码根据当前浏览器宽度切换样式表。我在 IE7、IE10、Chrome v33 和 FF v28 中测试过。

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>    
        <!--[if gt IE 8]><!-->
        <script type="text/javascript" src="https://code.jquery.com/jquery-2.1.0.min.js"></script>
        <link rel="stylesheet" media="(min-width: 0px) and (max-width: 1282px)" href="Content/narrow.css" />
        <link rel="stylesheet" media="(min-width: 1293px) and (max-width: 1419px)" href="Content/medium.css" />
        <link rel="stylesheet" media="(min-width: 1420px)" href="Content/wide.css" />
        <!--<![endif]-->
        <!--[if lt IE 9]>
            <link id="size-stylesheet" rel="stylesheet" href="Content/narrow.css" />
            <script type="text/javascript" src="https://code.jquery.com/jquery-1.9.1.min.js"></script>
            <script type="text/javascript" src="//html5shim.googlecode.com/svn/trunk/html5.js"></script>
            <script type="text/javascript">
                function adjustStyle(width) {
                    width = parseInt(width);
    
                    if (width < 1283) {
                        $("#size-stylesheet").attr("href", "Content/narrow.css");
                    } else if ((width >= 1283) && (width < 1419)) {
                        $("#size-stylesheet").attr("href", "Content/medium.css");
                    } else {
                        $("#size-stylesheet").attr("href", "Content/wide.css");
                    }
                }
    
                $(function () {
                    adjustStyle($(this).width());
                    $(window).resize(function () {
                        adjustStyle($(this).width());
                    });
                });
            </script>
            <![endif]-->
    </head>
    <body>
        <h1>This page is Responsive!</h1>
    </body>
    </html>
    

    有几点值得注意:

    • 不要在 Chrome 中使用 Javascript 在窗口调整大小时切换样式表。
    • jQuery 2.X 不支持 IE7。
    • 媒体查询非常适合 HTML5 浏览器。否则,将 HTML5 支持添加为 polyfill(例如,此处显示的 html5.js)。并使用 JavaScript 切换 CSS 表单。
    • 代码利用Downlevel-revealed conditional comments 有条件地在非IE浏览器上运行代码
    • 为了测试,创建 3 个 CSS 文件并简单地更改 body {background-color: }

    【讨论】:

      【解决方案5】:

      你调用 adjustSstyle 太多了。第一次调用 init,然后它可能会更改大小并从调整大小再次调用它。也不知道为什么你的代码没有嵌入到 head 中。

      【讨论】:

      • 我认为这个问题是一个僵局。如果事件被触发太多次,我希望console.log 在进程冻结并最终抛出 stackoverflow 异常之前连续写出。只是猜测。
      • 如果您的浏览器在输出到控制台之前挂起,则不会
      【解决方案6】:

      工作示例:http://jsfiddle.net/ErURP/4/

      使用setTimeoutclearTimeouthttp://yepnopejs.com 实现回调功能:

      $(function(){
        $narrow_css = "http://f.cl.ly/items/3Y2P2q022R0B3X163c31/narrow.css";
        $medium_css = "http://f.cl.ly/items/3c2P3Z180l1s0j3S2v3k/medium.css";
        $wide_css = "http://f.cl.ly/items/2i0l3s1Z3K262z3X2X1e/wide.css";
        $resize_timer = null;
        $resize_timeout = 100;
        $css_tags = ['narrow','medium','wide'];
      
        function remove_css_tag(arr) {
          $.each(arr, function(i,v) {$('head [href*="'+v+'"]').remove();});
        }
        function resize_callback() {
          var width = $(window).width();
          remove_css_tag($css_tags);
          console.log('resize fired');
          console.log('screen width: ' + window.screen.width);
          console.log('window width: ' + width);
      
          if (width < 500) {
            yepnope.injectCss($narrow_css);
          } else if ((width >= 500) && (width <= 850)) {
            yepnope.injectCss($medium_css);
          } else {
            yepnope.injectCss($wide_css);
          } 
        } 
      
        $(window).resize(function() {
          clearTimeout($resize_timer);
          $resize_timer = setTimeout(resize_callback, $resize_timeout);
        });
      
        // init
        resize_callback();
      });
      

      【讨论】:

      • 这个也冻结了。
      • 似乎与环境或版本相关——我在生产环境中运行该代码没有任何问题,那是在 QA 在许多浏览器上运行它之后......你在哪个版本的 OS/Chrome/jQuery 上?我正在使用 OS X 10.9.2 / Chrome 版本 33.0.1750.152 / jQuery 1.9.1
      • @P.Brian.Mackey 再三考虑,我正在块内执行 css 更改,而不是为外部样式表 url 设置一个 href ......您可以为三个样式表中的每一个添加一个命名空间并加载它们都在页面加载时 - 然后更改正文类,例如:$('body').addClass('narrow') 等。
      • @P.Brian.Mackey 我更新了代码以使用远程样式表和一个 jQuery 插件:http://yepnopejs.com。我很想知道这个更新后的代码是否适合你……
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-02-26
      • 2017-09-16
      • 1970-01-01
      • 1970-01-01
      • 2015-08-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多