【问题标题】:Load certain images before sending any other requests to the server在向服务器发送任何其他请求之前加载某些图像
【发布时间】:2020-10-26 06:09:40
【问题描述】:

我有一个基本的 Node js express web 应用程序,前端带有 webix UI。

有很多组件/表格需要在这些表格中填充大量数据。

我有一个加载屏幕,其中包含一些背景图像,每 3 秒更改一次背景图像 URL,直到所有数据的加载完成。

加载屏幕的问题在于图像不是浏览器首先下载的内容。这些表格有时甚至在图像下载之前就已填充,这超出了加载屏幕的全部目的。

我想知道是否有一种方法可以在浏览器中打开应用程序时首先加载这些图像。

这是 HTML 代码:

<body>
        <div id="container-id" class="container">
            <div id="text-id" class="text">Loading...</div>
        </div>
</body>

这是 CSS:

@-webkit-keyframes changeBg
    {
        0%  {background-image: url("/resources/images/one.jpg");}
        25%   {background-image: url("/resources/images/two.jpg");}
        50%   {background-image: url("/resources/images/three.jpg");}
        75%  {background-image: url("/resources/images/four.jpg");}
        100%  {background-image: url("/resources/images/five.jpg");}
    }
    .container {
      height: 100%;
      width: 100%;
      background-image: url("/resources/images/one.jpg");
      -webkit-animation: changeBg 15s infinite;
      background-size: 100%;
      background-position: center;
    }

基于这个类似的问题:load specific image before anything else

我尝试使用 javascript 作为索引页面的前几行加载图像,如下所示:

<head>
        <script type="text/javascript">
            (new Image()).src= window.location.href + "resources/images/one.jpg";
            (new Image()).src= window.location.href + "resources/images/two.jpg";
            (new Image()).src= window.location.href + "resources/images/three.jpg";
            (new Image()).src= window.location.href + "resources/images/four.jpg";
            (new Image()).src= window.location.href + "resources/images/five.jpg";
        </script>
        <link rel="stylesheet" href="webix.css" type="text/css" media="screen" charset="utf-8" />
        <link rel="stylesheet" href="app.css" type="text/css" media="screen" charset="utf-8" />
</head>

但是,其他请求仍然在图像之前得到服务。

【问题讨论】:

  • 你可以尝试用promises 实现它吗?
  • 不能使用Promises?例如:伪代码:ImagePromise.All(fetchImages).then(loadDOM)?
  • 如果您使用节点作为服务器,请尝试对前端做出反应。 React 让这件事变得更简单。 :)
  • @KarlL 您的意思是在 Promise 中加载图像,然后在“then”部分中加载其余的 CSS 和 JS 文件? 资产将如何在当时的部分中被识别 - 我在这里有什么问题吗?有没有办法可以在答案中发布 JSFiddle 或示例 sn-p
  • @cybercoder 我没有尝试过,但我怎么会在“then”部分声明其余资产,比如 Javascript 无法识别 标签 - 我这里有什么问题吗?有没有办法可以在答案中发布 JSFiddle 或示例 sn-p

标签: javascript html css node.js


【解决方案1】:

实际上脚本是按照它们在head 中的顺序加载的。浏览器不会等待事件被引发然后去加载其他脚本(这没有意义)。因此,您的脚本已完全加载,但未引发用于图像加载的 event

所以我们必须await 直到所有图像都加载完毕then 加载脚本。

代码如下:

<script type="text/javascript">
    function loadImageAsync(url) {
        return new Promise((resolve) => {
            let img = new Image();
            img.src = url;
            img.addEventListener('load', e => resolve(img));
        });
    };

    async function loadImages() {
        var im1 = loadImageAsync("imageUrlOne");
        var im2 = loadImageAsync("imageUrlTwo");

        var image1 = await im1;
        console.log(`image one loaded..., url:${image1.src}`)
        var image2 = await im2
        console.log(`image two loaded..., url:${image2.src}`)
    }

    function loadScript(url) {
        var script = document.createElement("script")
        script.type = "text/javascript";
        script.src = url;
        document.getElementsByTagName("head")[0].appendChild(script);
    }

    loadImages().then(() => {
        console.log("loading scripts...");
        loadScript("script 1 url here");
        loadScript("script 2 url here");
    });
</script>

【讨论】:

  • 试过了,没用。加载图像的脚本是页面上的第一件事。其余资产是在我在问题中发布的脚本之后声明的。
  • 这看起来可行,但我在脚本(.dust)中注入了一些变量,这些变量决定了用户的授权 - 通过将其余脚本的加载设置为“那么”逻辑我将无法通过该授权。话虽如此,我没有在我的问题中提到这种情况。您确实回答了我的要求,我非常感谢您的帮助。
  • 在稍微调整了我的灰尘文件并使用了一些解决方法后,我得到了这个工作。欣赏努力。谢谢
【解决方案2】:

你可以使用 react js 来做这些事情,Reactjs 让很多这样的事情变得简单。 了解更多有关 react 的信息。

访问:https://reactjs.org/

import React from "react";

class ImageWithStatusText extends React.Component {
  constructor(props) {
    super(props);
    this.state = { imageStatus: "loading" };
  }

  handleImageLoaded() {
    this.setState({ imageStatus: "loaded" });
  }

  handleImageErrored() {
    this.setState({ imageStatus: "failed to load" });
  }

  render() {
    return (
      <div>
        <img
          src={this.props.imageUrl}
          onLoad={this.handleImageLoaded.bind(this)}
          onError={this.handleImageErrored.bind(this)}
        />
        {this.state.imageStatus}
      </div>
    );
  }
}
export default ImageWithStatusText;

【讨论】:

  • 我现在无法更改技术堆栈,但可能用于不同的应用程序。
猜你喜欢
  • 1970-01-01
  • 2021-02-09
  • 1970-01-01
  • 2022-09-26
  • 2020-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-24
相关资源
最近更新 更多