LoginSignup
1
0

More than 1 year has passed since last update.

アクセシブルネームを取得するjQueryプラグイン

Last updated at Posted at 2019-06-12

MIT License Published on NPM

特にこれといって使うシーンもないですが、夏休みの自由研究的なノリでTypeScriptに書き直して公開しました😂

文中ではlabel要素をDOM探索で取得していますが、フォーム関連要素のlabelsというプロパティからNodeListOf<HTMLLabelElement>が取得できます👀
恥ずかしながら、このタイミングで改めてHTMLInputElementのインターフェース等々を読み返したことで気づきました笑

やっぱりこういう機会を産んでくれるところも、自分が昔書いたコードを見直すのって大切なことだと思います( ˘ω˘ )

追記:2021/07/23


とても久しぶりにjQueryを書くことになったので、
アクセシブルネームを取得するようなものを作ってみたり(何に使うんだ)。

/**
 * @see http://jquery.com/
 * @name fn
 * @class jQuery Library
 * @memberOf jQuery
 */

/**
 * 要素のアクセシブルネームを取得します
 * https://qiita.com/heppokofrontend/items/7e5d6d69893828cbf17e#comment-bc346c926f023fc5ac70
 * @return {string} 取得したアクセシブルネーム
 * @memberOf jQuery.fn
 * @license WTFPL 
 */
$.fn.getA11yName = function () {
    /**
     * @param {object} $self - jQueryオブジェクト
     * @return {string} aria-labelledby経由で取得を試みたアクセシブルネーム
     */
    const getAriaLabelledBy = ($self) => {
        const idList = $.trim($self.attr('aria-labelledby')).split(/\s/);
        let result = '';

        for (const id of idList) {
            result += `${$(document.getElementById(id)).text().trim()} `;
        }

        return result.trim();
    };
    /**
     * @param {object} $self - jQueryオブジェクト
     * @return {string} label要素経由で取得を試みたアクセシブルネーム
     */
    const getLabelElementTextContent = ($self) => {
        let result = '';
        const $allElm = $(document.getElementsByTagName('*'));
        const $closestLabel = $self.closest('label');
        const id = $self.attr('id');
        const labels = [];

        // 祖先のlabel要素
        if ($closestLabel.length) {
            labels.push({
                idx: $allElm.index($closestLabel),
                $node: $closestLabel.eq(0)
            });
        }

        // 祖先意外のlabel要素
        if (id) {
            const $labelingByForAttr = $(document.querySelectorAll(`label[for="${id}"]`));

            $labelingByForAttr.each(function () {
                const $label = $(this);

                labels.push({
                    idx: $allElm.index($label),
                    $node: $label
                });
            });
        }

        // 登場順に整理
        labels.sort(({idx: a}, {idx: b}) => a - b);

        for (const obj of labels) {
            result += `${obj.$node.text().trim()} `;
        }

        result = result.trim();

        // 結果的に中身が空でもlabel要素が見つかっていれば、
        // title属性を参照させないように空白文字を返す
        return result || (labels.length ? ' ' : '');
    };
    let result = '';

    this.each(function () {
        const $self = $(this);

        // アクセシブルネームの取得優先順に検証する
        result += (getAriaLabelledBy($self) || $self.attr('aria-label') || getLabelElementTextContent($self) || $self.attr('title') || '');
    });

    return result.trim();
};

使用方法

$('input').getA11yName(); // すべてのinput要素のアクセシブルネームを取得
$('input').eq(0).getA11yName(); // 1つのinput要素のアクセシブルネームを取得

謝辞

@htsign さんコードレビューありがとうございました!

1
0
6

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0