如何将 SVG 数据 URL 从 JS 指向 HTML Object 元素的数据属性?
How can you point an SVG data URL from JS to an HTML Object element's data attribute?
我在 kirupa.com 上找到了一个 simple tutorial,展示了如何使用 JS 将外部 SVG 注入 empty img 元素 在 HTML.
<html>
<head>
<style>
.rocketContainer {
background-color: #FFEB3B;
width: 100px;
height: 100px;
display: flex;
align-content: center;
justify-content: center;
}
.rocketContainer img {
width: 50px;
}
</style>
</head>
<body>
<div class="rocketContainer">
<img/>
</div>
<script>
var imageElement = document.querySelector(".rocketContainer img");
imageElement.src = "https://www.kirupa.com/images/rocket.svg";
</script>
</body>
</html>
但我需要使用对象元素,而不是 img 元素,因为我的 SVG 通过点击使用 JS 进行动画处理。我已经将我的 SVG 转换为数据 URIs/URLs 并在对象元素的数据属性中使用它们,但我在一页上重复使用它们超过六十次,并且相信将它们注入 HTML通过 JS 将有助于加载时间和性能。
Here's a CodePen link w/ my unsuccessful stab 修改上面的代码以使用对象而不是元素。如果有效,它将在右侧的框中显示相同的 SVG。核心代码复制如下。
<html>
<body>
<!-- Test Object with Empty data -->
<object class="likeButtonInject" type="image/svg+xml" data="">
</object>
<script>
var likeButtonObjectElement = document.querySelector(".likeButtonInject object data");
likeButtonObjectElement.data = "data:image/svg+xml,%3Csvg id='eproXtLa4JU1'
xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32.5 32.5' shape-rendering='geometricPrecision' text-rendering='geometricPrecision'%3E%3Cdefs%3E%3CradialGradient id='eproXtLa4JU3-fill' cx='0' cy='0' r='95.5' spreadMethod='pad' gradientUnits='userSpaceOnUse' gradientTransform='translate(99.6 85.5)'%3E%3Cstop id='eproXtLa4JU3-fill-0' offset='0%25' stop-color='rgba(255,255,255,0)'/%3E%3Cstop id='eproXtLa4JU3-fill-1' offset='100%25' stop-color='rgba(255,255,255,0)'/%3E%3C/radialGradient%3E%3CradialGradient id='eproXtLa4JU4-fill' cx='0' cy='0' r='176.8' spreadMethod='pad' gradientUnits='userSpaceOnUse' gradientTransform='rotate(45.1 -53.2 162.8)'%3E%3Cstop id='eproXtLa4JU4-fill-0' offset='0%25' stop-color='rgba(255,255,255,0)'/%3E%3Cstop id='eproXtLa4JU4-fill-1' offset='100%25' stop-color='rgba(122,122,122,0)'/%3E%3C/radialGradient%3E%3Cfilter id='eproXtLa4JU3-filter' x='-400%25' width='600%25' y='-400%25' height='600%25'%3E%3CfeComponentTransfer id='eproXtLa4JU3-filter-contrast-0' result='result'%3E%3CfeFuncR id='eproXtLa4JU3-filter-contrast-0-R' type='linear' slope='1.5' intercept='-.3'/%3E%3CfeFuncG id='eproXtLa4JU3-filter-contrast-0-G' type='linear' slope='1.5' intercept='-.3'/%3E%3CfeFuncB id='eproXtLa4JU3-filter-contrast-0-B' type='linear' slope='1.5' intercept='-.3'/%3E%3C/feComponentTransfer%3E%3CfeGaussianBlur id='eproXtLa4JU3-filter-blur-0' stdDeviation='0,0' result='result'/%3E%3CfeComponentTransfer id='eproXtLa4JU3-filter-opacity-0' result='result'%3E%3CfeFuncA id='eproXtLa4JU3-filter-opacity-0-A' type='table' tableValues='0 0.29'/%3E%3C/feComponentTransfer%3E%3CfeComponentTransfer id='eproXtLa4JU3-filter-brightness-0' result='result'%3E%3CfeFuncR id='eproXtLa4JU3-filter-brightness-0-R' type='linear' slope='1'/%3E%3CfeFuncG id='eproXtLa4JU3-filter-brightness-0-G' type='linear' slope='1'/%3E%3CfeFuncB id='eproXtLa4JU3-filter-brightness-0-B' type='linear' slope='1'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Cfilter id='eproXtLa4JU4-filter' x='-400%25' width='600%25' y='-400%25' height='600%25'%3E%3CfeComponentTransfer id='eproXtLa4JU4-filter-contrast-0' result='result'%3E%3CfeFuncR id='eproXtLa4JU4-filter-contrast-0-R' type='linear' slope='1.5' intercept='-.3'/%3E%3CfeFuncG id='eproXtLa4JU4-filter-contrast-0-G' type='linear' slope='1.5' intercept='-.3'/%3E%3CfeFuncB id='eproXtLa4JU4-filter-contrast-0-B' type='linear' slope='1.5' intercept='-.3'/%3E%3C/feComponentTransfer%3E%3CfeComponentTransfer id='eproXtLa4JU4-filter-opacity-0' result='result'%3E%3CfeFuncA id='eproXtLa4JU4-filter-opacity-0-A' type='table' tableValues='0 1'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3C/defs%3E%3Cg id='eproXtLa4JU2' transform='matrix(.13 0 0 .13 30.1 -.5)' stroke-width='12.5' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='1'%3E%3Cpath id='eproXtLa4JU3' style='mix-blend-mode:screen' d='M99.6 29.7c10.9-13.3 25.3-25.3 43-27.6a46.2 46.2 0 0 1 45.6 23 53 53 0 0 1 0 52.4c-15.2 25.5-38 45.2-59.5 65.3l-29 26.5m0-139.6C88.7 16.4 74.2 4.4 56.6 2.1a46.2 46.2 0 0 0-45.7 23 53 53 0 0 0 0 52.4c15.3 25.5 38 45.2 59.6 65.3l29 26.5' transform='translate(-206.3 43.2)' filter='url(%23eproXtLa4JU3-filter)' fill='url(%23eproXtLa4JU3-fill)' stroke='%23FFF'/%3E%3Cpath id='eproXtLa4JU4' d='M99.6 29.7c10.9-13.3 25.3-25.3 43-27.6a46.2 46.2 0 0 1 45.6 23 53 53 0 0 1 0 52.4c-15.2 25.5-38 45.2-59.5 65.3l-29 26.6m0-139.7C88.7 16.4 74.2 4.4 56.6 2.1a46.2 46.2 0 0 0-45.7 23 53 53 0 0 0 0 52.4c15.3 25.5 38 45.2 59.6 65.3l29 26.6' transform='translate(-206.3 43.2)' filter='url(%23eproXtLa4JU4-filter)' fill='url(%23eproXtLa4JU4-fill)' stroke='%23FEFEFE'/%3E%3C/g%3E%3Cscript%3E%3C!%5BCDATA%5B(function(s,i,u,o,w,d,t,n,x,e,p)%7Bw%5Bo%5D=w%5Bo%5D%7C%7C%7B%7D;w%5Bo%5D%5Bs%5D=w%5Bo%5D%5Bs%5D%7C%7C%5B%5D;w%5Bo%5D%5Bs%5D.push(i);e=d.createElementNS(n,t);e.async=true;e.setAttributeNS(x,'href',%5Bu,s,'.','j','s'%5D.join(''));e.setAttributeNS(null,'src',%5Bu,s,'.','j','s'%5D.join(''));p=d.getElementsByTagName(t)%5B0%5D;p.parentNode.insertBefore(e,p);%7D)('91c80d77',%7B'root':'eproXtLa4JU1','animations':%5B%7B'elements':%7B'eproXtLa4JU3':%7B'opacity':%5B%7B't':0,'v':1,'e':%5B0.645,0.045,0.355,1%5D%7D,%7B't':598.8023952095809,'v':1%7D%5D,'%23filter':%7B'keys':%5B%7B't':0,'v':%5B%7B'type':'contrast','value':1.5%7D,%7B'type':'blur','value':%7B'x':0,'y':0%7D%7D,%7B'type':'opacity','value':0.29%7D,%7B'type':'brightness','value':1%7D%5D,'e':%5B0.645,0.045,0.355,1%5D%7D,%7B't':598.8023952095809,'v':%5B%7B'type':'contrast','value':1.5%7D,%7B'type':'blur','value':%7B'x':18,'y':18%7D%7D,%7B'type':'opacity','value':1.0129511443425883%7D,%7B'type':'brightness','value':1.4%7D%5D%7D%5D,'data':%7B'items':%5B%5B'contrast','eproXtLa4JU3-filter-contrast-0'%5D,%5B'blur','eproXtLa4JU3-filter-blur-0'%5D,%5B'opacity','eproXtLa4JU3-filter-opacity-0'%5D,%5B'brightness','eproXtLa4JU3-filter-brightness-0'%5D%5D%7D%7D,'fill':%5B%7B't':0,'v':%7B't':'g','v':%5B%7B'r':255,'g':255,'b':255,'a':0%7D,%7B'r':255,'g':255,'b':255,'a':0%7D%5D,'r':'eproXtLa4JU3-fill'%7D%7D,%7B't':598.8023952095809,'v':%7B't':'g','v':%5B%7B'r':255,'g':255,'b':255,'a':1%7D,%7B'r':211,'g':211,'b':211,'a':1%7D%5D,'r':'eproXtLa4JU3-fill'%7D%7D%5D%7D,'eproXtLa4JU4':%7B'fill':%5B%7B't':0,'v':%7B't':'g','v':%5B%7B'r':255,'g':255,'b':255,'a':0%7D,%7B'r':122,'g':122,'b':122,'a':0%7D%5D,'r':'eproXtLa4JU4-fill'%7D%7D,%7B't':598.8023952095809,'v':%7B't':'g','v':%5B%7B'r':255,'g':255,'b':255,'a':0%7D,%7B'r':255,'g':255,'b':255,'a':0.8%7D%5D,'r':'eproXtLa4JU4-fill'%7D%7D%5D%7D%7D,'s':'MDLA2M2NiNzJiNDGM1YzJiMWM0YUmI5SGJmYmVWKNzI4YTg1ODNk4ODdlODg4MPDgyODM4OTg1HVDgyODA4OTgS1ODg4MDg4N2GM3MmI0YjljMGmI1YjNjNGI5DYmZiZTcyOGEP4MTdjNzJiOWBM0YjVjMmIxTR2M0YjliZmJlLVWMzNzI4YTgFxN2M3MmI2YjJliY2JjNzI4YDTgxN2M3MmIxNYmNjNGI1YzJJiZUZiMVhjNGPI1NzI4YWI2YEjFiY2MzUGI1VN2M3MmMzYzBCKYjViNWI0SzGcySThhODFCNT2U4Njg3Y2Q/I'%7D%5D,'options':'MDMAyMzhmMzY4NNzg4NzU4Njg4MMzY0ZTM2NzcK4MDdkNzc3ZjLM2NDAzNjc3OQDA3ZDc3N2YzNNjRlMzY4NjcE5OGE3OTg2ODJc3OTM2OTE/'%7D,'https://cdn.svgator.com/ply/','__SVGATOR_PLAYER__',window,document,'script','http://www.w3.org/2000/svg','http://www.w3.org/1999/xlink')%5D%5D%3E%3C/script%3E%3C/svg%3E%0A";
</script>
</body>
</html>
上面的代码给我一个 JS 错误 阅读 Uncaught TypeError: Cannot set properties of null (setting 'data') .
有没有办法避免这个错误,我在上面链接的尝试中是否还有其他明显的错误?
在第二种情况下,您的 CSS 选择器与您的层次结构不匹配。
在第一个(工作)案例中我们有
.rocketContainer img
在这里我们需要找到一个 class 名称为 .rocketContainer 的对象,然后寻找任何带有 img 标签的后代。有其中之一,所以我们找到了它。
在第二种情况下我们有
.likeButtonInject object data
因此我们再次寻找具有特定 class 名称的元素,但随后我们需要找到所有属于对象标签的后代。有 none 因为名称为 class 的元素没有子元素。除此之外,我们将寻找那些 none 现有对象标签的数据元素后代,但数据是对象标签的一个属性,而不是一个元素。
在这种情况下只是
.likeButtonInject
自己会做。
我在 kirupa.com 上找到了一个 simple tutorial,展示了如何使用 JS 将外部 SVG 注入 empty img 元素 在 HTML.
<html>
<head>
<style>
.rocketContainer {
background-color: #FFEB3B;
width: 100px;
height: 100px;
display: flex;
align-content: center;
justify-content: center;
}
.rocketContainer img {
width: 50px;
}
</style>
</head>
<body>
<div class="rocketContainer">
<img/>
</div>
<script>
var imageElement = document.querySelector(".rocketContainer img");
imageElement.src = "https://www.kirupa.com/images/rocket.svg";
</script>
</body>
</html>
但我需要使用对象元素,而不是 img 元素,因为我的 SVG 通过点击使用 JS 进行动画处理。我已经将我的 SVG 转换为数据 URIs/URLs 并在对象元素的数据属性中使用它们,但我在一页上重复使用它们超过六十次,并且相信将它们注入 HTML通过 JS 将有助于加载时间和性能。
Here's a CodePen link w/ my unsuccessful stab 修改上面的代码以使用对象而不是元素。如果有效,它将在右侧的框中显示相同的 SVG。核心代码复制如下。
<html>
<body>
<!-- Test Object with Empty data -->
<object class="likeButtonInject" type="image/svg+xml" data="">
</object>
<script>
var likeButtonObjectElement = document.querySelector(".likeButtonInject object data");
likeButtonObjectElement.data = "data:image/svg+xml,%3Csvg id='eproXtLa4JU1'
xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32.5 32.5' shape-rendering='geometricPrecision' text-rendering='geometricPrecision'%3E%3Cdefs%3E%3CradialGradient id='eproXtLa4JU3-fill' cx='0' cy='0' r='95.5' spreadMethod='pad' gradientUnits='userSpaceOnUse' gradientTransform='translate(99.6 85.5)'%3E%3Cstop id='eproXtLa4JU3-fill-0' offset='0%25' stop-color='rgba(255,255,255,0)'/%3E%3Cstop id='eproXtLa4JU3-fill-1' offset='100%25' stop-color='rgba(255,255,255,0)'/%3E%3C/radialGradient%3E%3CradialGradient id='eproXtLa4JU4-fill' cx='0' cy='0' r='176.8' spreadMethod='pad' gradientUnits='userSpaceOnUse' gradientTransform='rotate(45.1 -53.2 162.8)'%3E%3Cstop id='eproXtLa4JU4-fill-0' offset='0%25' stop-color='rgba(255,255,255,0)'/%3E%3Cstop id='eproXtLa4JU4-fill-1' offset='100%25' stop-color='rgba(122,122,122,0)'/%3E%3C/radialGradient%3E%3Cfilter id='eproXtLa4JU3-filter' x='-400%25' width='600%25' y='-400%25' height='600%25'%3E%3CfeComponentTransfer id='eproXtLa4JU3-filter-contrast-0' result='result'%3E%3CfeFuncR id='eproXtLa4JU3-filter-contrast-0-R' type='linear' slope='1.5' intercept='-.3'/%3E%3CfeFuncG id='eproXtLa4JU3-filter-contrast-0-G' type='linear' slope='1.5' intercept='-.3'/%3E%3CfeFuncB id='eproXtLa4JU3-filter-contrast-0-B' type='linear' slope='1.5' intercept='-.3'/%3E%3C/feComponentTransfer%3E%3CfeGaussianBlur id='eproXtLa4JU3-filter-blur-0' stdDeviation='0,0' result='result'/%3E%3CfeComponentTransfer id='eproXtLa4JU3-filter-opacity-0' result='result'%3E%3CfeFuncA id='eproXtLa4JU3-filter-opacity-0-A' type='table' tableValues='0 0.29'/%3E%3C/feComponentTransfer%3E%3CfeComponentTransfer id='eproXtLa4JU3-filter-brightness-0' result='result'%3E%3CfeFuncR id='eproXtLa4JU3-filter-brightness-0-R' type='linear' slope='1'/%3E%3CfeFuncG id='eproXtLa4JU3-filter-brightness-0-G' type='linear' slope='1'/%3E%3CfeFuncB id='eproXtLa4JU3-filter-brightness-0-B' type='linear' slope='1'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Cfilter id='eproXtLa4JU4-filter' x='-400%25' width='600%25' y='-400%25' height='600%25'%3E%3CfeComponentTransfer id='eproXtLa4JU4-filter-contrast-0' result='result'%3E%3CfeFuncR id='eproXtLa4JU4-filter-contrast-0-R' type='linear' slope='1.5' intercept='-.3'/%3E%3CfeFuncG id='eproXtLa4JU4-filter-contrast-0-G' type='linear' slope='1.5' intercept='-.3'/%3E%3CfeFuncB id='eproXtLa4JU4-filter-contrast-0-B' type='linear' slope='1.5' intercept='-.3'/%3E%3C/feComponentTransfer%3E%3CfeComponentTransfer id='eproXtLa4JU4-filter-opacity-0' result='result'%3E%3CfeFuncA id='eproXtLa4JU4-filter-opacity-0-A' type='table' tableValues='0 1'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3C/defs%3E%3Cg id='eproXtLa4JU2' transform='matrix(.13 0 0 .13 30.1 -.5)' stroke-width='12.5' stroke-linecap='round' stroke-linejoin='round' stroke-miterlimit='1'%3E%3Cpath id='eproXtLa4JU3' style='mix-blend-mode:screen' d='M99.6 29.7c10.9-13.3 25.3-25.3 43-27.6a46.2 46.2 0 0 1 45.6 23 53 53 0 0 1 0 52.4c-15.2 25.5-38 45.2-59.5 65.3l-29 26.5m0-139.6C88.7 16.4 74.2 4.4 56.6 2.1a46.2 46.2 0 0 0-45.7 23 53 53 0 0 0 0 52.4c15.3 25.5 38 45.2 59.6 65.3l29 26.5' transform='translate(-206.3 43.2)' filter='url(%23eproXtLa4JU3-filter)' fill='url(%23eproXtLa4JU3-fill)' stroke='%23FFF'/%3E%3Cpath id='eproXtLa4JU4' d='M99.6 29.7c10.9-13.3 25.3-25.3 43-27.6a46.2 46.2 0 0 1 45.6 23 53 53 0 0 1 0 52.4c-15.2 25.5-38 45.2-59.5 65.3l-29 26.6m0-139.7C88.7 16.4 74.2 4.4 56.6 2.1a46.2 46.2 0 0 0-45.7 23 53 53 0 0 0 0 52.4c15.3 25.5 38 45.2 59.6 65.3l29 26.6' transform='translate(-206.3 43.2)' filter='url(%23eproXtLa4JU4-filter)' fill='url(%23eproXtLa4JU4-fill)' stroke='%23FEFEFE'/%3E%3C/g%3E%3Cscript%3E%3C!%5BCDATA%5B(function(s,i,u,o,w,d,t,n,x,e,p)%7Bw%5Bo%5D=w%5Bo%5D%7C%7C%7B%7D;w%5Bo%5D%5Bs%5D=w%5Bo%5D%5Bs%5D%7C%7C%5B%5D;w%5Bo%5D%5Bs%5D.push(i);e=d.createElementNS(n,t);e.async=true;e.setAttributeNS(x,'href',%5Bu,s,'.','j','s'%5D.join(''));e.setAttributeNS(null,'src',%5Bu,s,'.','j','s'%5D.join(''));p=d.getElementsByTagName(t)%5B0%5D;p.parentNode.insertBefore(e,p);%7D)('91c80d77',%7B'root':'eproXtLa4JU1','animations':%5B%7B'elements':%7B'eproXtLa4JU3':%7B'opacity':%5B%7B't':0,'v':1,'e':%5B0.645,0.045,0.355,1%5D%7D,%7B't':598.8023952095809,'v':1%7D%5D,'%23filter':%7B'keys':%5B%7B't':0,'v':%5B%7B'type':'contrast','value':1.5%7D,%7B'type':'blur','value':%7B'x':0,'y':0%7D%7D,%7B'type':'opacity','value':0.29%7D,%7B'type':'brightness','value':1%7D%5D,'e':%5B0.645,0.045,0.355,1%5D%7D,%7B't':598.8023952095809,'v':%5B%7B'type':'contrast','value':1.5%7D,%7B'type':'blur','value':%7B'x':18,'y':18%7D%7D,%7B'type':'opacity','value':1.0129511443425883%7D,%7B'type':'brightness','value':1.4%7D%5D%7D%5D,'data':%7B'items':%5B%5B'contrast','eproXtLa4JU3-filter-contrast-0'%5D,%5B'blur','eproXtLa4JU3-filter-blur-0'%5D,%5B'opacity','eproXtLa4JU3-filter-opacity-0'%5D,%5B'brightness','eproXtLa4JU3-filter-brightness-0'%5D%5D%7D%7D,'fill':%5B%7B't':0,'v':%7B't':'g','v':%5B%7B'r':255,'g':255,'b':255,'a':0%7D,%7B'r':255,'g':255,'b':255,'a':0%7D%5D,'r':'eproXtLa4JU3-fill'%7D%7D,%7B't':598.8023952095809,'v':%7B't':'g','v':%5B%7B'r':255,'g':255,'b':255,'a':1%7D,%7B'r':211,'g':211,'b':211,'a':1%7D%5D,'r':'eproXtLa4JU3-fill'%7D%7D%5D%7D,'eproXtLa4JU4':%7B'fill':%5B%7B't':0,'v':%7B't':'g','v':%5B%7B'r':255,'g':255,'b':255,'a':0%7D,%7B'r':122,'g':122,'b':122,'a':0%7D%5D,'r':'eproXtLa4JU4-fill'%7D%7D,%7B't':598.8023952095809,'v':%7B't':'g','v':%5B%7B'r':255,'g':255,'b':255,'a':0%7D,%7B'r':255,'g':255,'b':255,'a':0.8%7D%5D,'r':'eproXtLa4JU4-fill'%7D%7D%5D%7D%7D,'s':'MDLA2M2NiNzJiNDGM1YzJiMWM0YUmI5SGJmYmVWKNzI4YTg1ODNk4ODdlODg4MPDgyODM4OTg1HVDgyODA4OTgS1ODg4MDg4N2GM3MmI0YjljMGmI1YjNjNGI5DYmZiZTcyOGEP4MTdjNzJiOWBM0YjVjMmIxTR2M0YjliZmJlLVWMzNzI4YTgFxN2M3MmI2YjJliY2JjNzI4YDTgxN2M3MmIxNYmNjNGI1YzJJiZUZiMVhjNGPI1NzI4YWI2YEjFiY2MzUGI1VN2M3MmMzYzBCKYjViNWI0SzGcySThhODFCNT2U4Njg3Y2Q/I'%7D%5D,'options':'MDMAyMzhmMzY4NNzg4NzU4Njg4MMzY0ZTM2NzcK4MDdkNzc3ZjLM2NDAzNjc3OQDA3ZDc3N2YzNNjRlMzY4NjcE5OGE3OTg2ODJc3OTM2OTE/'%7D,'https://cdn.svgator.com/ply/','__SVGATOR_PLAYER__',window,document,'script','http://www.w3.org/2000/svg','http://www.w3.org/1999/xlink')%5D%5D%3E%3C/script%3E%3C/svg%3E%0A";
</script>
</body>
</html>
上面的代码给我一个 JS 错误 阅读 Uncaught TypeError: Cannot set properties of null (setting 'data') .
有没有办法避免这个错误,我在上面链接的尝试中是否还有其他明显的错误?
在第二种情况下,您的 CSS 选择器与您的层次结构不匹配。
在第一个(工作)案例中我们有
.rocketContainer img
在这里我们需要找到一个 class 名称为 .rocketContainer 的对象,然后寻找任何带有 img 标签的后代。有其中之一,所以我们找到了它。
在第二种情况下我们有
.likeButtonInject object data
因此我们再次寻找具有特定 class 名称的元素,但随后我们需要找到所有属于对象标签的后代。有 none 因为名称为 class 的元素没有子元素。除此之外,我们将寻找那些 none 现有对象标签的数据元素后代,但数据是对象标签的一个属性,而不是一个元素。
在这种情况下只是
.likeButtonInject
自己会做。