特にこれといって使うシーンもないですが、夏休みの自由研究的なノリで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 さんコードレビューありがとうございました!