【问题标题】:JS launches before CSSJS 在 CSS 之前启动
【发布时间】:2014-08-02 12:56:33
【问题描述】:

这目前在 chrome 中发生,在 Firefox 中我还没有遇到这个问题(还)。

这是我的问题的一个非常简化的版本。

HTML:

<div class="thumbnail">
  <a href='#' id="clickMe">Click me!</a>
</div>

CSS:

div {
    width: 200px;
    height: 300px;
    background-color: purple;
}
a {
    position: absolute;
}
@media (max-width: 991px) {
    div {
        height: 200px;
    }
}

Javascript:

$(document).ready(function () {
    var $parent = $('#clickMe').parent();
    function resize() {
        $('#clickMe').offset({
            top: $parent.offset().top + $parent.height()-$('#clickMe').height()
        });
    }
    $(window).on('resize', resize);
    resize();
});

问题:

那么当我调整大小(不拖动)时,这会带来什么? javascript 首先启动并设置 &lt;a&gt;&lt;/a&gt; 的位置,然后 CSS 如果我们

从逻辑上讲,按钮现在在视觉上位于 div 的外部,而不是像我最初定义的那样位于边框上。

本文提出的临时解决方案。

jQuery - how to wait for the 'end' of 'resize' event and only then perform an action?

var doit;
    $(window).on('resize', function(){ clearTimeout(doit); doit = setTimeout(resize, 500); });

临时解决方案不是我想要的:

但是,在我的情况下,我真的不需要在调整大小事件实际完成时才调用“调整大小”。我只是希望我的 javascript 在 css 完成加载/或完成它的更改后运行。而且当 css 可能已经完成了。

问题:

有解决办法吗?任何人都知道 js 中的一种技术,可以等到 css 完全完成在调整大小期间应用修改?

其他信息:

在 jsfiddle 中测试这个很可能不会给你和我一样的结果。我的 css 文件有很多行,我正在使用 Twitter Bootstrap。这两个占用了大量资源,减慢了 css 应用程序的速度(我想,如果我错了,请告诉我)。

Miljan Puzović - 提出了一个解决方案,通过 js 加载 css 文件,然后在 css 上的 js 事件结束时应用 js 更改。

【问题讨论】:

  • CSS/JS 是内联添加的还是作为外部资源添加的?您是在head 中添加它还是在关闭body 之前添加它?
  • 这个怎么样:用 js 插入 css,当该事件完成时插入/应用其余的 js?
  • 我不太明白这个问题。有人可以帮我澄清一下吗?
  • 编辑(a)在实际问题陈述之前的顶部和(b)显式添加而不是文本的一部分对于新读者来说非常混乱(让我失望,确实如此)。也许最好将它们编辑到问题中?

标签: javascript jquery css twitter-bootstrap responsive-design


【解决方案1】:

我认为这简单的三个步骤将实现预期的行为(请仔细阅读:我还建议阅读更多有关上述属性的内容以深入了解其工作原理):

  1. Responsivefluid 布局问题应始终通过 CSS 主要(如果不是严格)解决。

    所以,删除你所有的JavaScript 代码。

  2. 您已经绝对定位了内部a#clickMe 元素。

    这意味着它将定位在其最近的相对定位元素中。根据提供的样式,它将定位在 body 元素内,因为在任何其他元素中都没有 position: relative;(默认 position 值为 static。根据提供的脚本,它似乎应该位于其直接 parent 容器中。为此,请将position: relative; 添加到div.thumbnail 元素。

  3. 根据您提供的脚本,您似乎需要将a#clickMe 放在div.thumbnail 的底部。

    现在我们确定添加到a#clickMe 的样式是相对于div.thumbnail 的,只需将bottom: 0px; 添加到a#clickMe 元素,它将相应地定位,而与其父元素的高度无关。请注意,这将在调整窗口大小时自动重新排列(无需脚本)。

最终的代码会是这样的(see fiddle here):

JS:

 /* No script needed. */

CSS:

div {
    width: 200px;
    height: 300px;
    background-color: purple;
    position: relative; //added
}
a {
    position: absolute;
    bottom: 0px; //added
}
@media (max-width: 991px) {
    div {
        height: 200px;
    }
}

如果您仍然坚持媒体查询更改检测,请参阅以下链接:

http://css-tricks.com/media-query-change-detection-in-javascript-through-css-animations/

http://css-tricks.com/enquire-js-media-query-callbacks-in-javascript/

http://tylergaw.com/articles/reacting-to-media-queries-in-javascript

http://davidwalsh.name/device-state-detection-css-media-queries-javascript

Twitter Bootstrap - how to detect when media queries starts

Bootstrap: Responsitive design - execute JS when window is resized from 980px to 979px

【讨论】:

  • 我同意在 javascript 或 css 中做所有事情可能更简单,我仍然想知道如何在应用 JS 之前等待 css 完成。
【解决方案2】:

我喜欢你的临时解决方案(我之前曾为类似的问题做过,我认为半秒对于用户来说等待时间不会太长,但也许它是为了你的需要......)。

这是您最有可能想到的替代方案,但我没有看到它被提及,所以在这里。为什么不全部通过 javascript 来完成,然后从你的 CSS 中删除你的 @media (max-width....

function resize() {
    var width = (window.innerWidth > 0) ? window.innerWidth : screen.width;
    if(width<992){
        $("div").each(function(e,obj){$(obj).height(200);});
    }
    $('#clickMe').offset({
        top: $parent.offset().top + $parent.height()-$('#clickMe').height()
    });

}

【讨论】:

  • 我喜欢尝试在 css 中做某些事情,如果我不能在 css 中完成,我会在 JS 中完成。我认为最好的解决方案是在 css 或 js 中完成所有这些。但我觉得有一天我会再次遇到这个问题,所以我真的很想知道如何等到 css 完成应用更改的确切时刻。
【解决方案3】:

在html页面中,将css文件的链接放在head部分;接下来,将 js 文件的链接放在 /body 标记之前,看看会发生什么。这样css会在js之前加载always。 希望对您有所帮助。

【讨论】:

  • 这将用于初始加载。我说的是什么时候已经加载了所有内容以及发生了调整大小事件。
【解决方案4】:

您是否尝试将调整大小处理程序不是绑定到窗口,而是绑定到您要收听调整大小的对象?

代替

$(window).on('resize', resize);

你可以试试

$("#clickMe").on('resize', resize);

或许

$("#clickMe").parent().on('resize', resize);

【讨论】:

    【解决方案5】:
    var didResize = false;
    $(window).resize(function() {
        didResize = true;
    });
    setInterval(function() {
        if (didResize) {
            didResize = false;
            console.log('resize');
        }
    }, 250);
    

    【讨论】:

    • 这仅检查javascript事件调整大小是否被调用并完成。我想看看调整大小的 css 修改何时完成。
    【解决方案6】:

    我同意 falsarella 的观点,即您应该尝试仅使用 CSS 来做您想做的事情。

    无论如何,如果你想在应用CSS之后对JS做一些事情,我认为你可以使用requestAnimationFrame,但我无法自己测试它,因为我无法重现你解释的行为。

    来自 MDN 文档:

    window.requestAnimationFrame() 方法告诉浏览器你 希望执行动画并请求浏览器调用 在下一次重绘之前更新动画的指定函数。这 方法将要在调用之前调用的回调作为参数 重绘。

    我会尝试这样的事情:

    var $parent = $('#clickMe').parent();
    
    function resize(){
    
        $('#clickMe').offset({
            top: $parent.offset().top + $parent.height()-$('#clickMe').height()
        });
    }
    
    
    window.onresize = function(e){
        window.requestAnimationFrame(resize);
    }
    
    window.requestAnimationFrame(resize);
    

    【讨论】:

      【解决方案7】:

      有人知道等到 css 完全加载完成的技术吗?

      $(window).load(function() { /* ... */ } 呢? (它只有在页面完全加载时才执行该功能,所以在css加载之后)

      【讨论】:

      • 我应该让自己更清楚一点。我还想等待调整大小结束时的 css 修改才能真正完成。我确实尝试加载,它只解决了部分问题。调整大小真的是令人沮丧的部分。
      猜你喜欢
      • 2022-01-18
      • 1970-01-01
      • 2017-04-12
      • 1970-01-01
      • 2020-05-23
      • 2014-10-13
      • 1970-01-01
      • 2014-04-18
      • 2018-09-18
      相关资源
      最近更新 更多