web-dev-qa-db-ja.com

ウィジェット管理フォームでJavaScriptをエレガントに使用

私はたくさんのウィジェットを含むプロジェクトに取り組んでいます、そして、クリックされると拡張するjQuery UI Accordionを使って構築された "More options"セクションを持つことが本当に素晴らしいと思います。

そのため、私は 'admin_enqueue_scripts'アクションを使用して 'jquery-ui-accordion'をエンキューしました。

function add_my_deps() {
    wp_enqueue_script('jquery-ui-accordion');
}    
add_action( 'admin_enqueue_scripts', 'add_my_deps' );

...そして私のJavaScriptはこのようになります:

(function($){
    $('.more-options-expansible').accordion();
})(jQuery)

ではどうしたのですか?

上記の "add_my_deps"アクションを介してエンキューする場合、ページをリロードした場合にのみ機能します(つまり、ウィジェットを配置するときには、要素が作成される前にJavaScriptがインスタンス化されます。そしてそれは通常通りインスタンス化されます。).

これをウィジェットのform()メソッドのHTML出力の最後にある<script>タグに入れると、次の例外が発生します。Uncaught TypeError: Object [object Object] has no method 'accordion'。これは、jQuery UI Accordionライブラリがロードされる前に、インライン<script>を介してアコーディオンをインスタンス化しているように見えるためです。

私が見逃している明白な何かはありますか?この例では単純なjQueryインスタンス化を使用していますが、AJAXを使用して何かをしようとするとさらに問題が発生するようです(つまり、適切な要素を選択して配置する方法)これを達成するためにBackbone.jsを使い始める必要があるのでしょうか?).

何か手助け?

2
aendrew

私は前の質問からの私の調査結果で私の答えを編集しました、これは今まっすぐにあなたを設定するべきです。

JSが実行されると、左側の隠しウィジェットフォームに対してインスタンス化されているため、失敗します。ウィジェットをアクティブなサイドバーにドラッグすると、隠されたフォームが実際には右側に複製されます。コンテンツのajax機能とは対照的です。これはつまり、あなたが追加した新しいウィジェットは既にそれに対してインスタンス化されたaccordionを持っていますが、クローン作成のため最初はうまく機能しません。明らかにページを更新した後でも、それは完璧に動作します。

新しいウィジェットを追加したときに意図したとおりに機能させるには、ページの右側にあるフォームコンテンツをターゲットにする必要があります。loadの代わりにajaxstopイベントにフックすることもできます。これは、クローンされたウィジェットが右側にドロップされた後、WordPressがウィジェットの位置を保存するためにajaxリクエストを送信するためです。

$(document).on('ajaxstop', '#widget-right .more-options-expansible', function(e){
    $(this).accordion();
});    

これにより、JSをインラインで追加するよりも優れたソリューションが得られ、スクリプトをフッターに入れることができます。

1
MichaelJames

上記の質問を投稿して以来、私が発見した1つの方法は、WP_Widget::form()を介してインラインをインスタンス化することです。wp_enqueue_script()は必要なJavaScriptをロードしますフッター(wp_enqueue_script()の5番目の引数)の代わりにJavaScript ヘッダーのをロードします。

考えてみると、これは非常に理にかなっています。

それでも、インラインJavaScriptを使用することは嫌いです。

そのため、誰かがより良いアイデアを持っている場合に備えて、この質問を公開したままにします。

1
aendrew

WordPressはいくつかのJavaScriptイベント、 'widget-added'、 'widget-updated'、 'widget-synced'を追加したので、ajaxイベントをハックする必要はもうありません。

https://core.trac.wordpress.org/ticket/19675

だから、私はあなたがあなたの外部のjsファイルでこのようなものにコードを更新する必要があると思います:

$(document).on('widget-added', function(event, widget) {
   $(widget).find('.more-options-expansible').accordion();
}

'widget-updated'と 'widget-synced'には似たものを追加する必要があるでしょう。

0
scottsawyer