-4

I'm encountering a problem with the .data() function in jQuery.

My scenario.

  • I insert a span into a content-editable div using atWho (at.js)
  • I subscribe to a click event of this span.
  • When clicked I do some things which are irrelevant for the element itself.
  • When I've done what I want to do. I inset an Object into a data-attribute using .data()
  • I now repeat the steps above. However the Object I insert in the data-attribute is now inserted into not only the new element. But also the element I created before.

Both elements have a unique ID. I have not been able to create a jsfiddle as of yet.

I would not be asking this question if I had not looked at it from all possible angles.

I checked if jquery returned multiple elements after click: Not the case. I checked if the data was being appended to both elements: This is the case. I checked if something was wrong with my own code: Not the case.

Jquery states the following: "Store arbitrary data associated with the matched elements or return the value at the named data store for the first element in the set of matched elements.".

Obviously this is not what it does.

Below is the highly simplified version of what I mentioned I do in the above.

$('.item').click(function() {
  var dataIwantToAddToDomElement = doSomeStuffRelatedToTheClickedElement(this);
  $(this).data(dataIwantToAddToDomElement);

})

function doSomeStuffRelatedToTheClickedElement(element) {

  if ($(element).data('nameOfTheStuffIwantToUse')) {
    var stuff = $(element).data('nameOfTheStuffIwantToUse');
    //do stuff on var
  }

  return stuff;
}
Byebye
  • 934
  • 7
  • 24
  • At least show us your jquery to change the data. It might be the selector that is is too broad. – J.G.Sebring Nov 26 '15 at 13:21
  • 2
    Use `$(document).on('click', '#element_id', function(){...});` and don't use `.data()` to insert into data attribute, that won't happen. Use `.attr('data-attribute', 'inserted stuff here');` to insert. – dingo_d Nov 26 '15 at 13:21
  • 1
    @dingo_d `don't use .data() to insert into data attribute, that won't happen.` The data will be kept, but it's stored in jQuery's internal cache not in the DOM, for performance reasons. – Rory McCrossan Nov 26 '15 at 13:22
  • 2
    Yeah, but if he wants to change it, and then use again, he'll get the value in the internal cache, and I recon he wants the DOM value after the change. I had the same issue not long ago, and then I realized that I can't use the `.data()` to add and then read again on some click event (after some searching here on SO) :) – dingo_d Nov 26 '15 at 13:25
  • @RoryMcCrossan OP said: `I inset an Object into a data-attribute using .data()` That is wrong. `dingo_d` said: `don't use .data() to insert into data attribute` That is true. – A. Wolff Nov 26 '15 at 13:27
  • @A.Wolff unless I'm missing your point, storing an object against an element using `data()` is not wrong, see: http://jsfiddle.net/0vy99fzq/. This is all moot though, as it's next to impossible the diagnose the issue in the question without seeing any code. – Rory McCrossan Nov 26 '15 at 13:34
  • @RoryMcCrossan My point was just that updating data property object doesn't update data attribute value. What you say is correct and what dingo said is correct too – A. Wolff Nov 26 '15 at 13:38
  • 2
    Ah right, now I see what you mean. I think we're all on the same page :) – Rory McCrossan Nov 26 '15 at 13:40
  • @dingo_d Sorry for the late response but the answer that you gave solved the problem. Could you provide an actual answer below? I will mark that as the answer. – Byebye Nov 26 '15 at 15:12
  • I added the requested code. If you would be so kind as to remove your downvotes that would be appreciated. – Byebye Dec 03 '15 at 13:23

1 Answers1

0

Since we didn't see the actual code I'll just put here what I've said in the comment. Say you have some HTML element that you'd want to access it on click event.

<div id="some_div" data-attribute="some content is here"></div>

You can access this div, and it's data properties, on click, in several ways:

jQuery(document).ready(function($){
    $('#some_div').on('click', function(){
        var div_data = $(this).data('attribute');
    });
});

This will give you the data-attribute contents of the #some_div. The 'drawback' of this method is that you are accessing a static object. It's not a drawback per se. It's a valid method if you want to bind event to a specific element.

But if you were to dynamically added elements, then you'd want to use:

jQuery(document).ready(function($){
    $(document).on('click', '#some_div', function(){
        var div_data = $(this).data('attribute');
    });
});

You are delegating events on the document objects children. This post recommends using closest parent that exists on page load to target (if possible)..

Now the part that was worrying you was that using

jQuery(document).ready(function($){
    $(document).on('click', '#some_div', function(){
        var div_data = $(this).data('attribute');
        $('#other_div').data('new_attribute', div_data);
    });
});

probably showed in the DOM that the data-new_attribute of the #another_div` changed, but when you then tried to fetch it using the same method, you got the data that was originally in it. But it changed in the inspector!

That's because, as Rory McCrossan pointed out, the data is kept in jQuery internal cache, and not the DOM. So you're just fetching the data attribute that was in #another_div in the first place.

What you need to use is good old .attr(). So what you'll use is

jQuery(document).ready(function($){
    $(document).on('click', '#some_div', function(){
        var div_data = $(this).data('attribute');
        $('#other_div').attr('data-new_attribute', div_data);
    });
});

If you'd try to output the data-new_attribute in the console after the click, you'd see the updated value.

Hope this helps.

Community
  • 1
  • 1
dingo_d
  • 11,160
  • 11
  • 73
  • 132