* 仕様書

[REFS[
- [12] [CITE@en-GB-x-hixie[HTML Standard]] ([TIME[2016-03-14 22:44:13 +09:00]] 版) <https://html.spec.whatwg.org/#dom-location-hash>
]REFS]

* 性質

[38] この[[属性]]は、 [CODE(xattr IDL)@en[Unforgeable]] です [SRC[>>12]]。

* 取得器

[16] [CODE(JS)@en[location.hash]] の[[取得器]]は、次のようにしなければ[MUST[なりません]]
[SRC[>>12]]。

[FIG(steps)[
= [24] [[文脈オブジェクト]]の[F[[[関係する[CODE(DOMi)@en[Document]]]]]]の[F[起源][文書の起源]]と[[入口設定群オブジェクト]]の[F[起源]]が[[同じ起源ドメイン]]でなければ、
== [25] [CODE(DOMe)@en[SecurityError]] [[例外]]を[[投げ]]、ここで停止します。
= [26] [VAR[URL]]を、[[文脈オブジェクト]]の[F[URL][Location (DOM)]] に設定します。
= [27] [VAR[URL]] の[F[素片][素片識別子]]が [[null]] か[[空文字列]]なら、
== [14] [[空文字列]]を返します。
= [15] それ以外なら、
== [28] [CODE[#]] と[VAR[URL]]の[F[素片][素片識別子]]を連結したものを返します。
]FIG]

* 設定器

[29] [CODE(JS)@en[location.hash]] の[[設定器]]は、次のようにしなければ[MUST[なりません]]
[SRC[>>12]]。

[FIG(steps)[
= [39] [VAR[入力]]を、与えられた値を [CODE(IDL)@en[USVString]] として解釈した結果に設定します。
= [30] [[文脈オブジェクト]]の[F[[[関係する[CODE(DOMi)@en[Document]]]]]]の[F[起源][文書の起源]]と[[入口設定群オブジェクト]]の[F[起源]]が[[同じ起源ドメイン]]でなければ、
== [17] [CODE(DOMe)@en[SecurityError]] [[例外]]を[[投げ]]、ここで停止します。
= [18] [VAR[複製]]を、[[文脈オブジェクト]]の[F[URL][Location (DOM)]] に設定します。
= [35] [VAR[入力]]の先頭が [CODE[#]] なら、これを削除します。
= [36] [VAR[複製]]の[F[素片][素片識別子]]を、[[空文字列]]に設定します。
= [37] [VAR[入力]]に[[基本URL構文解析]]を適用します。
[VAR[URL]] は[VAR[複製]]、[VAR[状態上書き]]は [[fragment state]] とします。
= [21] [[文脈オブジェクト]]と [VAR[複製]]について
[[[CODE(DOMi)@en[Location]]-object-setter navigate]] を実行します。
]FIG]

;; [23] [[URL scheme]] が [CODE(URI)@en[javascript:]] になる場合があるのかは謎です。

[22] [CODE[[[location.hash]] = ""]] は、[[素片識別子]]を除去するのでなく、
[[空文字列]]に設定します。

* 歴史

[1] 
[CODE(JS)[location.hash]], [[Gecko]] では[[百分率符号化]]
([[URI符号化]]) が復号されていて、 [[WinIE]]
では復号されていないという罠。 ([CODE(JS)[hash]]
以外も非互換な悪寒。)

回避するには、 [CODE(JS)[location.href]] を使うがよろし。

[PRE(JS example)[
function getFragment (uri) {
  var fstart = uri.indexOf ('#');
  if (fstart == -1) return null;
  return decodeURI (uri.substr (fstart + 1));
// 百分率符号化したままがよいなら
//   return uri.substr (fstart + 1);
}
var fragment = getFragment (location.href);
]PRE]

[[正規表現]]でさらりとこなす例
[PRE(JS example)[
var fragment = decodeURI (location.href.replace (/^.*#/, ""));
// 百分率符号化したままがよいなら
//   var fragment = location.href.replace (/^.*#/, "");
]PRE]

- [33] [CITE[[[最速インターフェース研究会]] :: firefoxのlocation.hashには1MB以上保存できる]], 
2005-03-18 07:30,
[TIME[2022-06-13T09:18:41.000Z]] <http://la.ma.la/blog/diary_200503040335.htm>
-- [2] [CITE[location.hash]] <http://ma.la/mirrorman/wiki.cgi/location.hash>

[41] >>2
[CODE(JS)[location.hash]] ([[素片識別子]]) 
に[[セッション]]情報を保存しようという試み。
同じことを考えてる人がいたとは。


[42] [CITE[最速インターフェース研究会 :: '''['''Ajax''']''' location.hashを使ったセッション復元]], [TIME[2022-06-13T09:21:28.000Z]] <http://la.ma.la/blog/diary_200502270128.htm>

[3]
[CITE[Merge and Context Ids]] <http://www.helpware.net/htmlhelp/how_to_merge_ctx2.htm>

[[HTML Help]] 内の [[redirect]] に素片識別子を使うという話。
([[名無しさん]])

[4]
[CITE[web拍手登録版を加工・改造・実験・検証]] <http://web1.nazca.co.jp/hp/macde/commonmailform/webclap.html#gratitude2>
(2004年9月付け)

[[利用者]]の入力に対する反応 (頁内容の変化)
をスクリプトと素片識別子により行っています。
([[名無しさん]] [sage])

[5]
'''はじめの [CODE(URI)[#]]''': 素片識別子の前に来る[[区切子]]の [CODE(URI)[#]]
は、 [CODE(DOMa)[hash]] の取得では
[WEAK[(元の URI にあれば)]] 常につきますが、
値の設定ではなくてもよいようです。
([[名無しさん]])

[6]
'''URI 符号化''': URI 全体として Gecko は必要に応じて [WEAK[(URI で使えない文字があれば)]] [[百分率符号化]]し、
WinIE は必要であっても放置するようです。

[CODE(DOMa)[hash]] で取得できる値は
Gecko では [[UTF-8]] として復号された状態、
WinIE では百分率符号化 [WEAK[(されていれば)]] されたままの状態です。

([[名無しさん]])

[7]
'''この属性が存在する物体''':
この属性は [[DOM水準0]] ですが、
[CODE(DOMa)[[[location]]]] 物体のみならず、
[CODE(HTMLa)[[[href]]]] 属性や
[CODE(HTMLa)[[[src]]]] 属性がある要素の
[[DOM]] 属性として
[WEAK[(他の [CODE(DOMa)[location]] 系属性と共に)]] 存在しています。

([[名無しさん]])

[8]
'''値の設定による移動''': 値を設定すると、
他の状況で URI が指定された場合同様に新しい素片識別子で識別される部分要素まで [[scroll]] するなりなんなりしようとします。
([[名無しさん]] [sage])

[9]
'''値の自動的な変化''': 頁内リンクの移動や
[CODE(DOM)[[CODE(DOMa)[[[location]]]].[CODE(DOMa)[[[href]]]]]]
などの設定で URI が変化すると、
自動的に [CODE(DOM)[[CODE(DOMa)[[[location]]]].[CODE(DOMa)[hash]]]]
の値も更新されます。
([[名無しさん]] [sage])

[10]
>>6 より、 Gecko でも WinIE でも
[CODE(DOM)[hash]] が構文的に正しい素片識別子になっていることは期待できません。
>>1 のように [CODE(DOMa)[href]]
から採るのが安全です。ただし
>>6 にあるように WinIE ではこちらも
URI として正しいことが期待できません。
([[名無しさん]])

[11]
[CITE[Bug 135309 - location.hash should not be unescaped]] <https://bugzilla.mozilla.org/show_bug.cgi?id=135309>

[13]
[CITE[Link Fingerprints]] ([CODE[2007-07-03 07:20:54 +09:00]] 版) <https://people.mozilla.com/~edilee/draft-lee-uri-linkfingerprints-00.txt>
([[名無しさん]] [WEAK[2007-07-24 14:22:07 +00:00]])

[19]
[CITE[Bug 377245 &#8211; '''['''SoC''']''' Link Fingerprints]] ([TIME[2008-10-12 16:57:12 +09:00]] 版) <https://bugzilla.mozilla.org/show_bug.cgi?id=377245>


[20] [CITE@en[1093611 – AnchorElement.hash should be the encoded version of the href attribute's fragment]]
( ([TIME[2014-11-13 10:57:52 +09:00]] 版))
<https://bugzilla.mozilla.org/show_bug.cgi?id=1093611>

[34] [CITE@en[Merge effective script origin into origin · whatwg/html@8a843f2]]
([TIME[2016-03-31 18:12:02 +09:00]] 版)
<https://github.com/whatwg/html/commit/8a843f2169a6864a3024c4329528dccb2051d275>

[40] [CITE@en[location.hash = "" should result in a fragment]]
( ([[annevk]]著, [TIME[2016-05-26 16:36:16 +09:00]]))
<https://github.com/whatwg/html/commit/c63078741df8ae8c4657dc068d5879fb3472dee6>

[32] [CITE@en[Remove javascript URL case from <a>/<area>/Location hash setter]]
([[annevk]]著, [TIME[2017-02-22 15:19:37 +09:00]])
<https://github.com/whatwg/html/commit/deea9fba916cb6e66c7dcfc57442cf25ac0441a1>

[31] [CITE@en[Remove javascript URL special case from the API]]
([[annevk]]著, [TIME[2017-02-16 22:57:09 +09:00]])
<https://github.com/whatwg/url/commit/4bf85a08da18ef367e093426abef776d59e8fb7b>