javascript 加载记录时旋转图标冻结

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24656805/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 03:10:56  来源:igfitidea点击:

Spin icon freezes while loading records

javascripthtmlbreezegif

提问by James

I am trying to load records using breeze. While loading record i am showing spin icon. But somehow spin icon seems to stop while records are being loaded in grid. Here is my html

我正在尝试使用微风加载记录。在加载记录时,我正在显示旋转图标。但不知何故,当记录被加载到网格中时,旋转图标似乎停止了。这是我的 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>

here is my code to load image

这是我加载图像的代码

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

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

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

Update1I tried below code as per answer but nothing happens. I also included css. But cant see anything.

Update1我按照答案尝试了下面的代码,但没有任何反应。我还包括了 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> 

回答by PW Kad

This is happening because a Gif requires the thread to be open to display the next image. If you were using a pure css approach you would not see this issue. Take font-awesome for example -

发生这种情况是因为 Gif 需要打开线程以显示下一个图像。如果您使用纯 css 方法,则不会看到此问题。以 font-awesome 为例 -

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

Because this is a pure CSS approach the spinner will continue to spin even when the thread bogs down loading all of of your new records and associating their related entities.

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

If you need to continue spinning I would highly including this bit of CSS from the Font-Awesome source -

如果您需要继续旋转,我会高度包括来自 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; }

And using either a static icon, image or sprite and just applying class of 'icon-spin' to it, regardless of whether it is an icon or not.

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

Edit

编辑

Add this wherever you are declaring your CSS -

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

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

Change this -

改变这个——

<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>

to this -

对此——

<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>

The reason it is fainstead of iconis the current version of FontAwesome changed to use fa instead of icon due to collisions

它是fa而不是的原因是icon当前版本的 FontAwesome 由于冲突而改为使用 fa 而不是图标

Last Edit

上次编辑

Your problem now is that your logic is faulty. I have tried to explain this in comments but I will give one last update with EXACTLY how your logic should look if you want to show your spinner and have it spinning.

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

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>

The reason this wasn't working is in your logic. Copy this EXACTLY to your solution and it will work.

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

回答by Frankie Loscavio

You could also Base64 encode the graphic and apply this loading graphic via CSS thus making subsequent usage faster and saving HTTP requests. The result of doing the Base64 encoded animated loader, is that for small common reusable assets like a loading or processing assets, it is already available and will continue to animate while performing numerous AJAX / HTTP requests, which is what you are trying to solve here.

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

See Also:

也可以看看:

In this way, you can have the graphic loaded when the CSS is loaded. Because having Base64 encoded images in not exactly the most maintainable solution you could use a technology like SASS / Compass and use the path to an asset and then when you pre-process or compile to css it uses the path to the asset or resource and encodes it to a Base64 encoded version for you. This technique will work with all kinds of image formats etc..

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

Sass / Compass Base64 References:

Sass / Compass Base64 参考资料:

"Embeds the contents of an image directly inside your stylesheet, eliminating the need for another HTTP request. For small images, this can be a performance benefit at the cost of a larger generated CSS file"

“将图像的内容直接嵌入到样式表中,无需另一个 HTTP 请求。对于小图像,这可能以生成更大的 CSS 文件为代价来提高性能”

But beware! Base64 encoding it isn't without some caveats

但要小心!Base64 编码并非没有一些警告

  • hard to maintain and update: without some tool to help, manually editing and putting together image sprites is quite a chore

  • increased memory consumption (possibly very dramatic): this is often overlooked. The time to deliver the images is decreased at the expense of a bigger memory and CPU footprint, especially for large sprites and sprites with a lot of whitespace.

  • bleedthrough: for sprites that don't have much whitespace to separate images, there's an increased chance of nearby images visibly bleeding through other elements, as in this case where bleedthrough was only seen on iOS (but looked fine on Chrome and Safari on the desktop). Note

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

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

  • 渗出:对于没有太多空白来分隔图像的精灵,附近图像明显渗出其他元素的可能性增加,因为在这种情况下,渗出仅在 iOS 上看到(但在桌面上的 Chrome 和 Safari 上看起来很好) )。笔记

Example Base64 Loading Spinner:

示例 Base64 加载微调器:

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

Working Example:

工作示例:

When to Base64 Encode Images (and When Not To)- http://davidbcalhoun.com/2011/when-to-base64-encode-images-and-when-not-to/

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

Encoding Tools

编码工具

Other StackOverflow References:

其他 StackOverflow 参考资料:

回答by Vality

This is only something of a guess, but I think your record loading script is blocking the web browser by running in the main thread. This is not a desirable behaviour but fortunately this is exactly what webworkerswere made for. First I recommend you read this pageto get a little background then read on.

这只是一个猜测,但我认为您的记录加载脚本通过在主线程中运行来阻止 Web 浏览器。这不是一种理想的行为,但幸运的是,这正是webworkers的目的。首先,我建议您阅读此页面以获得一些背景知识,然后继续阅读。

Basically you need to first move your loading code into a separate javascript file. This separate file should contain all the code to load the record, then place it in an object and post the object back to the main thread as shown bellow. You can then invoke this code from your main thread using:

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

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

Now the content which a webworker can directly access is limited due to thread safety concerns, therefore you may need to retrieve the records and then send them to the main thread using a postMessage(x);call which allows you to send any object back to the main page. The main page can then react to this message by installing a message handler with:

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

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

This means that the main thread is not blocked while all the records load and can animate your icon, only blocking briefly when it receives a record.

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

If this is not clear enough or you need more help please just ask :)

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

EDIT:

编辑:

To go into detail, in your case, inside the separate file you will want some code which does something along the lines of:

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

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

then in your main file you want:

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

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);
}; 

Note, this code does not actually do anything with the data once it receives it, you will want to handle that but I am sure you get the rough idea. Note these are also snippets only, you will need to turn them into full functions etc

请注意,此代码在收到数据后实际上并没有对数据执行任何操作,您会想要处理它,但我相信您已经大致了解了。请注意,这些也只是片段,您需要将它们转换为完整的功能等