PHP から JS に値を渡したいとき、PHP から適当な要素の data
アトリビュートに書き出して jQuery の .data()
メソッドで取り出していたんですけど・・・
http://api.jquery.com/data/ ... When the data attribute is an object (starts with '{') or array (starts with '[') then jQuery.parseJSON is used to parse the string; it must follow valid JSON syntax including quoted property names. If the value isn't parseable as a JavaScript value, it is left as a string. ...
なんと .data()
メソッドで data
アトリビュートから値が取られるとき、値が JSON としてパースできるならパースした結果が返り、できなければ属性値がそのまま文字列として返る仕様でした。
ので、PHP から JS に文字列を渡したいときに jQuery の .data()
メソッドで取っていると、文字列がたまたま JSON っぽかったときに文字列ではなく配列やオブジェクトになってしまうことがあります。
<!doctype html> <html> <head> <meta charset="utf-8"> <title></title> <script src="//code.jquery.com/jquery-3.2.1.min.js"></script> </head> <body> <script id="data" data-aaa="[1, 2, 3]" data-bbb="[1, 2, 3]x"> console.log($('#data').data('aaa')); // Array [ 1, 2, 3 ] console.log($('#data').data('bbb')); // "[1, 2, 3]x" console.log($('#data').attr('data-aaa')); // "[1, 2, 3]" console.log($('#data').attr('data-bbb')); // "[1, 2, 3]x" </script> </body> </html>
jQuery の .data()
は元々は HTML の data
アトリビュートから値を取るためのものではなく jQuery で独自に要素とデータを関連付けるためのもので(要素のプロパティとして直接データを持たせることによる DOM と JS オブジェクトを跨る循環参照よるメモリリークの問題を解消するため?)、data
アトリビュートからも値が取れるのは後付けの機能だったと思うので、単に data
アトリビュートから文字列を取りたいときは .data()
ではなく .attr()
を使うべき、ということですね。
ちなみにこんな感じに判定されているようです。
配列やオブジェクトなら PHP から json_encode
した値を書き出して jQuery で .data()
を使えば受け渡しが簡単にできて便利?なのかな??