整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          js如何控制一次只加載一張圖片,加載完成后再加載下一

          js如何控制一次只加載一張圖片,加載完成后再加載下一張

          天看到一個面試題,是關于img圖片加載方面的,有必要記錄一下。其實關于這個問題,只要知道圖片什么時候加載完成就能解決了。

          通過onload事件判斷Img標簽加載完成

          實現邏輯:新建一個Image對象實例,為實例對象設置src屬性等,在onload事件中添加此實例對象到父元素中,然后將圖片地址數組中的第一個元素剔除,繼續調用此方法直到存儲圖片地址的數組為空。

          代碼

          const imgArrs=[...]; // 圖片地址
          const content=document.getElementById('content');
          const loadImg=()=> {
          if (!imgArrs.length) return;
          const img=new Image(); // 新建一個Image對象
          img.src=imgArrs[0];
          img.setAttribute('class', 'img-item');
          img.onload=()=> { // 監聽onload事件
          // setTimeout(()=> { // 使用setTimeout可以更清晰的看清實現效果
          content.appendChild(img);
          imgArrs.shift();
          loadImg();
          // }, 1000);
          }
          img.onerror=()=> {
          // do something here
          }
          }
          loadImg();
          
          </script>

          實現效果

          加上setTimeout后,看到的效果更加明顯,我這里加了500毫秒的延遲(錄屏軟件只支持錄制8秒的時間...)

          其實我在網上還看到了一種答案,通過onreadystatechange事件實現監聽,于是在我本地調試了一下,發現并不能實現,img實例對象上并沒有這個屬性方法。查了查MDN,發現目前僅有XmlHttpRequest對象和Document對象中存在onreadystatechange屬性,而對于其它元素onreadystatechange此屬性并不存在。

          因此對于其它元素需要慎用onreadystatechange事件

          不過我電腦上目前只有Chorme和Safari兩種瀏覽器,對于onreadystatechange測試的覆蓋面不全,所以我上面的結論可能還需要進一步驗證才行,感興趣的掘友可以調試一下~。

          擴展知識

          img標簽是什么時候發送圖片資源請求的?

          1. HTML文檔渲染解析,如果解析到img標簽的src時,瀏覽器就會立刻開啟一個線程去請求圖片資源。
          2. 動態創建img標簽,設置src屬性時,即使這個img標簽沒有添加到dom元素中,也會立即發送一個請求。
          // 例1:
          const img=new Image();
          img.src='http://xxxx.com/x/y/z/ccc.png';

          上面的代碼如果運行起來后,就會發送請求。 如圖:

          再看一個例子:創建了一個div元素,然后將存放img標簽元素的變量添加到div元素內,而div元素此時并不在dom文檔中,頁面不會展示該div元素,那么瀏覽器會發送請求嗎?

          // 例2:
          const img=`<img src='http://xxxx.com/x/y/z/ccc.png'>`;
          const dom=document.createElement('div');
          dom.innerHtml=img;

          答案:會請求。如圖:

          通過設置css屬性能否做到禁止發送圖片請求資源?

          1. 給img標簽設置樣式display:none或者visibility: hidden,隱藏img標簽,無法做到禁止發送請求。
          <img src="http://xxx.com/x/sdf.png" style="display: none;">
          或者
          <img src="http://xxx.com/x/sdf.png" style="visibility: hidden;">
          1. 將圖片設置為元素的背景圖片,但此元素不存在,可以做到禁止發送請求。
          <!DOCTYPE html>
          <html lang='en'>
          <head>
          <meta charset='UTF-8'>
          <title></title>
          <style>
          .test {
          height: 200px;
          background-image: url('http://eb118-file.cdn.bcebos.com/upload/39148b2a545b48bf9b4ee95fd1b7f1eb_1515564089.png?');
          }
          </style>
          </head>
          <body>
          <div></div>
          </body>
          </html>
          

          dom文檔中不存在test元素時,即使設置了背景圖片,也不會發送請求,只有test元素存在時才會發送請求。

          另外這個例子其實有點不太貼切,img標簽和background-image二者有著本質的區別。一個屬于HTML標簽,另一個屬于css樣式,加載機制和解析順序也不同。

          一個完整的頁面是由js、html、css組成的,按照解析機制,html元素會優先解析,盡管css樣式是放在head標簽內的,但也不意味著它會優先加載,它只有等到html文檔加載完成后才會執行。而img標簽屬于網頁內容,所以img標簽會隨著網頁解析渲染優先于css樣式表加載出來。


          作者:娜個小部呀
          鏈接:https://juejin.cn/post/7340167256267391012

          、認識網頁

          在學習之初,我們需要認識一下網頁的概念,因為網頁與我們的 html是息息相關的。

          那么接下來我們來看一下,我們經常去通過瀏覽器查看的網頁,它的本質是什么?在此我們需要去做一個對比。我們眼中看到的網頁與程序員眼中看到的網頁,到底有什么不同?

          首先就是我們用戶眼中看到的網頁,這是一個普通的網頁,它的一個首頁的效果。這個里面大家可以看到有很多的文字內容,包括一些圖片內容,并且呢它按照一定的格式去進行了一個排版,那么這些就是我們用戶看到的網頁。


          用戶眼中看到的網頁


          而同樣這樣一個網頁,在程序員眼中是什么樣的效果呢?實際上程序員眼中的網頁,都是由這樣一系列的代碼組成,這個代碼里面并不能直觀的去展示成我們眼中看到的,比如圖片以及其他的內容效果。那么程序員的這眼中的網頁是怎么制作出來的。而用戶眼中的這個網頁又是怎么去呈現出來的?這是我們需要去思考的問題?

          程序員眼中看到的網頁

          接下來我們先解決第一個問題,程序員是如何去制作網頁文件的,其實程序員用的就是我們的 html 技術來去制作網頁文件。而我們通過瀏覽器查看到的網頁都是這種擴展名為點 html 或者是點 htm 的文件。

          二、 HTML 是什么呢

          HTML叫做超文本標記語言(Hypertext Markup Language),它是一種標記語言,主要就是用來去搭建網頁的結構用的。

          那么程序員制作的網頁就是 html 文件嗎?也不全是。網頁的組成呢很復雜 它除了 HTML之外,還有其他的內容。

          三、網頁的組成

          首先我們來看一下我們網頁的里面,組成的一個相關技術,也就是我們前端所需要學習的三層技術:

          這個里面 html 實際上它是我們制作網頁的時候,第一層叫做結構層,他用來去搭建網頁的整個的結構骨架;

          第二層 css 是樣式層,用來去美化我們的網頁結構;

          第三層叫做 javascript,它是行為層,這個行為實際上就是用來去制作,我們網頁中的很多交互效果;比如用戶點擊的效果,我們的頁面切換的其他效果等等;

          我們通過一個小小的案例,來帶大家好好理解一下什么是前端三層,大家都去自己繪畫或者是觀察過別人繪畫的過程。如果我們去繪制一個人物的時候,那么我們首先需要繪制的就是這個人物的結構,這個結構比如說人物包含頭部、身體以及四肢、我們需要去首先繪制一下它的輪廓,哪個地方是頭部,哪個地方是身體,其實這個過程就相當于前端里面 html 在搭建結構;

          搭建完結構之后,這樣的一個人物是不好看的,所以我們需要用到 css 去對它進行美化,我可以給他去化妝穿衣服,這樣我們就可以得到一個類似照片效果的人物,但是真正的人物效果它是可以去動的,是有各種各樣的運動,各種各樣的動作,這個動作和運動效果由誰來制作呢?就是我們 javascript 它的一個功能,它就相當于我們把一個靜態的,美化之后的一個人物讓它動起來。

          當然我們網頁除了這三層技術之外,它還包含其他的內容,就比如說我們看到的圖片、視頻、音頻、超級鏈接等等;那么這些內容包括我們之前所講的前端三層,它都是我們要去制作的具體存在的文件。

          wagger 是一個簡單、功能強大、非常流行的API 表達工具。基于Swagger 生成API,可以得到交互式文檔、自動生成代碼的SDK,以及API 的發現方式。

          Swagger 允許用戶在一個html5 web 頁面中,對API 進行文檔化和交互。

          優點:

          • 功能豐富:支持多種注解,自動生成接口文檔界面,支持在界面測試API接口功能;
          • 及時更新:開發過程中花一點寫注釋的時間,就可以及時的更新API文檔,省心省力;
          • 整合簡單:通過添加pom依賴和簡單配置,內嵌于應用中就可同時發布API接口文檔界面,不需要部署獨立服務。

          如下是自動生成的API 文檔界面:

          實現 Swagger 文檔

          1. 添加依賴

          主要是 添加 swagger2 核心包 以及 swagger-ui界面包的依賴。

          <dependency>

          <groupId>io.springfox</groupId>

          <artifactId>springfox-swagger2</artifactId>

          <version>2.7.0</version>

          </dependency>

          <dependency>

          <groupId>io.springfox</groupId>

          <artifactId>springfox-swagger-ui</artifactId>

          <version>2.7.0</version>

          </dependency>

          2. 編寫Swagger的配置類

          package com.rickie;

          import org.springframework.context.annotation.Bean;

          import org.springframework.context.annotation.Configuration;

          import springfox.documentation.builders.ApiInfoBuilder;

          import springfox.documentation.builders.PathSelectors;

          import springfox.documentation.builders.RequestHandlerSelectors;

          import springfox.documentation.service.ApiInfo;

          import springfox.documentation.spi.DocumentationType;

          import springfox.documentation.spring.web.plugins.Docket;

          import springfox.documentation.swagger2.annotations.EnableSwagger2;

          @Configuration

          @EnableSwagger2

          public class Swagger2 {

          @Bean

          public Docket createRestApi() {

          return new Docket(DocumentationType.SWAGGER_2)

          .apiInfo(apiInfo())

          .select()

          .apis(RequestHandlerSelectors.basePackage("com.rickie.rest"))

          .paths(PathSelectors.any())

          .build();

          }

          private ApiInfo apiInfo() {

          return new ApiInfoBuilder()

          .title("Swagger構建RESTful API")

          .description("")

          .termsOfServiceUrl("")

          .version("1.0")

          .build();

          }

          }

          3. 在controller 中編寫自己的api 文檔,主要是參數和接口的描述

          如下是ProductController.java 的示例代碼。

          package com.rickie.rest;

          import com.rickie.dto.Product;

          import io.swagger.annotations.ApiImplicitParam;

          import io.swagger.annotations.ApiOperation;

          import org.springframework.web.bind.annotation.PathVariable;

          import org.springframework.web.bind.annotation.RequestMapping;

          import org.springframework.web.bind.annotation.RequestMethod;

          import org.springframework.web.bind.annotation.RestController;

          import java.util.ArrayList;

          import java.util.List;

          @RestController

          @RequestMapping(value="/products") // 通過這里配置使下面的映射都在/products下

          public class ProductController {

          private List<Product> productList;

          //初始化

          public ProductController(){

          productList=new ArrayList<Product>();

          for (int i=0; i < 10; i++) {

          Product product=new Product();

          product.setId(i);

          product.setCount(i+10);

          product.setName("watch"+i);

          product.setDesc("watch desc"+i);

          productList.add(product);

          }

          }

          @ApiOperation(value="獲取產品列表", notes="獲取產品列表")

          @RequestMapping(value={""}, method=RequestMethod.GET)

          public List<Product> getProductList() {

          return productList;

          }

          @ApiOperation(value="獲取產品詳細信息", notes="根據url的id來獲取產品詳細信息")

          @ApiImplicitParam(name="id", value="產品ID", required=true, dataType="Integer",paramType="path")

          @RequestMapping(value="/{id}", method=RequestMethod.GET)

          public Product getProduct(@PathVariable Integer id) {

          return productList.get(id);

          }

          }

          @ApiOperation:

          作用在方法上,表示一個http請求的操作 。

          @ApiImplicitParam:

          作用在方法上,表示單獨的請求參數

          參數:

          1. name :參數名。

          2. value : 參數的具體意義,作用。

          3. required : 參數是否必填。

          4. dataType :參數的數據類型。

          5. paramType :查詢參數類型,這里有幾種形式:

          @ApiImplicitParams:

          用于方法,包含多個 @ApiImplicitParam。

          @Api:

          作用在類上,用來標注該類具體實現內容。標識這個類是swagger的資源 。

          參數:

          1. tags:允許您為操作設置多個標簽的屬性。

          2. description:可描述該類的作用。

          4. 啟動應用程序,訪問Swagger

          訪問如下鏈接,可以看到第一張圖片所示,顯示所有的API 列表方法。

          http://localhost:8080/swagger-ui.html

          點擊查看第一個方法/products,如下圖所示,可以進行交互操作。

          訪問 http://localhost:8080/v2/api-docs 可以獲取接口的JSON 描述文件,如下圖所示。


          主站蜘蛛池模板: 亚洲第一区香蕉_国产a| 亚洲高清偷拍一区二区三区| AV鲁丝一区鲁丝二区鲁丝三区| 国产日韩精品视频一区二区三区 | 日韩一区二区三区在线观看| 亚洲精品精华液一区二区| 亚洲一区爱区精品无码| 冲田杏梨AV一区二区三区| 精品久久一区二区三区| 亚洲一区精品伊人久久伊人| 国产综合视频在线观看一区| 国产精品高清一区二区人妖| 日本一区二区三区在线观看| 国产免费无码一区二区| 久久精品国产第一区二区| 亚洲国产成人久久一区WWW | 国产乱码伦精品一区二区三区麻豆 | 国产探花在线精品一区二区| 国产一区在线观看免费| 日韩内射美女人妻一区二区三区| 国产一区二区中文字幕| 久久婷婷色综合一区二区| 秋霞鲁丝片一区二区三区| 国产伦精品一区二区三区不卡| 一区二区三区免费电影| 免费无码一区二区| 麻豆AV一区二区三区| 台湾无码一区二区| 日韩一区二区三区无码影院| 亚洲图片一区二区| 精品欧洲av无码一区二区14| 人妻无码一区二区三区AV| 麻豆AV一区二区三区久久| 久久国产午夜精品一区二区三区 | 无码人妻精品一区二区三18禁| 日本在线电影一区二区三区 | 精品国产a∨无码一区二区三区| 国产MD视频一区二区三区| 一区二区三区在线|日本| 国产亚洲一区二区手机在线观看| 国产在线无码视频一区二区三区 |