You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

StencilJS新手求助:实现支持HTML的居中Tooltip功能

StencilJS 条形图 Tooltip 解决方案

核心实现思路

  1. 条件渲染:依据tooltip字段是否为空,决定是否渲染Tooltip元素
  2. 居中布局:通过CSS绝对定位+transform实现Tooltip在条形容器内精准居中
  3. HTML解析:利用Stencil的innerHTML属性绑定HTML字符串,同时注意内容安全(若内容来自用户输入需做转义处理)
  4. 可选Slot方案:若需更灵活的Tooltip内容自定义,可结合Slot实现复杂交互

完整代码示例

1. 条形图组件(bar-chart.tsx)

import { Component, Prop, h } from '@stencil/core';

interface BarData {
  value: number;
  color: string;
  tooltip: string;
}

@Component({
  tag: 'bar-chart',
  styleUrl: 'bar-chart.css',
  shadow: true,
})
export class BarChart {
  @Prop() data: BarData[] = [];

  render() {
    return (
      <div class="bar-chart-container">
        {this.data.map((bar, index) => (
          <div 
            key={index} 
            class="bar-wrapper"
            style={{ height: `${bar.value}%`, backgroundColor: bar.color }}
          >
            {/* 仅当tooltip非空时渲染 */}
            {bar.tooltip && (
              <div class="bar-tooltip" innerHTML={bar.tooltip}></div>
            )}
          </div>
        ))}
      </div>
    );
  }
}

2. 样式文件(bar-chart.css)

.bar-chart-container {
  width: 200px;
  height: 400px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 8px;
  padding: 16px;
  background-color: #f5f5f5;
}

.bar-wrapper {
  position: relative;
  width: 100%;
  transition: opacity 0.2s;
}

.bar-wrapper:hover {
  opacity: 0.8;
}

.bar-tooltip {
  position: absolute;
  /* 水平垂直居中 */
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  /* 基础样式 */
  padding: 6px 12px;
  background-color: rgba(0, 0, 0, 0.8);
  color: #fff;
  border-radius: 4px;
  font-size: 14px;
  z-index: 10;
  /* 兼容HTML标签样式 */
  span {
    color: #69c0f9;
    font-weight: bold;
  }
}

3. 组件调用示例

<bar-chart 
  data={[
    { value: 50.5, color: "#2c8646", tooltip: "Done" },
    { value: 30, color: "#69c0f9", tooltip: "" },
    { value: 10, color: "#e03021", tooltip: "Have data:<span>12</span>" },
  ]}
></bar-chart>

Slot方案(适配复杂自定义内容)

如果需要在Tooltip中加入按钮、图标等交互元素,可改用Slot实现:

修改条形图组件的渲染逻辑

// 替换bar-chart.tsx中的map渲染部分
{this.data.map((bar, index) => (
  <div 
    key={index} 
    class="bar-wrapper"
    style={{ height: `${bar.value}%`, backgroundColor: bar.color }}
  >
    {bar.tooltip || this.el.querySelector(`[slot="tooltip-${index}"]`) ? (
      <div class="bar-tooltip">
        <slot name={`tooltip-${index}`}>{bar.tooltip}</slot>
      </div>
    ) : null}
  </div>
))}

Slot方式调用组件

<bar-chart 
  data={[
    { value: 50.5, color: "#2c8646", tooltip: "Done" },
    { value: 30, color: "#69c0f9", tooltip: "" },
    { value: 10, color: "#e03021", tooltip: "" },
  ]}
>
  {/* 给第三个条形自定义带交互的Tooltip */}
  <div slot="tooltip-2">
    Have data: <span style="color:#69c0f9; font-weight:bold">12</span>
    <button style="margin-left:8px; padding:2px 6px">查看详情</button>
  </div>
</bar-chart>

关键注意事项

  • 内容安全:若tooltip内容来自用户输入,需用DOMPurify等工具做HTML转义,避免XSS攻击
  • 定位依赖:必须给.bar-wrapper设置position: relative,否则Tooltip会相对于整个文档定位
  • 响应式适配:可通过媒体查询调整Tooltip的字体大小、内边距,适配不同屏幕尺寸

内容的提问来源于stack exchange,提问作者SamGS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 10:05:23