Jquery с использованием объектов в качестве фильтров

Есть ли способ выбрать элементы DOM через объекты?

Например, я хочу иметь возможность связывать объекты с элементами DOM следующим образом:

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

И позже...

$.something(obj);

Или даже лучше:

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

Что-то вроде этого. Вы можете видеть, что я хочу связать объект с элементом DOM таким образом, чтобы я мог захватить элемент с объектом.

Я знаю, что это можно сделать с помощью метода filter(), мой вопрос в том, есть ли более элегантный способ, который не использует filter() для этого.

EDIT:

Чтобы уточнить, я хочу использовать объект типа типа селектора, поэтому я могу сделать что-то похожее на это $(obj), очевидно, что это не сработает, но вы получите идею (надеюсь)

ИЗМЕНИТЬ № 2:

Я хочу сделать что-то вроде этого:

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

Я не хочу, чтобы он менял obj каким-либо образом, хотя (obj должен быть только {prop: 'prop'}).

Ответы

Ответ 1

Расширьте jQuery тремя способами:

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

Ваш код выглядит так:

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

Полный источник: http://jsfiddle.net/nUUSV/6/.

Уловкой для этого решения является хранение селекторов/идентификаторов, основанных на конструкторе jQuery в одном массиве, и объекты, привязанные к этим селекторам/идентификаторам в другом массиве, а затем используя $.inArray, чтобы получить индекс объекта после извлечения и используя этот индекс для захвата связанной коллекции jQuery.

Ответ 2

демо

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


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


Или короткий путь: var obj = { a: $('.box1'), b: $('.box2') };

demo jsBin 2

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

Ответ 3

Вы ищете $.data. Этот метод связывает любой объект JavaScript или примитив с элементом DOM. Под капотом он не добавляет данные в качестве expando в элемент DOM или что-то еще - вместо этого jQuery поддерживает свой собственный кеш объектов DOM-элементов и хэшей данных. Но это под капотом; Дело в том, что я думаю, это именно то, что вы ищете.

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

Затем, позже:

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

Ответ 4

Я не думаю, что это легко достижимо. Позвольте пояснить:

Для достижения желаемого вам понадобится хэш-карта, которая позволяет объекты в позиции клавиш. Однако JavaScript не поддерживает объекты как ключи в хэшмапах. Так, например, следующее не работает:

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

map[key] = data;

В существующих реализациях javascript есть другие решения, например. двойной поиск:

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;

Эта реализация, однако, имеет ужасную производительность. В JavaScript Harmony есть предложение для так называемого WeakMap. Firefox, я считаю, в настоящее время является единственным браузером, реализующим их. Поскольку требуемая функция не является широко доступной, и обходные решения имеют низкую производительность, я бы рекомендовал попытаться выяснить другой способ достижения того, что вы пытаетесь сделать.

Ответ 5

Как я понимаю, вы ищете какой-то сахарный способ запуска нескольких именованных поисков в DOM и результаты отфильтровываются в объекте пространства имен.

Если это так, я думаю, для вас может быть полезно следующее расширение jquery:

$.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;
}

И вот пример того, как указанное расширение может быть применимо к вашим случаям:

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

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

Надеюсь, это поможет вам.

Ответ 6

Не уверен, что это то, что вы ищете. Возможно, вы можете написать пользовательский селектор, основанный на селекторе jquery, который обрабатывает объекты с помощью свойства selector, как вам нравится. Выбираемый объект будет выглядеть как

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

Таким образом, вы можете использовать его как любой другой объект, но вам нужно добавить свойство selector. Чем вы добавляете свой пользовательский селектор:

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

Теперь вы можете делать что-то вроде

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

См. реализацию на http://jsfiddle.net/JXcnJ/

Ответ 7

Если я правильно понял, я думаю, вам нужно определить свойство и сказать enumerable как false. См. Ниже,

Примечание: Ниже приведен пример, демонстрирующий и не предназначенный для этого,

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]);
    }
});

Ссылка: http://yehudakatz.com/2011/08/12/understanding-prototypes-in-javascript/