7

これはいつも私を取得します。Web ページ上の素敵な UI 要素をすべて初期化した後、一部のコンテンツを (モーダルまたはタブなどに) 読み込みますが、新しく読み込まれたコンテンツには UI 要素が初期化されていません。例えば:

$('a.button').button(); // jquery ui button as an example
$('select').chosen(); // chosen ui as another example
$('#content').load('/uri'); // content is not styled :(

私の現在のアプローチは、バインドが必要な要素のレジストリを作成することです。

var uiRegistry = {
  registry: [],
  push: function (func) { this.registry.push(func) },
  apply: function (scope) {
    $.each(uiRegistry.registry, function (i, func) {
      func(scope);
    });
  }
};

uiRegistry.push(function (scope) {
  $('a.button', scope).button();
  $('select', scope).chosen();
});

uiRegistry.apply('body'); // content gets styled as per usual

$('#content').load('/uri', function () {
  uiRegistry.apply($(this)); // content gets styled :)
});

この問題を抱えているのは私だけではないので、これを行うためのより良いパターンはありますか?

4

2 に答える 2

1

私の答えは基本的にあなたが概説したものと同じですが、jquery イベントを使用してセットアップ コードをトリガーします。私はそれを「moddom」イベントと呼んでいます。

新しいコンテンツをロードすると、親でイベントをトリガーします。

parent.append(newcode).trigger('moddom');

ウィジェットで、そのイベントを探します。

$.on('moddom', function(ev) {
  $(ev.target).find('.myselector')
})

これは、イベント メソッドを説明するために単純化しすぎています。

実際には、セレクターとコールバック引数を取る関数 domInit でラップします。セレクターに一致する新しい要素が見つかるたびに、最初の引数として jquery 要素を使用して、コールバックを呼び出します。

私のウィジェットコードでは、これを行うことができます:

domInit('.myselector', function(myelement) {
  myelement.css('color', 'blue');
})

domInit は、既に適用されている関数のレジストリである問題の要素「domInit」にデータを設定します。

私の完全な domInit 関数:

window.domInit = function(select, once, callback) {
  var apply, done;
  done = false;
  apply = function() {
    var applied, el;
    el = $(this);
    if (once && !done) {
      done = true;
    }
    applied = el.data('domInit') || {};
    if (applied[callback]) {
      return;
    }
    applied[callback] = true;
    el.data('domInit', applied);
    callback(el);
  };
  $(select).each(apply);
  $(document).on('moddom', function(ev) {
    if (done) {
      return;
    }
    $(ev.target).find(select).each(apply);
  });
};

これで、dom を変更するたびに「moddom」イベントをトリガーすることを覚えておく必要があります。

「一度」の機能が必要ない場合は、これを単純化できますが、これは非常にまれなケースです。コールバックを 1 回だけ呼び出します。たとえば、一致する要素が見つかったときに何かグローバルなことをしようとしている場合 - ただし、それは一度だけ行う必要があります。done パラメータなしで簡略化:

window.domInit = function(select, callback) {
  var apply;
  apply = function() {
    var applied, el;
    el = $(this);
    applied = el.data('domInit') || {};
    if (applied[callback]) {
      return;
    }
    applied[callback] = true;
    el.data('domInit', applied);
    callback(el);
  };
  $(select).each(apply);
  $(document).on('moddom', function(ev) {
    $(ev.target).find(select).each(apply);
  });
};

DOM が変更されたときにブラウザがコールバックを受け取る方法が必要なように思えますが、そのようなことは聞いたことがありません。

于 2013-02-25T19:25:10.203 に答える
0

最善の方法は、すべての ui コードを関数でラップすることです (さらに別のファイルを使用することをお勧めします)。ajax ロードでは、その関数をコールバックとして指定するだけです。ここに小さな例があります。

テキスト フィールドとクラスsomeclass-for-dateを日付ピッカーにバインドするコードがあるとします。コードは次のようになります。

$('.someclass-for-date').datepicker();

これが私が最高だと思うものです

function datepickerUi(){
    $('.someclass-for-date').datepicker();
}

負荷は次のようになります

$('#content').load('/uri', function(){

    datepickerUi();

})

または、html の最後にあるスクリプト タグでロードすることもできます (ただし、デバッグが難しいため、それは好きではありません)。

ここにいくつかのヒントがあります

コードと CSS のスタイルを可能な限りクリーンに保ちます..つまり、日付ピッカーである必要があるテキスト フィールドに対して、Web サイト全体で 1 つのクラスを提供します..このレートでは、すべてのコードがクリーンで維持しやすくなります..

OOCss の詳細を読むと、私の言いたいことが明確になります。

主にjqueryでは、組織がすべてです...少し考えてみると、1行のコードでやりたいことが得られます..

編集

これはあなたに似たものを使ったjsフィドルですが、少しきれいだと思います ここをクリック

于 2013-02-25T19:04:28.683 に答える