簡體   English   中英

如何刷新存儲和快照的 jquery 選擇器變量

[英]How can I refresh a stored and snapshotted jquery selector variable

昨天我遇到了分配給變量的 jquery 選擇器的問題,這讓我很生氣。

這是一個帶有測試用例的jsfiddle:

  • 將 .elem 分配給我的 obj var
  • 將兩個長度都記錄到控制台。 結果 => 4
  • 從 DOM 中刪除 #3
  • 將 obj 記錄到控制台 => 刪除的 #3 仍然存在並且長度仍然是 4。我發現 jquery 查詢被快照了? 到變量,不能?不會? 更新
  • 將 .elem 記錄到控制台.. 是的 結果 => 3 並且 #3 消失了
  • 現在我用 300 的新寬度更新 .elem
  • logging obj & obj.width 給了我 300.. 所以快照已經更新了? 有趣的是,4 個 div 中的 3 個具有新的寬度,但刪除的 #3 沒有...

另一個測試:向 domtree 添加一個 li 元素並記錄 obj 和 .elem。 .elem 確實有新的 li 而 obj 沒有,因為它仍然是舊快照

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

有沒有辦法用新內容更新這個 obj ? 我不想創建一個新的 obj,因為在我的應用程序中,該對象中保存了很多信息,我不想破壞...

是的,這是一個快照。 此外,從頁面 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

我也喜歡@Esailja 解決方案,但似乎 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;
};

代碼不是很漂亮,但它適用於我的過濾選擇器。

干凈和通用的解決方案與 jQuery 3.4.1 正常工作:

我的解決方案是執行以下操作:

  1. 在 jQuery 對象初始化時攔截選擇器,同時使用繼承透明地維護所有其他 jQuery 功能
  2. 使用我們在初始化期間添加的新“選擇器”屬性構建刷新插件

定義:

$ = (function (originalJQuery) 
{
    return (function () 
    {
        var newJQuery = originalJQuery.apply(this, arguments);
        newJQuery.selector = arguments.length > 0 ? arguments[0] : null;
        return newJQuery;
    });
})($);

$.fn = $.prototype = jQuery.fn;

$.fn.refresh = function () 
{
    if (this.selector != null && (typeof this.selector === 'string' || this.selector instanceof String))
    {
        var elems = $(this.selector);
        this.splice(0, this.length);
        this.push.apply(this, elems);
    }
    return this;
};

用法:

var myAnchors = $('p > a');
//Manipulate your DOM and make changes to be captured by the refresh plugin....
myAnchors.refresh();
//Now, myAnchors variable will hold a fresh snapshot 

注意:作為優化,對象選擇器不需要刷新,因為它們本質上是通過引用傳遞的,因此,在刷新插件中,我們僅在選擇器是字符串選擇器而不是對象選擇器時才刷新,以進行說明,請考慮以下代碼:

// Define a plain object
var foo = { foo: "bar", hello: "world" };
 
// Pass it to the jQuery function
var $foo = $( foo );
 
// Test accessing property values
var test1 = $foo.prop( "foo" ); // bar

// Change the original object
foo.foo = "koko";

// Test updated property value
var test2 = $foo.prop( "foo" ); // koko

不推薦使用 Jquery .selector,最好在分配時記住帶有選擇器值的字符串到某個變量

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

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

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

如果您使用remove()它將只刪除 DOM 的一部分,而不是所有的孩子或相關的,相反,如果您在元素上使用empty()問題就消失了。

例如:

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

也許它對某人有用!

您還可以在函數中返回 JQuery 選擇器,並將此函數保存到變量中。 您的代碼看起來有點不同,但它有效。 每次執行該函數時,您的 jquery 選擇器都會再次搜索 DOM。

在這個例子中,我使用了一個沒有括號的箭頭函數,它將返回箭頭旁邊的任何內容。 在這種情況下,它將返回 JQuery 集合。

 const $mySelector = () => $('.selector'); console.log($mySelector().last().text()); $('.parent').append('<li class="selector">4</li>') console.log($mySelector().last().text()); //RETURNS 4 not 3
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <ul class="parent"> <li class="selector">1</li> <li class="selector">2</li> <li class="selector">3</li> </ul>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM