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

ExtJS 4.2柱状图:如何实现Tab键遍历柱状条功能?

实现ExtJS 4.2柱状图的Tab键遍历柱状条功能

你的问题在于给整个图表容器添加了tabIndex,但Tab遍历需要作用在每个柱状条的DOM元素上。ExtJS 4.2的图表基于SVG/VML渲染,每个柱状条是独立的图形节点,需要单独处理:

具体实现思路

  • 在afterrender监听器中,定位到柱状图系列的DOM元素组
  • 遍历每个柱状条元素,设置tabindex="0"使其可被Tab聚焦
  • 添加焦点事件触发柱状条高亮,添加键盘事件支持方向键切换焦点(可选)

修改后的完整代码

Ext.onReady(function() {
    var store = Ext.create('Ext.data.JsonStore', {
        fields: ['name', 'data'],
        data: [
            { 'name': 'metric one',   'data':10 },
            { 'name': 'metric two',   'data': 7 },
            { 'name': 'metric three', 'data': 5 },
            { 'name': 'metric four',  'data': 2 },
            { 'name': 'metric five',  'data':27 }
        ]
    });

    Ext.create('Ext.chart.Chart', {
        renderTo: Ext.getBody(),
        width: 500,
        height: 300,
        arialabel:'Sample chart',
        animate: true,
        store: store,
        axes: [{
            type: 'Numeric',
            position: 'bottom',
            fields: ['data'],
            label: {
                renderer: Ext.util.Format.numberRenderer('0,0')
            },
            title: 'Sample Values',
            grid: true,
            minimum: 0
        }, {
            type: 'Category',
            position: 'left',
            fields: ['name'],
            title: 'Sample Metrics'
        }],
        listeners:{
            afterrender:function(chart) {
                // 获取柱状图系列的图形组元素
                var series = chart.series.items[0];
                var groupEl = series.groupEl;
                var barElements = groupEl.dom.childNodes;

                // 遍历每个柱状条元素
                Ext.Array.each(barElements, function(el, index) {
                    var barEl = Ext.get(el);
                    // 设置tabindex使其可聚焦,同时添加无障碍标签
                    barEl.set({
                        tabindex: '0',
                        'aria-label': store.getAt(index).get('name') + ': ' + store.getAt(index).get('data')
                    });

                    // 焦点事件:触发柱状条高亮并显示提示框
                    barEl.on('focus', function() {
                        series.highlightItem({index: index});
                        series.tips.show(series.items[index]);
                    });

                    // 失焦事件:取消高亮并隐藏提示框
                    barEl.on('blur', function() {
                        series.unHighlightItem();
                        series.tips.hide();
                    });

                    // 键盘事件:支持方向键切换焦点,回车触发自定义操作
                    barEl.on('keydown', function(e) {
                        var nextIndex;
                        if (e.getKey() === e.RIGHT || e.getKey() === e.DOWN) {
                            nextIndex = index + 1;
                            nextIndex = nextIndex >= barElements.length ? 0 : nextIndex;
                        } else if (e.getKey() === e.LEFT || e.getKey() === e.UP) {
                            nextIndex = index - 1;
                            nextIndex = nextIndex < 0 ? barElements.length - 1 : nextIndex;
                        } else if (e.getKey() === e.ENTER) {
                            console.log('选中柱状条:' + store.getAt(index).get('name'));
                            return;
                        } else {
                            return;
                        }
                        // 切换到目标柱状条的焦点
                        Ext.get(barElements[nextIndex]).focus();
                    });
                });
            }
        },
        series: [{
            type: 'bar',
            axis: 'bottom',
            highlight: true,
            tips: {
                trackMouse: true,
                width: 140,
                height: 28,
                renderer: function(storeItem, item) {
                    this.setTitle(storeItem.get('name') + ': ' + storeItem.get('data') + ' views');
                }
            },
            label: {
                display: 'insideEnd',
                field: 'data',
                renderer: Ext.util.Format.numberRenderer('0'),
                orientation: 'horizontal',
                color: '#333',
                'text-anchor': 'middle'
            },
            xField: 'name',
            yField: 'data'
        }]
    });
});

关键细节说明

  1. 定位柱状条元素:通过chart.series.items[0].groupEl获取整个柱状系列的DOM容器,其下的子节点对应每个独立柱状条。
  2. 无障碍优化:给每个柱状条添加aria-label,确保屏幕阅读器能正确朗读柱子的名称和数值。
  3. 交互体验增强:关联焦点/失焦事件与高亮、提示框逻辑,方向键切换焦点让键盘操作更流畅。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 22:02:45