Data Attribute does not apply css after modify the value by jQuery

ぐ巨炮叔叔 提交于 2019-12-10 20:17:57

问题


I would like to implement a check list by list item (li). I use data-checked attribute to keep the checking state. I set the icon color with css selector ('true' = black and 'false' = white color).

It work fine when the page display, all tasks show the white icon as their default data-checked value is 'false'. But when I click the list items, the data-checked value is modified to 'false', but the color does not change to black.

I have checked the value by alert them. They are properly.

What am I doing wrong?

Thank you.

HTML:

<ul>
  <li data-id='1' data-checked='false' onclick='toggle_task(this);'>
    <i class='fs fa-check'></i>
    <span>Task A</span>
  </li>
  <li data-id='2' data-checked='false' onclick='toggle_task(this);'>
    <i class='fs fa-check'></i>
    <span>Task B</span>
  </li>
</ul>
<button onclick='show_checked();'>Done</button>

CSS:

ul li[data-checked='true'] i:first-child {
  color: #000000;
}
ul li[data-checked='false'] i:first-child {
  color: #eeeeee;
}

Javascript:

function toggle_task(sender) {
  if ($(sender).data('checked').toString == 'true') {
    $(sender).data('checked','false');
  } else {
    $(sender).data('checked','true');
  }
}
function show_checked() {
  $(li).each(function() {
    var text = $(this).data('id').toString() + ': ' + $(this).data('checked').toString();
    alert($(this).data('checked'));
  });
}

回答1:


I think you have become confused between the HTML data-* attributes (which you are using as part of your CSS selector) and the jQuery data method which stores arbitrary JavaScript objects associated with the element but outside of the DOM. The confusion probably comes from this-

.data( key ) Returns: Object Description:

Return the value at the named data store for the first element in the jQuery collection, as set by data(name, value) or by an HTML5 data-* attribute.

The method allows you to read data from HTML 5 data-* attributes if there is no value with that key in the jQuery collection, but not to set it.

What you want to do is use the jQuery attr method like this-

function toggle_task(sender) {
  if ($(sender).attr('data-checked') === 'true') {
    $(sender).attr('data-checked','false');
  } else {
    $(sender).attr('data-checked','true');
  }
}

function show_checked() {
  $('li').each(function() {
    var text = $(this).attr('id') + ': ' + $(this).attr('data-checked');
    alert($(this).attr('data-checked')); //Consider using console.log rather than alert here
  }); //Fixed your jQuery selector - required quotes for li element - is not a JavaScript variable
}

As a bonus the attr method returns a string and not an object - so you can dispense with the toString calls.

I'm not entirely sure what you want to do visually, but if you want to have a coloured block need to the element indicating if it is checked or not (in which case the <i> element is not the most semantically appropriate) you also need to update your CSS-

/* These need to be background-color, not color */

ul li[data-checked='true'] i:first-child {
  background-color: #000000;
}
ul li[data-checked='false'] i:first-child {
  background-color: #eeeeee;
}

/* Also need to add these styles to actually see the empty elements */

.fa-check {
    display: inline-block;
    height: 0.5em;
    width: 0.5em;
}

I have created JSFiddles of your original code and the updated code which is worked as I think you want it to.

Please, please, please consider using unobtrusive event handlers with jQuery using the jQuery on method rather than having inline "onclick" attributes. This keeps your JavaScript logic separate from your HTML content, see http://en.wikipedia.org/wiki/Unobtrusive_JavaScript.



来源:https://stackoverflow.com/questions/23152398/data-attribute-does-not-apply-css-after-modify-the-value-by-jquery

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!