PrimeFacesには、IE上で動かないバグが結構あります。
原因としてはJavaScriptでうまくいかない事がほぼなのですが、
結構困ります。
僕がハマってしまって一応解決した事を書いていこうと思います。
今回は、FileUpload部品でIEのみスクリプトエラーが出てしまう事象の解決方法を書いていきます。
前提
動作環境は以下の通りです
・PrimeFaces4.0
・JSF2.2
・GlassFish4.0
・JavaSE7
・IE8
PrimeFaces環境でのjQuery利用方法についてはこちらのエントリを。
事象
1.ファイルアップロードの参照ボタンからエクスプローラーでファイル選択
2.ファイルをアップロードする前にp:fileuploadのキャンセルボタン(×ボタン)を押す
3.スクリプトエラー発生
原因
PrimeFacsesのfileupload.js内で、ボタン押下時にcssの切り替えを行おうとしているのですが、
その際になぜかIE環境だけnodeの参照が出来なくなり、undefinedを参照したとしてスクリプトエラーが発生していました。
対応策
・ボタンのクリックイベントをハンドリングして、cssの描画処理を変更する
まぁ、これしか無いと思います。僕は応急処置として、mousehover/mouseoutと同じ描画処理に変更しました。
実際のコードは以下の通りです。
// body onload属性でこのfunctionを実行 function addOnLoad() { $(".ui-fileupload).each( function () { fixUploadWidgetForIE(widgetById($(this).attr("id"))); }); } // IE用のscript error 回避策 function fixUploadWidgetForIE(widget) { $(document).off('fileupload focus.fileupload blur.fileupload), widget.rowCancelActionSelector) .on('focus.fileupload', widget.rowCancelActionSelector, null, function(e) { $(widget).addclass('ui-state-hover').removeClass(''ui-state-active); }) .on('blur.fileupload', widget.rowCancelActionSelector, null, function(e) { $(widget).removeClass('ui-state-hover ui-state-active'); } ); } //widget取得funciton function widgetById( id ) { for(var i in PrimeFaces.widget[i].cfg["id] ) { if( id === PrimeFaces.widgets[i]) { return PrimeFaces.widgets[i]; } } }
これをxhtml上で適用してあげれば、解決出来ます。
具体的には、<body onload="addOnLoad()">
といったかたちでfunctionを呼び出していただければ、画面内のfileupload部品に対して、
不具合修正したイベントハンドリングが適用されます。
画面ロード毎にスクリプトが走るのが嫌だ!ということであれば、
自前でタグライブラリを作成するしか無いですね。
試しては無いですが、
JavaのTagを作成し、tldで読み込み独自拡張する必要があると思います。 jsクラスはextend以下のようにextend出来ます。
MyWidget.ModifiedFileUpload = PrimeFaces.widget.FileUpload.extend({ hoge : function() { } }):
まとめ
ここまで書いておいてなんですが、
PrimeFacesを利用する場合はIEを推奨ブラウザとしない方が良いと思います。
PrimeFacesのプロジェクトチームとしてはIEに関してもTestを行っており、
一応動作は保証している範囲だと思うのですが、
どうしても、IE独自の不具合というのは多いです。
これはPrimeFacesに限った事ではなく、JavaScriptを利用するとどうしてもブラウザ間の障壁は大きく、
特に、IEに関しては独自仕様やIE自体のバグなどがあるため、悩まされる事が多いです。
IE対応、どうしてもやらないといけない場合(例えば僕とか)もあるので、
そういった方の参考になれば幸いです。
また、もっと良い方法があるよという場合は、コメントいただければと思います。
0 件のコメント:
コメントを投稿