为什么.addClass()和.removeClass()没有按预期工作?

时间:2015-09-12 03:58:05

标签: javascript jquery html

我用google搜索和谷歌搜索以及搜索Stackoverflow。在查看了大约二十个其他问题并且没有看到相同情况之后,我决定发布一个新问题。

我不需要帮助让这个工作。我只想了解为什么它不起作用。这对我没有任何意义。所以,我的问题是:

为什么将jQuery对象保存到变量会导致.addClass() / .removeClass()不起作用?

我正在尝试做什么

我有一个span的课程fa fa-eye,我想将fa-eye课程更改为fa-eye-slash,然后再点按一下按钮。

什么不起作用

这是我的HTML:

<button id='visibility-toggle' data-status='hidden'>
  <span class='fa fa-eye'></span>
  Show
</button>

这是我的无效 JavaScript:

jQuery('#visibility-toggle').click(function(e){
  e.preventDefault();
  var button = jQuery(this);
  var icon = button.find('.fa');
  if(button.data('status') === 'hidden') {
    show_stuff();
    button.html(button.html().replace('Show', 'Hide'));
    icon.addClass('fa-eye-slash');
    icon.removeClass('fa-eye');
    button.data('status', 'visible');
  } else {
    hide_stuff();
    button.html(button.html().replace('Hide', 'Show'));
    icon.addClass('fa-eye');
    icon.removeClass('fa-eye-slash');
    button.data('status', 'hidden');
  }
});

字符串替换正在运行,显示/隐藏功能正在运行。添加/删除类功能无效。

我也试过做这些改变。

HTML:

  <span class='show-icon fa fa-eye'></span>

JS:

  var icon = jQuery('.show-icon');

......仍然没有工作。

工作正常

但是这里是踢球者。这个有效(不是将jQuery对象保存到icon变量,而是每次只查找它):

jQuery('#visibility-toggle').click(function(e){
  e.preventDefault();
  var button = jQuery(this);
  if(button.data('status') === 'hidden') {
    show_stuff();
    button.html(button.html().replace('Show', 'Hide'));
    jQuery('.show-icon').addClass('fa-eye-slash');
    jQuery('.show-icon').removeClass('fa-eye');
    button.data('status', 'visible');
  } else {
    hide_stuff();
    button.html(button.html().replace('Hide', 'Show'));
    jQuery('.show-icon').addClass('fa-eye');
    jQuery('.show-icon').removeClass('fa-eye-slash');
    button.data('status', 'hidden');
  }
});

所以,我的问题是: 为什么将jQuery对象保存到变量会导致.addClass() / .removeClass()不起作用?

我多年来一直在使用jQuery,之前从未注意过这种行为。这看起来很奇怪。我只是缺少一些超级简单的东西吗?我太累了吗?

其他信息

我在Google Chome Version 45.0.2454.85 (64-bit) Ubuntu 14.04.3上看到此行为。我没有尝试过其他浏览器或其他系统。

我正在使用jQuery 2.1.3来自https://code.jquery.com/jquery-2.1.3.min.js

如果我在控制台中运行此代码,它将按预期工作。

var icon = jQuery('.show-icon');
icon.addClass('fa-eye-slash');
icon.removeClass('fa-eye');
icon.addClass('fa-eye');
icon.removeClass('fa-eye-slash');

当我在控制台中console.log(icon)console.log(jQuery('.show-icon'))时,它们看起来完全一样。

[span.show-icon.fa.fa-eye, prevObject: n.fn.init[1], context: document, selector: ".show-icon"]

我能够始终如一地来回切换代码以及它的一种工作方式,另一种方式则不然。

编辑:这是现在按预期工作的

HTML:

<button id='visibility-toggle' data-status='hidden'>
  <span class='fa fa-eye'></span>
  <span class='text'>Show</span>
</button>

JS:

jQuery('#visibility-toggle').click(function(e){
  e.preventDefault();
  var button = jQuery(this);
  var icon = button.find('.fa');
  var text = button.find('.text');
  if(button.data('status') === 'hidden') {
    show_stuff();
    text.text(text.text().replace('Show', 'Hide'));
    icon.addClass('fa-eye-slash');
    icon.removeClass('fa-eye');
    button.data('status', 'visible');
  } else {
    hide_stuff();
    text.text(text.text().replace('Hide', 'Show'));
    icon.addClass('fa-eye');
    icon.removeClass('fa-eye-slash');
    button.data('status', 'hidden');
  }
});

我知道这很难看。我会在早上重构它。

1 个答案:

答案 0 :(得分:4)

当您用.html()替换文档块时,您将丢弃代表这些元素的所有DOM对象,并创建一堆新对象。您保存的图标副本是指被.html替换的被抛弃的对象。避免像瘟疫一样.html - 使用.attr.text.empty .append等正确修改对象。.html是一个安全漏洞等待发生。