在 svg 中需要写一个 markdown 编辑器,需要用到 <foreignObject> 绘制来html,编辑器选择了 simplemde。大致html部分结构如下,<markdown-editor> 组件为定制封装好的 simplemde 编辑器。

<template>
<svg>
<g>
<foreignObject :width="XXX" :height="XXX">
<div xmlns="http://www.w3.org/1999/xhtml">
<markdown-editor></markdown-editor>
</div>
</foreignObject>
</g>
</svg>
</template>

  在 Chrome 浏览器开发完成,测试上线都符合预期,但是最后收到用户反馈:她用的是 mac 自带的 Safari 浏览器,在 Safari 里markdown编辑器会出现错位等各种问题。于是我先打开我的 Firefox 浏览器,自测正常,那估计就是 Safari 浏览器的兼容问题了。我看了下 Safari 浏览器的表现:markdown 编辑器每次一打开检查本身的 dom 占位是正确的,但是可视的编辑器界面却会被渲染到最顶部 <svg> 标签的左上角原点(0,0)。最后排查到是因为 safari 对 SVG 中的 <foreignObject> 标签支持不友好,渲染容易错位,特别是遇到 position 属性的时候,而我在引入simplemde 编辑器的同时也引入了 simplemde.min.css,其中大量使用了 position 属性我也在 StackOverflow 和 Github 找到了几篇关于这个bug的讨论帖作为参考:

  StackOverflow:SVG foreignObject not working properly on Safari

  Github:Safari + foreignobject render issue

  最后Github一位程序员ankero一锤定音,原文大意如下:

    这不是一个问题,但是可以添加到 README 中。我将在这里添加它,以便如果有人面临类似的问题,可以在这个仓库中找到一个解决方案。在使用这个库(指的是react-d3-tree库,但是遇到的问题是一样的)进行开发时,如果使用 foreignObject 呈现节点,请检查它在 Safari (Mac + iOS)中的显示方式。我们遇到了一个问题,节点内容呈现为父 SVG 的坐标0,0(左上角)。这是由于 Safari 中的一个 bug,它影响 foreignObject 根据顶部 SVG 而不是 foreignObject 本身计算呈现位置。通过检查节点并查看基于浏览器的节点是否在应该在的位置,您可以非常清楚地看到这种效果,但是呈现在了错误的位置。(这段描述和我当时排查的结果一模一样)

    那么,如果你看到这个问题,解决方案是什么?

    据我所知,如果您使用以下任何 CSS 选项,dom 元素将呈现在错误的位置。所以解决办法就是不要用这些。对我们来说,我们需要检查浏览器是否是 Safari,然后删除一些需要一个或多个这样的样式的功能。

      所以不要在 Safari + foreignObject 中使用以下样式:

        • position(您可以使用 position: fixed,但这将导致溢出问题)
        • webkit-transform-style
        • webkit-backface-visibility
        • transition
        • transform

    如何检测 Safari?

    我们使用以下片段:

export const IS_SAFARI = /Safari/.test(navigator.userAgent) && /Apple Computer/.test(navigator.vendor);

  这里提一下 position: fixed 导致的溢出问题,这个在上一个StackOverflow链接中被很多程序员提为解决,方案,这个办法确实能解决一些简单的需求和页面,但是需要注意的一点是,使用这种办法会导致页面缩放出现问题。具体来说就是svg所绘制元素的缩放比例与<foreignObject>所绘制元素的缩放比例不是一致的,这也会带来位置错乱问题。不过可以根据自己的具体情况进行抉择。

  各大浏览器之间的兼容问题是各位前端er心中永远的痛,一方面希望谷歌或火狐浏览器能一统江湖,但是另一方面又希望百家齐放能促进前端技术的发展。但是话说又说回来,最重要的还是遵守标准,既然标准都设立在那了,为啥各家不跟上标准呢。

Safari浏览器对SVG中的<foreignObject>标签支持不友好,渲染容易错位的更多相关文章

  1. WebKit策略:<foreignObject>可用于绘制svg中的html标签,但与<use>搭配不生效

    在<svg>里面可以利用<foreignObject>绘制html标签,原本是我在iconfont采用Font class方式引入svg的无奈之举. 起初的设计是所有icon先 ...

  2. html页面在苹果手机内,safari浏览器,微信中滑动不流畅问题解决方案

    1. -webkit-overflow-scrolling:touch是什么? MDN上是这样定义的: -webkit-overflow-scrolling 属性控制元素在移动设备上是否使用滚动回弹效 ...

  3. Dedecms中{dede:type}标签支持调用父级栏目名称

    需求: 我们用{dede:type}标签调用栏目相关内容时,同时需要调用该栏目的父级栏目的名称. {dede:type}标签的代码做了一下开发,支持这个调用了. 开发方法: 1.打开include/t ...

  4. eclipse中添加jstl标签支持(引入头)

    https://blog.csdn.net/wangyuxuan_java/article/details/8580318

  5. d3.js svg中 g 标签问题一览

    svg 中的g标签, 算是比较特殊 1 没有x y属性 2 没有width height 属性 3 不能fill 4 .... g标签基本只管分组问题, 其他功能一概不提供 要解决这些问题, 直接在g ...

  6. iOS中Safari浏览器select下拉列表文字太长被截断的处理方法

    网页中的select下拉列表,文字太长的话在iOS的Safari浏览器里会被自动截断,显示成下面这种: 安卓版的浏览器则没有这个问题. 如何让下拉列表中的文字在iOS的Safari浏览器里显示完整呢? ...

  7. 利用iOS中Safari浏览器创建伪Web App

    在safari浏览器里有一个“添加到主屏幕”选项,我们可以用来创建伪Web App,下面来了解一下iOS中Safari的私有属性 第一步设置Web App的主屏幕图标: 有两种属性值apple-tou ...

  8. 获取SVG中g标签的宽度高度及位置坐标

    1. 问题的出现 对于普通的HTML元素,有很多获得其宽度width.高度height.距左left.距顶top等属性的方法: 类似offsetWidth,clientWidth,width之类的,通 ...

  9. 发布时一键添加html中的css标签和script标签版本号来防止浏览器缓存

    AppendFileVersion 是一个VSIX插件支持vs2015意以上版本 是我用来发布时一键添加html中的css标签和script标签版本号来防止浏览器缓存 分享给大家! download ...

  10. 解决java web中safari浏览器下载后文件中文乱码问题

    解决java web中safari浏览器下载后文件中文乱码问题 String fileName = "测试文件.doc"; String userAgent = request.g ...

随机推荐

  1. PHP全栈开发(二):MYSQL学习

    昨天进行了CentOS 7 下面的 LAMP搭建 今天学习一下MySQL的一些入门级操作 主要参考PHP中文网的"MySQL最新手册教程" http://www.php.cn/my ...

  2. CentOS 7.9 安装 nginx-1.22.0

    一.CentOS 7.9 安装 nginx-1.22.0 下载地址:http://nginx.org/en/download.html 2 安装前的准备 # 操作系统内核版本 uname -a # 操 ...

  3. SpringBoot入门项目CRM学习过程中的报错记录(更新ing)

    在用mybatis自动生成实体类和mapper时报错..... is unrecognized or represents more than one time zone. You must conf ...

  4. 研一入坑Go 文件操作

    1 package main 2 3 import ( 4 "fmt" 5 "os" 6 "path" 7 "path/filep ...

  5. A-卷积网络压缩方法总结

    卷积网络的压缩方法 一,低秩近似 二,剪枝与稀疏约束 三,参数量化 四,二值化网络 五,知识蒸馏 六,浅层网络 我们知道,在一定程度上,网络越深,参数越多,模型越复杂,其最终效果越好.神经网络的压缩算 ...

  6. Kafka之 API实战

    Kafka之 API实战 一.环境准备 1)启动zk和kafka集群,在kafka集群中打开一个消费者 [hadoop1 kafka]$ bin/kafka-console-consumer.sh \ ...

  7. vulnhub靶场之RED: 1

    准备: 攻击机:虚拟机kali.本机win10. 靶机:RED: 1,地址我这里设置的桥接,,下载地址:https://download.vulnhub.com/red/Red.ova,下载后直接Vi ...

  8. 在vue中的form表单中下拉框中的数据来自数据库查询到的数据

    文章目录 1.实现的效果: 2.前端html代码 3.js中的代码 4.后端的方法 1.实现的效果: 增加一个新的类型到数据库 2.前端html代码 需要注意的部分:prop后边是表单中的字段 v-m ...

  9. Jedis测试redis。(redis在linux虚拟机中)

    文章目录 1.确保虚拟机开启.并且连接到redis 2.建立一个maven工程 3.在pom中加入jedis的依赖 4.编写测试用例 5.测试结果 1.确保虚拟机开启.并且连接到redis 2.建立一 ...

  10. HTML躬行记(2)——WebRTC基础实践

    WebRTC (Web Real-Time Communications) 是一项实时通讯技术,在 2011 年由 Google 提出,经过 10 年的发展,W3C 于 2021 年正式发布 WebR ...