2012-04-30 47 views
14

Có cách nào để có các phần tử DOM có thể chọn thông qua các đối tượng không?jquery sử dụng các đối tượng làm bộ lọc

Ví dụ tôi muốn để có thể liên kết các đối tượng phần tử DOM như vậy:

var obj = { a: 1, b:2 }; 
$('a').click(function() { this.selectThing = obj }); 

Và sau này ...

$.something(obj); 

Hoặc thậm chí tốt hơn:

$('a|selectThing?=', obj); 

Một cái gì đó như thế. Bạn có thể thấy rằng tôi muốn kết hợp một đối tượng với một phần tử DOM theo cách mà tôi có thể lấy phần tử đó với đối tượng.

Tôi biết điều này có thể được thực hiện với phương pháp filter(), câu hỏi của tôi là nếu có cách thanh lịch hơn không sử dụng filter() để thực hiện việc này.

EDIT:

Để làm rõ, tôi muốn để có thể sử dụng một đối tượng giống như một chọn, vì vậy tôi có thể làm điều gì đó tương tự -$(obj) này rõ ràng rằng sẽ không làm việc, nhưng bạn sẽ có được ý tưởng (tôi hy vọng)

EDIT # 2:

tôi muốn để có thể làm điều gì đó như thế này:

var obj = { prop: 'prop' }; 
$('a').bindTo(obj); 
$.retreive(obj) // should equal $('a') 

Tôi không muốn nó thay đổi obj theo bất kỳ cách nào (obj vẫn chỉ là {prop: 'prop'}).

+0

Bạn có thể thêm ví dụ về sử dụng phương pháp lọc để đạt được điều này không? Tôi không biết bạn đang cố làm gì khác. – Esailija

+0

Bạn đã kiểm tra câu trả lời tôi đã đề xuất http://stackoverflow.com/questions/2891452/jquery-data-selector/2895933#2895933? – Meligy

+0

@MohamedMeligy: có, nhưng một lần nữa không sử dụng đối tượng trong công cụ chọn, thay vào đó, lựa chọn đó có dữ liệu được liên kết với phần tử DOM. – qwertymk

Trả lời

1

Mở rộng jQuery với ba phương pháp:

jQuery.bindObj(data) 
jQuery.unbindObj(data) 
$.retrieve(data) 

Mã của bạn trông giống như:

$('a').bindObj({blorg: 'shmorg'}); 
console.log($.retrieve({blorg: 'shmorg'})); // logs live result of $('a'); 

nguồn đầy đủ: http://jsfiddle.net/nUUSV/6/.Bí quyết cho giải pháp này là lưu trữ bộ chọn/số nhận dạng dựa vào hàm tạo jQuery trong một mảng và đối tượng được liên kết với các bộ chọn/số nhận dạng trong mảng khác, sau đó sử dụng $.inArray để lấy chỉ mục của đối tượng khi truy xuất và sử dụng chỉ mục đó để lấy bộ sưu tập jQuery bị ràng buộc.

+0

Đây là những gì tôi đang tìm kiếm. Cảm ơn – qwertymk

+0

Hãy nhận biết rằng hiệu suất của điều này là tồi tệ hơn đáng kể so với tìm kiếm băm đơn giản. –

2

Bạn đang tìm kiếm $.data. Phương thức này liên kết bất kỳ đối tượng JavaScript hoặc nguyên thủy nào với phần tử DOM. Dưới mui xe, nó không thêm dữ liệu như là một phần mở rộng cho phần tử DOM hoặc bất cứ thứ gì - thay vào đó, jQuery duy trì bộ nhớ cache đối tượng riêng của các phần tử DOM và các băm dữ liệu. Nhưng đó là dưới mui xe; vấn đề là, tôi nghĩ đó chính xác là những gì bạn đang tìm kiếm.

$('#example').data('foo', { bar: 'quux' }); // returns the jquery object containing '#example', like most jQuery methods 

Sau đó, sau này:

console.log($('#example').data('foo')); // returns {bar: 'quux'} 
+2

Điều này không trả lời câu hỏi – qwertymk

8

demo

var $div1 = $('.box1'); 
var $div2 = $('.box2'); 
var obj = { a: $div1, b: $div2 }; 


obj.a.css({background:'red'}); 


Hoặc cách ngắn: var obj = { a: $('.box1'), b: $('.box2') };


demo jsBin 2

var obj = $('.box1, .box2'); // store objects 
obj.css({background:'red'}); // access collection 
+1

+1 là câu trả lời duy nhất giải quyết câu hỏi. – tobyodavies

+0

@tobyodavies: Tôi đang tìm cách sử dụng một đối tượng để lấy một phần tử, không lưu các phần tử trên một đối tượng. Những gì tôi muốn là tương tự như có một bộ chọn có thể là một đối tượng – qwertymk

+0

Không phải là giải pháp này chính xác? Đối tượng không thực sự là "lưu" các phần tử bên trong chính nó, thay vì đối tượng chứa 2 đối tượng jquery tham chiếu đến các phần tử DOM. Nếu bạn muốn làm $ (obj) thì obj phải là một chuỗi với bộ chọn jquery. Tôi đoán bản chất của đối tượng "obj" là gì? Bạn luôn có thể ghi đè lên "toString" chức năng của đối tượng để in ra một bộ chọn Tôi đoán ... Tôi vẫn không chắc chắn những gì bạn đang cố gắng để làm. Có lẽ một chút công phu là theo thứ tự? – Kasapo

2

Tôi không nghĩ rằng đây là một cách dễ dàng đạt được. Hãy để tôi làm rõ:

Để đạt được những gì bạn muốn, bạn sẽ yêu cầu một hashmap cho phép các đối tượng ở vị trí khóa. JavaScript chưa (chưa) hỗ trợ các đối tượng như các khóa trong hashmaps.Ví dụ: các trường hợp sau không hoạt động:

var key = {value: 'key'}; 
var data {value: 'data'}; 
var map = {}; 

map[key] = data; 

Có các giải pháp khác để đạt được điều này trong triển khai javascript hiện tại, ví dụ: một tra cứu kép:

var key = {value: 'key'}; 
var data {value: 'data'}; 
var map = { keys: [], data: [], get: function (key) { 
    var k = this.keys.indexOf(key); 
    if (k >= 0) { 
    return this.data[k]; 
    } else return undefined; 
}, set: function (key, val) { 
    var k = this.keys.indexOf(key); 
    if (k < 0) { 
    k = this.keys.push(k) - 1; 
    } 
    this.data[k] = val; 
} }; 

map.set(key, data); 
map.get(key).value; 

Triển khai này tuy nhiên có hiệu suất khủng khiếp. Có một đề xuất cho một cái gọi là WeakMap trong JavaScript Harmony. Firefox tôi tin rằng hiện tại là trình duyệt duy nhất thực hiện chúng. Vì tính năng được yêu cầu không có sẵn rộng rãi và giải pháp có hiệu suất kém nên tôi khuyên bạn nên tìm cách khác để đạt được những gì bạn đang cố gắng.

1

Như tôi đã hiểu, bạn đang tìm một số cách đường để chạy nhiều tìm kiếm có tên trên DOM và có kết quả được lọc trong đối tượng không gian tên.

Nếu vậy, tôi đoán phần mở rộng jquery sau đây có thể hữu ích cho bạn:

$.fn.seek = function (selectors) { 
    var container = this, 
    found = {}; 

    $.each(selectors, function (name) { 
    if ($.isPlainObject(selectors[name])) { 
     found[name] = $(container).seek(selectors[name]); 
    } 
    else if ($.type(selectors[name]) === 'string') { 
     found[name] = $(container).find(selectors[name]); 
    } 
    }); 

    return found; 
} 

Và đây là ví dụ về cách mở rộng ở trên có thể được áp dụng đối với trường hợp của bạn:

var res = $('body').seek({ 
    links: 'a', 
    headers: 'h1,h2,h3,h4,h5,h6' 
}); 

$(res.links).css({ color: 'green' }); 
$(res.headers).css({ color: 'red' }); 

tôi hy vọng điều này sẽ giúp bạn.

1

Không chắc chắn nếu đây là những gì bạn đang tìm kiếm. Có lẽ bạn có thể viết một bộ chọn tùy chỉnh dựa trên bộ chọn jquery, mà xử lý các đối tượng với một thuộc tính selector theo cách bạn muốn. Đối tượng có thể chọn sẽ trông giống như

var objSelector = {'selector' : '#select-me', 'a' : 'somestring', 'b' : 1243}; 

Vì vậy, bạn có thể sử dụng nó giống như bất kỳ đối tượng nào khác, nhưng bạn phải thêm thuộc tính bộ chọn. Hơn bạn thêm chọn tùy chỉnh của bạn:

$$ = (function($) { 
    return function(el, tag) { 
     if (typeof el === 'object' && el.selector !== undefined) { 
      return $(el.selector);     
     } 
     return $(el); 
    } 
}($)); 

Bây giờ bạn có thể làm những việc như

$$(objSelector).css({'border':'1px solid red'}); 

Xem một thực hiện trên http://jsfiddle.net/JXcnJ/

1

Nếu tôi hiểu đúng rồi, tôi nghĩ rằng bạn cần phải xác định một tài sản và nói enumerable là sai. Xem dưới đây,

Lưu ý: Dưới đây chỉ là một ví dụ để chứng minh và không chính xác có nghĩa là để làm công cụ như vậy,

DEMO

$(function() { 

    $.fn.bindTo = function(o) { 
     var _that = this; 

     Object.defineProperty(o, 'myFx', { 
      value: function() { return $(_that); }, 
      writable: true, 
      enumerable: false, 
      configurable: true 
     }); 
    } 

    $.retrieve = function(obj) { 
     return obj.myFx(); 
    } 

    var obj = { 
     prop: 'prop' 
    }; 

    $('#test').bindTo(obj); 

    $($.retrieve(obj)).html('Test'); 

    //below is for proof 
    for (i in obj) { 
     alert(obj[i]); 
    } 
}); 

tham khảo:http://yehudakatz.com/2011/08/12/understanding-prototypes-in-javascript/

Các vấn đề liên quan