首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在reactjs中检测是否支持avif?

如何在reactjs中检测是否支持avif?
EN

Stack Overflow用户
提问于 2021-11-11 10:19:56
回答 2查看 275关注 0票数 0

我正试图通过格式化来优化图像。但有些浏览器不支持avif。

所以我创建了这样一个实用程序函数

代码语言:javascript
复制
  function isAvifSupported() {
    let returnValue;
    const avif = new Image();
    avif.src =
      "data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAIAAAACAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQ0MAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgANogQEAwgMg8f8D///8WfhwB8+ErK42A=";
    avif.onload = function () {
        returnValue = true
    };
    return returnValue;
  }

但是,当我试图调用这个函数时,它总是返回未定义的。但是当我使用在航空网站上提供的功能时。效果很好。下面是它的代码

代码语言:javascript
复制
function AddClass(class) { document.documentElement.classList.add(class) };
var avif = new Image();
avif.src = "data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAIAAAACAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQ0MAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgANogQEAwgMg8f8D///8WfhwB8+ErK42A=";
avif.onload = function () { AddClass("avif") };
avif.onerror = function () {
  var webp = new Image();
  webp.src = "data:image/webp;base64,UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==";
  webp.onload = function () { AddClass("webp") }
}

但是上面定义的函数在dom的顶层添加了css。它必须返回true或false,而不是添加类。这样我就能像这样很容易地处理好。

代码语言:javascript
复制
let updatedImageUrl = isAvifSupported() ? `${imageUrl}?fm=avif` ? imageUrl

但我不知道怎么解决这个问题。请推荐一个解决方案。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-11-12 04:25:39

下面的功能将运行良好。这是@Stefan Judis的扩展回答版本。我根据我的项目修改了这个

代码语言:javascript
复制
import React, { useEffect, useState } from "react";
import "./styles.css";

const url =
  "https://images.ctfassets.net/{space_id}/1WJFyl9C8q18KI6OQG7mPu/{unique_name}/name.jpg";

const ImageFormat = () => {
  const [imageFormat, setImageFormat] = useState("");

  function addImageProcess(src) {
    return new Promise((resolve, reject) => {
      let img = new Image();
      img.onload = () => resolve("avif");
      img.onerror = () => {
        const webp = new Image();
        webp.src =
          "data:image/webp;base64,UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==";
        webp.onload = async () => {
          resolve("webp");
        };

        webp.onerror = () => {
          reject("");
        };
      };
      img.src = src;
    });
  }

  useEffect(() => {
    async function logImageFormat(imageUrl) {
      let imageFormatValue = await addImageProcess(imageUrl);
      setImageFormat(`${url}?fm=${imageFormatValue}&w=3500`);
    }

    logImageFormat(
      "data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAIAAAACAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQ0MAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgANogQEAwgMg8f8D///8WfhwB8+ErK42A="
    );
  }, []);

  return (
    <>
      <div className="App">{imageFormat}</div>
    </>
  );
};

export default ImageFormat;
票数 0
EN

Stack Overflow用户

发布于 2021-11-11 11:33:15

代码段的主要问题是没有考虑异步调用。

函数返回后将调用onload。要解决这个问题,您必须提供回调并实现承诺,如下例所示。

代码语言:javascript
复制
function isAvifSupported() {
  return new Promise(resolve => {
      var image = new Image();
  
      image.onload = image.onerror = function() {
        resolve(image.width === 2);
      };
  
      image.src = "data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAIAAAACAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQ0MAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgANogQEAwgMg8f8D///8WfhwB8+ErK42A=";
    });
}

isAvifSupported().then(console.log);

作为灵感,我调整了标准现代化片段以适应您的用例,并使用了您的虚拟映像。

请记住,因为您必须使用异步调用,所以特性检测也必须是异步的。

代码语言:javascript
复制
isAvifSupported().then(
  isSupported => {
    const updatedImageUrl = isSupported ?
      `${imageUrl}?fm=avif` :
      imageUrl;
  }
);

根据您的项目,您可能需要重构一些东西来实现承诺(或回调)解决方案,但不幸的是,无法同步检查avif支持。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69926617

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档