SVG 提供了多种方式来实现交互功能,使其成为创建交互式图形的强大工具:
1. 事件监听 SVG 元素支持标准 DOM 事件,可以直接在 SVG 元素上添加事件监听器。
HTML 属性方式:
svg<svg width="200" height="200"> <circle cx="100" cy="100" r="50" fill="blue" onclick="handleClick()" onmouseover="handleMouseOver()" onmouseout="handleMouseOut()" /> </svg> <script> function handleClick() { console.log('Circle clicked!'); } function handleMouseOver() { console.log('Mouse over circle'); } function handleMouseOut() { console.log('Mouse out of circle'); } </script>
JavaScript addEventListener 方式:
javascriptconst circle = document.querySelector('circle'); circle.addEventListener('click', function() { this.setAttribute('fill', 'red'); }); circle.addEventListener('mouseover', function() { this.setAttribute('fill', 'green'); }); circle.addEventListener('mouseout', function() { this.setAttribute('fill', 'blue'); });
2. CSS 交互 使用 CSS 的伪类和过渡效果实现交互。
svg<svg width="200" height="200"> <style> .interactive-circle { fill: blue; transition: all 0.3s ease; cursor: pointer; } .interactive-circle:hover { fill: red; r: 60; } .interactive-circle:active { fill: green; } </style> <circle class="interactive-circle" cx="100" cy="100" r="50" /> </svg>
3. JavaScript 动态操作 通过 JavaScript 动态修改 SVG 属性和样式。
javascript// 修改属性 const circle = document.querySelector('circle'); circle.setAttribute('cx', '150'); circle.setAttribute('fill', 'purple'); // 修改样式 circle.style.fill = 'orange'; circle.style.opacity = '0.5'; // 添加新元素 const svg = document.querySelector('svg'); const newCircle = document.createElementNS('http://www.w3.org/2000/svg', 'circle'); newCircle.setAttribute('cx', '50'); newCircle.setAttribute('cy', '50'); newCircle.setAttribute('r', '30'); newCircle.setAttribute('fill', 'yellow'); svg.appendChild(newCircle);
4. 拖拽交互 实现 SVG 元素的拖拽功能。
javascriptlet selectedElement = null; let offset = { x: 0, y: 0 }; function getMousePosition(evt) { const CTM = svg.getScreenCTM(); return { x: (evt.clientX - CTM.e) / CTM.a, y: (evt.clientY - CTM.f) / CTM.d }; } function startDrag(evt) { selectedElement = evt.target; offset = getMousePosition(evt); offset.x -= parseFloat(selectedElement.getAttribute('cx')); offset.y -= parseFloat(selectedElement.getAttribute('cy')); } function drag(evt) { if (selectedElement) { evt.preventDefault(); const coord = getMousePosition(evt); selectedElement.setAttribute('cx', coord.x - offset.x); selectedElement.setAttribute('cy', coord.y - offset.y); } } function endDrag(evt) { selectedElement = null; } const svg = document.querySelector('svg'); svg.addEventListener('mousedown', startDrag); svg.addEventListener('mousemove', drag); svg.addEventListener('mouseup', endDrag); svg.addEventListener('mouseleave', endDrag);
5. 动画交互 结合动画和交互实现更复杂的效果。
javascriptconst circle = document.querySelector('circle'); circle.addEventListener('click', function() { this.style.transition = 'all 0.5s ease'; this.style.transform = 'scale(1.5)'; setTimeout(() => { this.style.transform = 'scale(1)'; }, 500); });
6. 可访问性交互 为 SVG 添加可访问性支持。
svg<svg width="200" height="200" role="img" aria-labelledby="svg-title svg-desc"> <title id="svg-title">交互式圆形</title> <desc id="svg-desc">点击圆形可以改变颜色</desc> <circle cx="100" cy="100" r="50" fill="blue" tabindex="0" onclick="changeColor(this)" onkeydown="handleKeydown(event, this)" /> </svg> <script> function changeColor(element) { const colors = ['blue', 'red', 'green', 'yellow', 'purple']; const currentColor = element.getAttribute('fill'); const currentIndex = colors.indexOf(currentColor); const nextIndex = (currentIndex + 1) % colors.length; element.setAttribute('fill', colors[nextIndex]); } function handleKeydown(event, element) { if (event.key === 'Enter' || event.key === ' ') { event.preventDefault(); changeColor(element); } } </script>
最佳实践:
- 优先使用 CSS 实现简单交互
- 复杂交互使用 JavaScript
- 添加适当的可访问性支持
- 考虑移动端触摸事件
- 优化性能,避免频繁的 DOM 操作