14

有什么方法可以通过对象选择 DOM 元素?

例如,我希望能够将对象与 DOM 元素相关联,如下所示:

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

而后来...

$.something(obj);

甚至更好:

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

类似的东西。你可以看到我想将一个对象关联到一个 DOM 元素,这样我就可以用对象抓取元素。

我知道这可以通过该filter()方法来完成,我的问题是是否有更优雅的方式不filter()用于执行此操作。

编辑:

澄清一下,我希望能够使用一种类似于选择器的对象,所以我可以做类似的事情,这$(obj)显然是行不通的,但你明白了(我希望)

编辑#2:

我希望能够做这样的事情:

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

我不希望它以obj任何方式改变(obj应该仍然是{prop: 'prop'}唯一的)。

4

7 回答 7

8

演示

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


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


或者简短的方法:var obj = { a: $('.box1'), b: $('.box2') };


演示 jsBin 2

var obj = $('.box1, .box2'); // store objects
obj.css({background:'red'}); // access collection
于 2012-04-30T01:12:16.100 回答
2

你正在寻找$.data. 此方法将任何 JavaScript 对象或原语与 DOM 元素相关联。在底层,它不会将数据作为扩展添加到 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'}
于 2012-04-30T01:04:52.317 回答
2

我不认为这很容易实现。让我澄清一下:

要实现您想要的,您需要一个允许对象位于键位置的哈希图。JavaScript (目前)不支持对象作为 hashmap 中的键。因此,例如,以下内容不起作用:

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 是目前唯一实现它们的浏览器。由于所需的功能没有广泛使用,而且变通方法的性能很差,我建议尝试找出一种不同的方法来实现你想要的。

于 2012-05-03T12:21:52.093 回答
1

据我了解,您正在寻找某种糖方法来在 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' });

我希望这可以帮助你。

于 2012-05-07T18:43:04.500 回答
1

不确定这是否是您正在寻找的。也许您可以编写一个基于 jquery 选择器的自定义选择器,它以您喜欢的方式处理具有选择器属性的对象。一个可选择的对象看起来像

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

所以你可以像任何其他对象一样自由使用它,但你必须添加选择器属性。比您添加自定义选择器:

$$ = (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/上的实现

于 2012-05-07T18:55:48.933 回答
1

如果我当时理解正确,我认为您需要定义一个属性并说enumerable为假。见下文,

注意:下面只是一个演示示例,并不完全是为了做这些事情,

演示

$(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/

于 2012-05-08T22:02:27.800 回答
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 集合。

于 2012-05-08T22:43:54.433 回答