TEST

WAI-ARIA メモ

最終更新:

eriax

- view
管理者のみ編集可

aria-controls による連動型選択肢

<!DOCTYPE html>
<title>TEST</title>

<style type="text/css">

@media screen {
  
  *[aria-hidden="true"] {
    display: none;
  }
  
  *.aria-hidden {
    display: none;
  }
  
}

</style>
<script type="text/javascript">

var _GenerateAssociation =
    function () {
        var _SetAriaHidden_Select =
            function () {
                return function SetAriaHidden_Select (select) {
                    var controls = select.getAttribute ('aria-controls');
                    
                    if (! controls) {
                        return;
                    }
                    controls = controls.split (/\s+/);
                    
                    var index = select.selectedIndex - 1;
                    var count = controls.length;
                    var d = select.ownerDocument;
                    var i;
                    var n;
                    
                    for (i = 0; i < index; ++i) {
                        n = d.getElementById (controls[i]);
                        
                        if (! n) {
                            continue;
                        }
                        if (n.getAttribute ('aria-hidden') !== 'true') {
                            n.setAttribute ('aria-hidden', 'true');
                            _AddClass (n, 'aria-hidden');
                        }
                        _SetAriaHidden_All (n, true);
                    }
                    if (index < 0) {
                        _SetAriaHidden_All (select, true);
                    }
                    else {
                        n = d.getElementById (controls[index]);
                        
                        if (n) {
                            n.setAttribute ('aria-hidden', 'false');
                            _RemoveClass (n, 'aria-hidden');
                            
                            try {
                                var e = d.createEvent ('HTMLEvents');
                                e.initEvent ('change', false, false);
                                n.dispatchEvent (e);
                            }
                            catch (err) {
                                n.fireEvent ('onchange');
                            }
                        }
                    }
                    for (i += 1; i < count; ++i) {
                        n = d.getElementById (controls[i]);
                        
                        if (! n) {
                            continue;
                        }
                        if (n.getAttribute ('aria-hidden') !== 'true') {
                            n.setAttribute ('aria-hidden', 'true');
                            _AddClass (n, 'aria-hidden');
                        }
                        _SetAriaHidden_All (n, true);
                    }
                };
            } ();
        
        var _SetAriaHidden_All =
            function () {
                return function SetAriaHidden_All (elt, hidden) {
                    var controls = elt.getAttribute ('aria-controls');
                    
                    if (! controls) {
                        return;
                    }
                    
                    controls = controls.split (/\s+/);
                    hidden = String (hidden);
                    
                    var count = controls.length;
                    var d = elt.ownerDocument;
                    var i;
                    var n;
                    
                    for (i = 0; i < count; ++i) {
                        n = d.getElementById (controls[i]);
                        
                        if (! n) {
                            continue;
                        }
                        
                        n.setAttribute ('aria-hidden', hidden);
                        _AddClass (n, 'aria-hidden');
                        
                        SetAriaHidden_All (n, hidden);
                    }
                };
            } ();
        
        var _AddClass =
            function () {
                return function AddClass (elt, className) {
                    var c = elt.className;
                    
                    k = className.replace (/\W/g, '$&');
                    
                    if (! new RegExp ('(?:^|\s)' + k + '(?:\s|$)').test (c)) {
                        c += '\x20' + className;
                        elt.className = c.replace (/^\s+|\s+$/g, '').replace (/\s+/g, '\x20');
                    }
                };
            } ();
        
        var _RemoveClass =
            function () {
                return function RemoveClass (elt, className) {
                    var c = elt.className;
                    
                    k = className.replace (/\W/g, '$&');
                    
                    if (new RegExp ('(?:^|\s)' + k + '(?:\s|$)').test (c)) {
                        c = c.replace (new RegExp (k), '');
                        elt.className = c.replace (/^\s+|\s+$/g, '').replace (/\s+/g, '\x20');
                    }
                };
            } ();
        
        return function () {
            return function GenerateAssociation (startIDs) {
                return function handleEvent (e) {
                    switch (e.type) {
                        
                    case 'load' :
                        var count = startIDs.length;
                        var d = e.target || this.document;
                        var i;
                        var c;
                        
                        for (i = 0; i < count; ++i) {
                            c = d.getElementById (startIDs[i]);
                            
                            if (c) {
                                _SetAriaHidden_All (c, true);
                                _SetAriaHidden_Select (c);
                            }
                        }
                        return;
                        
                    case 'change' :
                        var c = e.currentTarget || this;
                        _SetAriaHidden_Select (c);
                        return;
                    }
                };
            };
        } ();
    } ();

var anAssociation1 = _GenerateAssociation ([ 'start' ]);

</script>

<body onload="return anAssociation1.call (this, event);">
    
<form action="#">
  <p>
    <select id="start" aria-controls="C1 C2 C3" onchange="return anAssociation1.call (this, event);">
      <option>-</option>
      <option>Category 1</option>
      <option>Category 2</option>
      <option>Category 3</option>
    </select>
    <select id="C1" aria-controls="C1-1 C1-2 C1-3" onchange="return anAssociation1.call (this, event);">
      <option>-</option>
      <option>Category 1-1</option>
      <option>Category 1-2</option>
      <option>Category 1-3</option>
    </select>
    <select id="C1-1">
      <option>-</option>
      <option>Category 1-1-1</option>
      <option>Category 1-1-2</option>
      <option>Category 1-1-3</option>
    </select>
    <select id="C1-2">
      <option>-</option>
      <option>Category 1-2-1</option>
      <option>Category 1-2-2</option>
      <option>Category 1-2-3</option>
    </select>
    <select id="C1-3">
      <option>-</option>
      <option>Category 1-3-1</option>
      <option>Category 1-3-2</option>
      <option>Category 1-3-3</option>
    </select>
    <select id="C2" aria-controls="C2-1 C2-2 C2-3" onchange="return anAssociation1.call (this, event);">
      <option>-</option>
      <option>Category 2-1</option>
      <option>Category 2-2</option>
      <option>Category 2-3</option>
    </select>
    <select id="C2-1">
      <option>-</option>
      <option>Category 2-1-1</option>
      <option>Category 2-1-2</option>
      <option>Category 2-1-3</option>
    </select>
    <select id="C2-2">
      <option>-</option>
      <option>Category 2-2-1</option>
      <option>Category 2-2-2</option>
      <option>Category 2-2-3</option>
    </select>
    <select id="C2-3">
      <option>-</option>
      <option>Category 2-3-1</option>
      <option>Category 2-3-2</option>
      <option>Category 2-3-3</option>
    </select>
    <select id="C3" aria-controls="C3-1 C3-2 C3-3" onchange="return anAssociation1.call (this, event);">
      <option>-</option>
      <option>Category 3-1</option>
      <option>Category 3-2</option>
      <option>Category 3-3</option>
    </select>
    <select id="C3-1">
      <option>-</option>
      <option>Category 3-1-1</option>
      <option>Category 3-1-2</option>
      <option>Category 3-1-3</option>
    </select>
    <select id="C3-2">
      <option>-</option>
      <option>Category 3-2-1</option>
      <option>Category 3-2-2</option>
      <option>Category 3-2-3</option>
    </select>
    <select id="C3-3">
      <option>-</option>
      <option>Category 3-3-1</option>
      <option>Category 3-3-2</option>
      <option>Category 3-3-3</option>
    </select>
  </p>
</form>

aria-controls と aria-labelledby

<!DOCTYPE html>
<title>TEST</title>
<body>

<form action="#" onclick="

var target = event.target || event.srcElement;
var currentTarget = event.currentTarget || this;
var doc = target.ownerDocument;

switch (target.tagName) {

case 'IMG' :
    var source = target;
    var result;
    var t;
    
    for (t = target; t; t = t.parentNode) {
        result = t.getAttribute ('aria-controls');
        
        if (result) {
            result = doc.getElementById (result);
            
            if (! result) {
                break;
            }
            if (result.tagName === 'IMG') {
                result.src = source.src;
                result.alt = source.alt;
            }
            break;
        }
        if (t === currentTarget) {
            break;
        }
    }
    return;
    
case 'INPUT' :
    var sources = target.getAttribute ('aria-labelledby');
    var source;
    var results;
    var result;
    var t;
    var i;
    
    if (! sources) {
        return;
    }
    sources = sources.replace (/^\s+|\s+$/g, '').replace (/\s+/g, '\x20').split (/\x20/);
    
    for (i = 0; source = sources[i]; ++i) {
        source = doc.getElementById (source);
        sources[i] = source ? (source.tagName === 'IMG') ? source : null : null;
    }
    for (t = target; t; t = t.parentNode) {
        results = t.getAttribute ('aria-controls');
        
        if (results) {
            results = results.replace (/^\s+|\s+$/g, '').replace (/\s+/g, '\x20').split (/\x20/);
            
            for (i = 0; result = results[i]; ++i) {
                source = sources[i];
                
                if (! source) {
                    continue;
                }
                result = doc.getElementById (result);
                
                if (! result) {
                    continue;
                }
                if (result.tagName === 'IMG') {
                    result.src = source.src;
                    result.alt = source.alt;
                }
            }
        }
        if (t === currentTarget) {
            break;
        }
    }
    return;
}

">
  <fieldset>
    <legend>画像を選んで下さい</legend>
    <ul>
      <li aria-controls="A">
        <span>A グループ:</span>
        <img id="A0" src="A0.png" alt="A0">
        <img id="A1" src="A1.png" alt="A1">
        <img id="A2" src="A2.png" alt="A2">
        <img id="A3" src="A3.png" alt="A3">
      </li>
      <li aria-controls="B">
        <span>B グループ:</span>
        <img id="B0" src="B0.png" alt="B0">
        <img id="B1" src="B1.png" alt="B1">
      </li>
      <li aria-controls="C">
        <span>C グループ:</span>
        <img id="C0" src="C0.png" alt="C0">
        <img id="C1" src="C1.png" alt="C1">
        <img id="C2" src="C2.png" alt="C2">
      </li>
    </ul>
    <ul>
      <li aria-controls="A B C">
        <input type="button" value="お勧めの組み合わせ 1" aria-labelledby="A0 B0 C1">
        <input type="button" value="お勧めの組み合わせ 2" aria-labelledby="A3 B1 C0">
        <input type="button" value="お勧めの組み合わせ 3" aria-labelledby="A2 B1 C1">
      </li>
    </ul>
    <img src="0.png" alt="dummy">
  </fieldset>
  <fieldset>
    <legend>結果</legend>
    <p>
      <img id="A" src="blank.png" alt="*">
      <img id="B" src="blank.png" alt="*">
      <img id="C" src="blank.png" alt="*">
    </p>
  </fieldset>
</form>

タグ:

WAI-ARIA
目安箱バナー