首页 > 解决方案 > 有没有办法让 SVG className 向后兼容?

问题描述

许多旧库依赖 className 来识别它们的上下文。

所以点击处理程序可以如下所示:

function click(event)
{
   if (event.target.className.indexOf('something')!= -1){
       // Do something
   }
}

但如果目标元素是 svg 元素,这将失败。原因是 svg className 是SVGAnimatedString类型的对象

是否有任何临时解决方法可以避免旧代码出现问题?更改处理程序不是一种选择,因为不清楚有多少库具有此代码,并且更改库代码可能是不可能的。

将 SVG 更改为其他元素不是一种选择,因为 SVG 是第 3 方控件的一部分。

更新:

“是否有任何临时解决方法可以避免旧代码出现问题?” 根据评论似乎不清楚。我的目标是查看是否有任何 polyfill 或任何其他技术可用于临时使 SVG 元素将其 className 作为字符串,直到 3rd 方库赶上。然后我将更新 3rd 方库并还原此代码。

截至目前 - 简单地覆盖 className 似乎是不可能的,因为它似乎只有 getter 而没有用于 SVG 元素的 setter。

function oldModuleHandler(e) {
  if (e.className.indexOf("initial") > -1 || e.className.indexOf("fixed") > -1) {
    alert('Behaves as expected.');
  }
}

function theFix(e) {
  e.className = "fixed";
}
<html>

<head>

</head>

<body>

  <div style="border:2px solid silver;">
    <h2>Demo:</h2>
    Click on the left square, it is a div and it will have it's color changed to green because .className.indexOf will go through just fine. Same does not apply for SVG.<br/> <br/><br/>
    <div onclick="theFix(this); oldModuleHandler(this)" class="initial">
    </div>

    <svg class="initial" onclick="theFix(this); oldModuleHandler(this)"></svg>
    <div style="clear:both;"></div>
  </div>
  <style>
    .fixed {
      background: green !important;
      width: 80px;
      height: 80px;
      float: left;
    }
    
    .initial {
      background: transparent;
      border: 1px solid black;
      width: 80px;
      height: 80px;
      float: left;
    }
  </style>
</body>

</html>

更新 2 我添加了一个小代码来演示这个问题。如果你点击左边的方块(它是一个 div)——它会工作得很好。如果你点击右边的方块——SVG——它不会起作用,因为 .className.indexOf() 会抛出一个错误。

标签: javascriptsvgpolyfillsvuesax

解决方案


您可以使用getAttributeand setAttributeOR 'classList方法:

function oldModuleHandler(e) {
  var c = e.getAttribute('class');
  if (~c.indexOf("initial") || ~c.indexOf("fixed")) {
    alert('Behaves as expected.');
  }
}

function theFix(e) {
  e.className = "fixed";
  e.setAttribute('class', 'fixed')
  // OR 
  e.classList.add('fixed')
}
.fixed {
      background: green !important;
      width: 80px;
      height: 80px;
      float: left;
    }
    
    .initial {
      background: transparent;
      border: 1px solid black;
      width: 80px;
      height: 80px;
      float: left;
    }
<div style="border:2px solid silver;">
    <h2>Demo:</h2>
    Click on the left square, it is a div and it will have it's color changed to green because .className.indexOf will go through just fine. Same does not apply for SVG.<br/> <br/><br/>
    <div onclick="theFix(this); oldModuleHandler(this)" class="initial">
    </div>

    <svg class="initial" onclick="theFix(this); oldModuleHandler(this)"></svg>
    <div style="clear:both;"></div>
  </div>

和/或查看Proxy API.


推荐阅读