【问题标题】:Spin icon freezes while loading records加载记录时旋转图标冻结
【发布时间】:2014-08-30 15:55:13
【问题描述】:

我正在尝试使用微风加载记录。加载记录时,我显示旋转图标。但不知何故,在网格中加载记录时,旋转图标似乎停止了。 这是我的 html

<div id="showSpin" data-bind="visible: isSpinning" style="padding: 10px; position: absolute; top:248px;left: 320px;  background-color: #FFF; opacity: 0.9; filter: alpha(opacity=90);">
    <img src="/images/spin.gif" />
</div>

这是我加载图片的代码

isSpinning(true)
context.getData(name, records).then(function (data) {
     isSpinning(false);

    setTimeout(function () {
        isSpinning(false);
    }, 300);

})
.fail("Record not found");

更新1 我根据答案尝试了下面的代码,但没有任何反应。我还包括CSS。但是什么都看不到。

<div id="loading" data-bind="visible: isSpinning" style="padding: 10px; position: absolute; top:240px;left: 280px;  background-color: #FFF; opacity: 0.9; filter: alpha(opacity=90);">
    <i class="icon-spin " style="width: 40px"></i>
    <!--<img src="../../../../../Content/images/download.jpg" style="width: 40px" />-->
</div> 

【问题讨论】:

  • 我相信这是因为浏览器正在加载大量记录,并且在显示记录之前基本上会冻结一段时间。此效果可能因浏览器而异。我不确定它周围是否有任何东西
  • 我在 IE 10 上测试过,chrome 和结果是一样的。所以你的意思是没有解决方案?
  • 可能是您的计算机速度较慢,或者您只是一次加载太多。不知道你用的是什么功能,你可以试试jquery ajax,看看效果好不好
  • 不确定谁投反对票,为什么?我的问题有什么问题?我也付出了一些努力
  • 您可能需要在工作线程中进行加载,它可能会阻塞为图标设置动画的线程。

标签: javascript html breeze gif


【解决方案1】:

这是因为 Gif 需要打开线程才能显示下一张图像。如果您使用的是纯 css 方法,您将不会看到此问题。以 font-awesome 为例 -

<i class="icon-spin icon-spinner"></i>

因为这是一种纯 CSS 方法,所以即使线程在加载所有新记录并关联它们的相关实体时陷入困境,微调器也会继续旋转。

如果您需要继续旋转,我会高度包含来自 Font-Awesome 来源的这一点 CSS -

@-moz-keyframes spin {
  0% {
    -moz-transform: rotate(0deg); }

  100% {
    -moz-transform: rotate(359deg); } }

@-webkit-keyframes spin {
  0% {
    -webkit-transform: rotate(0deg); }

  100% {
    -webkit-transform: rotate(359deg); } }

@-o-keyframes spin {
  0% {
    -o-transform: rotate(0deg); }

  100% {
    -o-transform: rotate(359deg); } }

@-ms-keyframes spin {
  0% {
    -ms-transform: rotate(0deg); }

  100% {
    -ms-transform: rotate(359deg); } }

@keyframes spin {
  0% {
    transform: rotate(0deg); }

  100% {
    transform: rotate(359deg); } }

.icon-spin {
  display: inline-block;
  -moz-animation: spin 2s infinite linear;
  -o-animation: spin 2s infinite linear;
  -webkit-animation: spin 2s infinite linear;
  animation: spin 2s infinite linear; }

并且使用静态图标、图像或精灵,并对其应用“icon-spin”类,无论它是否是图标。

编辑

在声明 CSS 的任何地方添加 -

<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css" rel="stylesheet">

改变这个 -

<div id="showSpin" data-bind="visible: isSpinning" style="padding: 10px; position: absolute; top:248px;left: 320px;  background-color: #FFF; opacity: 0.9; filter: alpha(opacity=90);">
    <img src="/images/spin.gif" />
</div>

到这里-

<div id="showSpin" data-bind="visible: isSpinning" style="padding: 10px; position: absolute; top:248px;left: 320px;  background-color: #FFF; opacity: 0.9; filter: alpha(opacity=90);">
    <i class="fa fa-spinner fa-spin"></i>
</div>

之所以是fa而不是icon是因为当前版本的FontAwesome由于碰撞而改为使用fa而不是icon

上次编辑

你现在的问题是你的逻辑有问题。我试图在 cmets 中解释这一点,但我会给出最后一次更新,如果你想展示你的微调器并让它旋转,你的逻辑应该是什么样子。

isSpinning(true)
context.getData(name, records).then(function (data) {
    isLoading(false);

    setTimeout(function () {
        isSpinning(false);
    }, 1000);

})
.fail("Record not found");


<div id="showSpin" data-bind="visible: isSpinning" style="padding: 10px; position: absolute; top:248px;left: 320px;  background-color: #FFF; opacity: 0.9; filter: alpha(opacity=90);">
    <!-- THERE IS NO REASON TO USE A VISIBLE BINDING HERE AND ON THE PARENT -->
    <i class="fa fa-2x fa-spinner fa-spin"></i>
</div>

这不起作用的原因在于您的逻辑。将其完全复制到您的解决方案中,它将起作用。

【讨论】:

  • 因此,如果解决方案对您有用,但您需要进行调整,我建议您阅读字体真棒文档。就目前而言,这应该可以解决您遇到的问题,但您只需要进行一些调整以适应您的喜好。特别是使用 fa-2x 或 fa-3x 使其更大,但他们的文档非常宝贵
  • 它在旋转,但如果我在按钮上使用它而不是在 div 内.. 为什么??
  • 对不起,按钮也没有工作。我的意思是,如果我只在按钮上使用图标而不隐藏和取消隐藏,它就可以工作
  • 如果我删除图标上的可见绑定,那么它可以工作 icon
【解决方案2】:

这只是猜测,但我认为您的记录加载脚本通过在主线程中运行而阻塞了 Web 浏览器。这不是一个可取的行为,但幸运的是,这正是 webworkers 的目的。首先,我建议您阅读this page 了解一些背景知识,然后继续阅读。

基本上,您需要先将加载代码移动到单独的 javascript 文件中。这个单独的文件应该包含加载记录的所有代码,然后将它放在一个对象中并将对象发送回主线程,如下所示。 然后,您可以使用以下方法从主线程调用此代码:

var myWorker = new Worker("my_loading_code.js");

现在,由于线程安全问题,webworker 可以直接访问的内容受到限制,因此您可能需要检索记录,然后使用 postMessage(x); 调用将它们发送到主线程,这允许您将任何对象发回到主页。然后,主页可以通过安装消息处理程序来对此消息做出反应:

myWorker.onmessage = function(record){
    // This is only pseudo code, use your actual code here
    reactToRecievingRecord(record);
}; 

这意味着主线程在所有记录加载时不会被阻塞,并且可以为您的图标设置动画,只有在收到记录时才会短暂阻塞。

如果这还不够清楚,或者您需要更多帮助,请询问:)

编辑:

详细来说,在您的情况下,在单独的文件中,您需要一些代码来执行以下操作:

context.getData(name, records).then(function (data) {
    postMessage(data);
})

然后在你想要的主文件中:

isSpinning(true);
var myWorker = new Worker("my_loading_code.js");
myWorker.onmessage = function(record){
    // This is only pseudo code, use your actual code here
    isLoading(false);
    isSpinning(false);
}; 

请注意,此代码在收到数据后实际上并没有对数据做任何事情,您会想要处理它,但我相信您已经大致了解了。请注意,这些也只是 sn-ps,您需要将它们变成完整的功能等

【讨论】:

  • 根据您的示例,我需要将此代码 context.getData(name, records).then(function (data) { 移动到其他文件??
  • @Happy 我将编辑答案,因为此评论框太小,无法正确回复。
  • @Happy 有帮助吗?您将第一个位放入一个名为 my_loading_code.js 的文件中(一旦您玩过它并执行您想要的操作),第二个位替换您最初在主文件中的内容。
  • 我还没有尝试过,但是我不能使用这种方法,因为我必须创建新的 js 文件才能加载 ajax 请求。我的应用程序中有很多 ajax 请求,然后它只会为这些请求提供太多的 js 文件。还有其他想法吗?
  • @Happy 别担心,您不必为每个不同的 ajax 请求创建一个新的 js 文件。只创建一个额外的 js 文件,创建后将由主线程发送一条消息,告诉它要处理什么样的请求,然后工作人员可以运行适当的函数/代码路径。这意味着您只需要一个用于工作线程的脚本,该脚本可用于每种类型的请求。
【解决方案3】:

您还可以对图形进行 Base64 编码并通过 CSS 应用此加载图形,从而使后续使用更快并节省 HTTP 请求。执行 Base64 编码动画加载器的结果是,对于小型常见可重用资产,如加载或处理资产,它已经可用并将在执行大量 AJAX / HTTP 请求时继续动画,这就是您要在此处解决的问题.

另请参阅:

通过这种方式,您可以在加载 CSS 时加载图形。因为在最可维护的解决方案中使用 Base64 编码的图像,您可以使用诸如 SASS / Compass 之类的技术并使用资产的路径,然后当您预处理或编译为 css 时,它使用资产或资源的路径并进行编码它为您提供 Base64 编码版本。这种技术适用于各种图像格式等。

Sass / Compass Base64 参考:

“将图像的内容直接嵌入到您的样式表中, 消除对另一个 HTTP 请求的需要。对于小图像,这 可以以生成更大的 CSS 为代价获得性能优势 文件”

但要小心! Base64 编码并非没有一些注意事项

  • 难以维护和更新:没有一些工具来帮助,手动 编辑和组合图像精灵是一件很麻烦的事

  • 内存消耗增加(可能非常显着):这通常是 被忽视了。交付图像的时间在 以更大的内存和 CPU 占用为代价,特别是对于大型 具有大量空白的精灵和精灵。

  • bleedthrough:用于没有太多空格可分隔的精灵 图像,附近图像明显流血的可能性增加 通过其他元素,例如在这种情况下,只有渗出 在 iOS 上看到(但在桌面上的 Chrome 和 Safari 上看起来不错)。 注意

Base64 加载微调器示例:

.genericLoader { background-image: url('data:image/gif;base64,R0lGODlhEAAQAPIAAP///wAAAMLCwkJCQgAAAGJiYoKCgpKSkiH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAADMwi63P4wyklrE2MIOggZnAdOmGYJRbExwroUmcG2LmDEwnHQLVsYOd2mBzkYDAdKa+dIAAAh+QQJCgAAACwAAAAAEAAQAAADNAi63P5OjCEgG4QMu7DmikRxQlFUYDEZIGBMRVsaqHwctXXf7WEYB4Ag1xjihkMZsiUkKhIAIfkECQoAAAAsAAAAABAAEAAAAzYIujIjK8pByJDMlFYvBoVjHA70GU7xSUJhmKtwHPAKzLO9HMaoKwJZ7Rf8AYPDDzKpZBqfvwQAIfkECQoAAAAsAAAAABAAEAAAAzMIumIlK8oyhpHsnFZfhYumCYUhDAQxRIdhHBGqRoKw0R8DYlJd8z0fMDgsGo/IpHI5TAAAIfkECQoAAAAsAAAAABAAEAAAAzIIunInK0rnZBTwGPNMgQwmdsNgXGJUlIWEuR5oWUIpz8pAEAMe6TwfwyYsGo/IpFKSAAAh+QQJCgAAACwAAAAAEAAQAAADMwi6IMKQORfjdOe82p4wGccc4CEuQradylesojEMBgsUc2G7sDX3lQGBMLAJibufbSlKAAAh+QQJCgAAACwAAAAAEAAQAAADMgi63P7wCRHZnFVdmgHu2nFwlWCI3WGc3TSWhUFGxTAUkGCbtgENBMJAEJsxgMLWzpEAACH5BAkKAAAALAAAAAAQABAAAAMyCLrc/jDKSatlQtScKdceCAjDII7HcQ4EMTCpyrCuUBjCYRgHVtqlAiB1YhiCnlsRkAAAOwAAAAAAAAAAAA==');   
}

工作示例:

何时对图像进行 Base64 编码(以及何时不) - http://davidbcalhoun.com/2011/when-to-base64-encode-images-and-when-not-to/

编码工具

其他 StackOverflow 参考资料:

【讨论】:

  • 我试过了,但还是同样的问题。它只是在 ajax 请求期间冻结
  • 你了解微风框架吗?我认为这与此有关。我正在使用微风框架来获取内部使用 oData 和 Ajax 的数据。如果我使用普通的 ajax 请求使用这个 spin.js,那么我可以看到它在旋转,但是当我通过微风发出请求时,它会冻结
  • 有什么可以指点我groups.google.com/forum/#!topic/durandaljs/VnSX-uV-fA8
猜你喜欢
  • 1970-01-01
  • 2014-10-18
  • 1970-01-01
  • 2018-08-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-20
  • 2014-08-17
  • 2014-08-25
相关资源
最近更新 更多