web-dev-qa-db-ja.com

保存およびスナップショットされたjqueryセレクター変数を更新するにはどうすればよいですか

私は昨日、変数に割り当てたjquery-selectorの問題で実行され、それが私を怒らせています。

ここにテストケースのあるjsfiddleがあります:

  • .elemをobj varに割り当てます
  • 両方の長さをコンソールに記録します。結果=> 4
  • DOMから#3を削除する
  • コンソールにobjをログに記録=>削除された#3はまだそこにあり、長さはまだ4です。jqueryクエリがスナップショットされていることがわかりましたか?変数にできませんか?できませんか?更新します
  • コンソールに.elemを記録します。yep結果=> 3で、#3はなくなりました
  • .elemを新しい幅300に更新します
  • logging obj&obj.widthで300が得られます。スナップショットは更新されましたか?興味深いのは、4つのdivのうち3つが新しい幅になっていることですが、削除された#3はそうではありません...

別のテスト:domtreeにli要素を追加し、objと.elemをログに記録します。 .elemには新しいliがあり、objにはまだありません。これはまだ古いスナップショットであるためです。

http://jsfiddle.net/CBDUK/1/

このオブジェクトを新しいコンテンツで更新する方法はありませんか?新しいobjを作成したくありません。私のアプリケーションには、そのオブジェクトに保存された多くの情報があるため、破棄したくありません...

31
Ralk

ええ、それはスナップショットです。さらに、ページDOMツリーから要素を削除しても、要素へのすべての参照が魔法のように消滅するわけではありません。

次のように更新できます:

var a = $(".elem");

a = $(a.selector);

ミニプラグイン:

$.fn.refresh = function() {
    return $(this.selector);
};

var a = $(".elem");

a = a.refresh();

ただし、この単純なソリューションは複雑なトラバーサルでは機能しません。それらのスナップショットを更新するには、.selectorプロパティのパーサーを作成する必要があります。

形式は次のとおりです。

$("body").find("div").next(".sibling").prevAll().siblings().selector
//"body div.next(.sibling).prevAll().siblings()"

インプレースミニプラグイン:

$.fn.refresh = function() {
    var elems = $(this.selector);
    this.splice(0, this.length);
    this.Push.apply( this, elems );
    return this;
};

var a = $(".elem");
a.refresh() //No assignment necessary
60
Esailija

@Esailijaソリューションも好きでしたが、this.selectorにはフィルターに関するいくつかのバグがあるようです。だから私は自分のニーズに合わせて修正しました、多分それは誰かに役立つでしょう

これはjQuery 1.7.2のためのもので、より高いバージョンのフィルターされたスナップショットで更新をテストしませんでした

$.fn.refresh = function() { // refresh seletor
    var m = this.selector.match(/\.filter\([.\S+\d?(\,\s2)]*\)/); // catch filter string
    var elems = null;
    if (m != null) { // if no filter, then do the evarage workflow
        var filter = m[0].match(/\([.\S+\d?(\,\s2)]*\)/)[0].replace(/[\(\)']+/g,'');
        this.selector = this.selector.replace(m[0],''); // remove filter from selector
        elems = $(this.selector).filter(filter); // enable filter for it
    } else {
        elems = $(this.selector);
    }
    this.splice(0, this.length);
    this.Push.apply( this, elems );
    return this;
};

コードはそれほど美しくありませんが、フィルターされたセレクターでは機能しました。

1
Roman M. Koss

remove()を使用すると、DOMの一部のみが削除されますが、すべての子または関連は削除されません。代わりに、要素でempty()を使用すると、問題はなくなります。

例えば。:

 $('#parent .child).find('#foo').empty();

多分それは誰かに役立つかもしれません!

Jquery .selectorは非推奨です。割り当てるときに、変数にセレクター値を含む文字列を思い出してください。

function someModule($selector, selectorText) {
   var $moduleSelector = $selector;
   var moduleSelectorText = selectorText;

   var onSelectorRefresh = function() {
      $moduleSelector = $(moduleSelectorText);
   }
}

https://api.jquery.com/selector/

0
Kattie