整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

解决ios15系统的手机使用html2canvas截图页面空白崩溃

近ios15系统推出了,公司的app开始测试ios15的兼容,然后就出现了有截图的页面卡顿白屏的问题。

业务场景是这样,我们的每个页面都会有多个截图,截图使用的方式是html2canvas这个插件,

1、截图方法如下:

// 截图方法
 function convertToPoster() {
   var $poster = $('#poster-content');
   html2canvas($poster[0], {useCORS: true})
     .then(
     function (canvas) {
       var oImage = new Image();
       oImage.src = canvas.toDataURL('image/png', 1);
       $(oImage)
         .addClass('poster');
       $poster.parent()
         .after(oImage)
         .hide();
     }
   );
 };

2、调用方法如下:

$(window).load(function() {
  convertToPoster();
})

3、问题现象:

当页面先截一张图之后,再去截第二张图时,页面就会出现卡顿白屏的问题,这个问题时必现,且在ios的浏览器中走也是这样。

4、解决方案:

经过很多轮的调试之后,依然找不出原因,因为既无报错也不确定页面是在哪行代码卡住的,最终只能采用笨办法,去屏蔽页面的html结构,只留下两个截图的结构,突然好运降临,页面不卡了,截图成功了,那是不是就能证明是页面的某个dom结构导致的呢?

因为页面较为复杂,最终经过10多轮的屏蔽组合,终于确定在了button这里,那么这个button按钮的样式会有什么影响呢?

一步一步挨个去屏蔽属性,结果并没有预料中的变好,正在疑惑之时,突然看到了用户代理样式里面有三个属性是没有替换的,其中有个font-family:system-ui这个样式在chrome浏览器中是没有的,会不会是这个影响的呢?果然屏蔽了它之后就可以了,页面操作无比丝滑。

我们先来看看这个样式究竟是什么意思?

system-ui是一种通用字体系列,它选择当前操作系统下的默认系统字体,它的优势在于和当前系统使用的字体相匹配,可以让Web页面和App风格看起来更统一。

话说它虽然出现得比较晚,但是在can i use上显示的兼容性还是很好的,为啥会出现在ios15的手机系统上呢?目前ios15的资料还少之又少查不到,有待于深究。

记录下目前的处理方案:

//兼容ios15手机系统字体导致的问题
var isiOS = !!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
if (isiOS) {
  var ios_ver = parseInt(navigator.userAgent.toLowerCase().match(/cpu iphone os (.*?) like mac os/)[1].replace(/\_/g, '.'));
  if (ios_ver >= 15) {
    if ($('button')) {
      $('button').css('font-family', 'PingFangSC-Regular');
    }
  }
}

版权声明

本文为[青咕咕]所创,转载请带上原文链接,感谢

https://juejin.im/post/7006119499216715783

寻找热爱表达的你#


"一键将网页截图制作成HTML网页"是指一种技术,它允许用户通过简单的操作,将网页的截图转换成HTML代码的网页。这通常涉及到自动布局、样式提取和代码生成。以下是实现这一功能的相关技术和步骤:

1. 截图捕捉:首先,需要有一个方法来捕捉网页的截图,这可以通过浏览器插件、屏幕捕获工具或专门的应用程序来完成。

2. 图像处理:捕捉到的截图可能需要进行预处理,比如裁剪、压缩或调整分辨率,以确保图像的质量。

3. 元素识别:使用图像识别技术来分析截图,识别网页中的元素,比如文本、按钮、图片等。

4. 布局分析:基于识别出的元素,分析页面的布局信息,包括元素的大小、位置和层级。

5. 样式解析:提取页面的样式信息,包括颜色、字体、间距等,并将它们转换为CSS代码。

6. HTML生成:根据布局和样式信息,生成HTML结构代码,将截图中的元素转换为HTML标签。

7. 代码优化:对生成的HTML代码进行优化,确保代码的可读性、维护性和性能。

8. 响应式设计:确保生成的网页代码能够适应不同的屏幕尺寸和设备,实现响应式布局。

9. 交互性实现:如果截图中的页面包含交互元素,需要添加相应的JavaScript代码来实现这些交互。

10. 一键操作:提供一个简单的用户界面,用户只需点击一个按钮,就可以完成截图到HTML的转换。

11. 预览功能:在转换过程中提供实时预览,让用户可以实时看到转换效果。

12. 自定义选项:允许用户对生成的HTML代码进行自定义,比如修改布局、添加额外的样式或功能。

13. 保存和导出:用户可以保存或导出生成的HTML代码,以便进一步使用或分享。

14. 错误处理:在转换过程中识别和处理潜在的错误,比如布局冲突或样式问题。

15. 兼容性测试:确保生成的网页在不同的浏览器和设备上都能正常显示和工作。

16. 安全性考虑:生成的代码应遵循安全最佳实践,避免潜在的安全风险。

17. 用户反馈:收集用户反馈,不断改进转换算法和用户体验。

18. 开源和社区支持:作为开源项目,鼓励社区参与贡献代码和改进功能。

这种一键转换技术可以大大提高网页开发的效率,尤其是对于快速原型设计和演示目的。然而,需要注意的是,自动生成的代码可能需要进一步的人工审查和调整,以确保最终产品的质量和性能。此外,一些复杂的网页效果和动态交互可能需要手动编写代码来实现。

需求一直有,今年比较多,如题,工作中遇到网页截图这样的需求,本着效果好,功能全又稳定的意图,去网上搜索相关技术,像HTML2Image、cssbox、selenium等,还有很多其他的技术,这篇文章主要说说我测试使用并能满足需求的cssbox,selenium。

Cssbox

CSSBox是一个用纯Java编写的(X)HTML/CSS渲染引擎。它的主要目的是提供关于呈现的页面内容和布局的完整和进一步可处理的信息。 但是,它也可以用于浏览Java Swing应用程序中呈现的文档。核心CSSBox库还可以用于获得所呈现的文档的位图或矢量(SVG)图像。 使用SwingBox包,CSSBox可以用作Java Swing应用程序中的交互式Web浏览器组件。

官网地址:http://cssbox.sourceforge.net/

使用

1引入maven依赖

<!--网站转换为图片cssbox-->
<dependency>
<groupId>net.sf.cssbox</groupId>
<artifactId>cssbox</artifactId>
<version>5.0.0</version>
</dependency>

2使用

@Test
public void cssboxTest(){
    try {
        ImageRenderer render = new ImageRenderer();
        //网络链接的html
        String url = "https://www.zhangbj.com/p/524.html";
        //文件保存路径
        String path = "C:\\Users\\Administrator\\Desktop"+File.separator+"html.png";
        FileOutputStream out = new FileOutputStream(new File(FilenameUtils.normalize(path)));
        //开始截屏
        render.renderURL(url, out);
    } catch (Exception e) {
    e.printStackTrace();
    }
}

3结果

样式可能出现问题,中文有时候乱码

Selenium

1引入依赖

<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>

2相关准备

selenium+chromedriver谷歌驱动+chrome浏览器

1.注意谷歌驱动的版本要和谷歌浏览器的版本一样或者版本最相近

2.注意chromedriver谷歌驱动需要放在jdk安装目录下,具体路径为xxx/bin/chromedriver.exe,在linux和window中操作一样,这样切换系统是就无需改代码。

3.需要安装谷歌浏览器

谷歌驱动下载地址:https://registry.npmmirror.com/binary.html?path=chromedriver/

3使用

@Slf4j
public class Html2ImageUtil {
/**
* 将HTML转为图片,并保存至指定位置
* @param url 页面地址
* @param targetPath 保存地址(包含图片名,如 /images/test.png)
* @return
*/
public static String htmlToImage(String url, String targetPath) {
  if (StringUtils.isEmpty(url) || StringUtils.isEmpty(targetPath)) {
  throw new RuntimeException("截图失败!缺少必填项");
  }
  // 休眠时长
  Integer sleepTime = 3 * 1000;
  // 无头模式
  System.setProperty("java.awt.headless", "true");
  //获取谷歌配置信息
  ChromeOptions chromeOptions = getChromeOptions();
  // 配置信息中有默认窗口大小,也可以单独设置窗口大小
  chromeOptions.addArguments("--window-size=1920,6000");
  //创建webdriver 谷歌驱动
  WebDriver driver = new ChromeDriver(chromeOptions);
  //也可以通过如下方式设置窗口大小
  // Dimension dimension = new Dimension(1000, 30);
  // driver.manage().window().setSize(dimension);
  try {
    //加载页面
    driver.get(url);
    //等待加载页面
    Thread.sleep(sleepTime);
    //截屏
    File srcFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
    //保存到指定位置
    FileUtils.copyFile(srcFile, new File(FilenameUtils.normalize(targetPath)));
  } catch (InterruptedException | IOException e) {
  e.printStackTrace();
  throw new RuntimeException(e.getMessage());
  } finally {
  driver.quit();
  }
  log.info("截图成功!");
  return targetPath;
}
/**
* 获取chrome配置信息
* 注意 chromedriver谷歌驱动需要放在jdk安装目录下,具体路径为xxx/bin/chromedriver.exe ,在linux和window中操作一样
* @return
*/
public static ChromeOptions getChromeOptions() {
    ChromeOptions options = new ChromeOptions();
    //获取当前操作系统
    String os = System.getProperty("os.name");
    //获取jdk安装目录,需要提前将谷歌驱动放进jdk的bin目录下,在linux和window中操作一样
    String sysPath = System.getProperty("java.home").replace("jre", "bin");
    String chromeDriver = sysPath + File.separator+"chromedriver.exe";
    options.addArguments("disable-infobars");
    //设置为 headless 模式,不需要真实启动浏览器
    options.setHeadless(true);
    //options.addArguments("--headless");
    options.addArguments("--dns-prefetch-disable");
    options.addArguments("--no-referrers");
    options.addArguments("--disable-gpu");
    options.addArguments("--disable-audio");
    options.addArguments("--no-sandbox");
    options.addArguments("--ignore-certificate-errors");
    options.addArguments("--allow-insecure-localhost");
    options.addArguments("--window-size=1920,6000"); // 窗口默认大小
    String userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36";
    userAgent = "user-agent=" + userAgent;
    options.addArguments(userAgent);
    // 设置chrome二进制文件
    options.setPageLoadStrategy(PageLoadStrategy.EAGER);
    // 设置驱动
    System.setProperty("webdriver.chrome.driver", chromeDriver);
    log.debug("结束获取chrome配置信息");
    return options;
}

测试

public static void main(String[] args) {
		htmlToImage("https://www.cnblogs.com/tester-ggf/p/12602211.html","C:\\Users\\Administrator\\Desktop\\aaa.png");
}

效果十分完美

总结

最完美的方案就是selenium+chromedriver谷歌驱动+chrome浏览器,无需多说,用吧。

您的赞和关注是对我创作的最大肯定谢谢大家!