I have a DOM element like this:
<div id='master-value'>Apples</div>
I have many other elements elsewhere on the page that I need to sync with the 'master-value'.
<div class='fruit-value' data-reference='master-value'>Apples</div>
<div class='some-fruit' data-reference='master-value'>Apples</div>
When I change the value of the 'master-value', I want all the synced elements to update with it.
$('#master-value').text('Pears');
Should affect:
<div class='fruit-value' data-reference='master-value'>Pears</div>
<div class='some-fruit' data-reference='master-value'>Pears</div>
What I don't want, is on every change of 'master-value' to have to search through all the elements in order to find the synced elements in order to change them. I think that's quite slow when there are many elements that needs to be searched through.
There should be some way for the child values to be pre-bound to the master value so that the selection goes quickly.
$('.fruit-value, .some-fruit').sync('#master-value');
I have some ideas, for instance: I can create an array of preselected synced objects, bind a custom event on the master value and run that event whenever I change the value. The event would go through the array to update all the child elements.
I'm sure there's a better way of doing it though...
Thanks!
I have a DOM element like this:
<div id='master-value'>Apples</div>
I have many other elements elsewhere on the page that I need to sync with the 'master-value'.
<div class='fruit-value' data-reference='master-value'>Apples</div>
<div class='some-fruit' data-reference='master-value'>Apples</div>
When I change the value of the 'master-value', I want all the synced elements to update with it.
$('#master-value').text('Pears');
Should affect:
<div class='fruit-value' data-reference='master-value'>Pears</div>
<div class='some-fruit' data-reference='master-value'>Pears</div>
What I don't want, is on every change of 'master-value' to have to search through all the elements in order to find the synced elements in order to change them. I think that's quite slow when there are many elements that needs to be searched through.
There should be some way for the child values to be pre-bound to the master value so that the selection goes quickly.
$('.fruit-value, .some-fruit').sync('#master-value');
I have some ideas, for instance: I can create an array of preselected synced objects, bind a custom event on the master value and run that event whenever I change the value. The event would go through the array to update all the child elements.
I'm sure there's a better way of doing it though...
Thanks!
Share Improve this question edited Aug 19, 2010 at 21:36 Mark asked Aug 19, 2010 at 20:52 MarkMark 33.7k34 gold badges108 silver badges139 bronze badges 4- I don't understand how you discriminate between elements to be "synchronized" and elements that you wouldn't synchronize. If you were to implement it the bad way, what would that look like? Is it based on the content of the elements? – Pointy Commented Aug 19, 2010 at 20:59
- @Pointy the element itself have the reference it when it is brought in via ajax. sorry I'm somehow really tired and this question was constructed quite poorly. – Mark Commented Aug 19, 2010 at 21:34
- @Pointy well Chris van de Steeg's way would probably be the bad way I described. Nick's solution would cache the traversal step, but then I would have to add each element to the cache when they're created. I think in my magical fantasy land there's a way to bind each syncing element to the master value so that it would update itself without doing anything from the master side. But that probably means some kind of timer, and would end up being bad for performance. – Mark Commented Aug 19, 2010 at 21:51
- Well, it's not like there's any magic sauce inside the browser that could make some "syncWith" mechanism not involve iterating over a list of elements and updating a cache upon DOM modifications. I doubt that doing that (with good code) in Javascript would be much worse than an "inside the browser" implementation. – Pointy Commented Aug 19, 2010 at 22:06
4 Answers
Reset to default 2You can store the selector once, like this:
var elements = $('.fruit-value, .some-fruit'); //do this once
elements.text($("#master-value").text()); //when you want to sync
The elements
variable/jQuery object will keep an array of references to DOM elements so it won't be traversing to find them each time.
wouldn't it be easier to give them all the same class?
So you coud do
$('.fruit').text('Pears')
If you're looking for plugin type of functionality, try this:
When setting up, it takes an object with one property syncWith
to set up the elements it should sync with.
When setting the text, it will set the text for the master and the synced elements.
Try it out: http://jsfiddle/GH33J/
Just a first attempt. There would be room for improvement if (for example) the master was more than one element. There should be a global reference to all the elements to synchronize and an option to tell if the masters should be synced too.
$.fn.sync = function(arg) {
// if arg plain object, we are doing an initial setup
if ($.isPlainObject(arg)) {
return this.each(function() {
$.data(this, 'syncWith', $(arg.syncWith));
});
// if arg is jQuery object, we are adding new items
} else if (arg.jquery) {
return this.each(function() {
var $set = $.data(this, 'syncWith');
$.each(arg, function() {
$set.push(this);
});
});
console.log(this.data('syncWith'));
// otherwise assume we have a string, and are syncing a new value
} else {
return this.each(function() {
$(this).text(arg);
$.data(this, 'syncWith').text(arg);
});
}
};
// Set up the sync
$('#master-value').sync({
syncWith: '.fruit-value,.some-fruit'
});
var $new = $('<div class="fruit-value">Apples</div>').appendTo('body');
// Pass a jQuery object containing newly created element(s) to add to the set
$('#master-value').sync($new);
// Activate a sync
$('#master-value').sync("pears");
OK here we go:
This is the official data linking plugin from Microsoft. It's now being supported by the jQuery Core team, so we know it's good. :)
http://weblogs.asp/scottgu/archive/2010/05/07/jquery-templates-and-data-linking-and-microsoft-contributing-to-jquery.aspx
http://blog.jquery./2010/10/04/new-official-jquery-plugins-provide-templating-data-linking-and-globalization/