Web標準仕様
<label>内の文言をクリックすると、<label>と<input>の2回クリックイベントが<div>まで上がってきます。
この挙動は「Web標準仕様」で定義された挙動でしょうか。
該当仕様書のURLがわかりましたら、是非教えてください。
仕様に則ってコーディングするのが原則と考えます。
検証結果
手元のGoogle Chromeで検証し、下記仕様とあたりを付けました。
label要素でclickイベントが発火した場合、対応するフォーム部品でもclickイベントが発火する
HTML Standard の「4.10 Forms」配下で定義されている要素をフォーム部品と想定し、フォーム部品にlabel要素が対応している状況で、clickイベントが2回発火しないように書いたのが下記コードとなります。
html
1 < div id = " target " >
2 < fieldset >
3 < legend > label要素配下にフォーム部品がある場合 </ legend >
4 < p > < label > input[type=text] < input type = " text " /> </ label > </ p >
5 < p > < label > button < button > button </ button > </ label > </ p >
6 < p > < label > select < select > < option value = " dog " > Dog </ option > </ select > </ label > </ p >
7 < p > < label > textarea < textarea > Dog </ textarea > </ label > </ p >
8 < p > < label > output < output > output </ output > </ label > </ p >
9 < p > < label > progress < progress id = " file " max = " 100 " value = " 70 " > 70% </ progress > </ label > </ p >
10 < p > < label > meter < meter id = " fuel " min = " 0 " max = " 100 " low = " 33 " high = " 66 " optimum = " 80 " value = " 50 " > at 50/100 </ meter > </ label > </ p >
11 </ fieldset >
12 < fieldset >
13 < legend > label要素のfor属性値に対応するフォーム部品がある場合 </ legend >
14 < p > < label for = " foo " > input[type=text] </ label > < input id = " foo " type = " text " /> </ p >
15 </ fieldset >
16 < fieldset >
17 < legend > label要素に対応するフォーム部品がない場合 </ legend >
18 < p > < label > label </ label > </ p >
19 </ fieldset >
20 </ div >
21 < script >
22 'use strict' ;
23 document . getElementById ( 'target' ) . addEventListener ( 'click' , function handleClick ( event ) {
24 const target = event . target , htmlFor = target . htmlFor ? target . ownerDocument . getElementById ( target . htmlFor ) : null ;
25 if ( target . tagName === 'LABEL' &&
26 ( target . querySelector ( 'input,button,select,textarea,output,progress,meter' ) ||
27 htmlFor && [ 'INPUT' , 'BUTTON' , 'SELECT' , 'TEXTAREA' , 'OUTPUT' , 'PROGRESS' , 'METER' ] . includes ( htmlFor . tagName ) )
28 ) return ;
29 console . log ( event . type , target ) ;
30 } , false ) ;
31 </ script >