jQuery toggle()函数在初始状态未知的情况下的使用

4

我正在开发一个项目,其中使用一张小图片来标记表格中多行记录的收藏状态。数据从数据库中获取,图片基于该项是否为收藏项。如果是收藏项,则使用一张图片,否则使用另一张不同的图片。我希望用户能够切换图片并将其设为收藏或非收藏状态。以下是我的代码:

$(function () {
    $('.FavoriteToggle').toggle(
      function () {
        $(this).find("img").attr({src:"../../images/icons/favorite.png"});
        var ListText = $(this).find('.FavoriteToggleIcon').attr("title");
        var ListID = ListText.match(/\d+/);
        $.ajax({
            url: "include/AJAX.inc.php",    
            type: "GET",
            data: "action=favorite&ItemType=0&ItemID=" + ListID,        
            success: function () {}     
        });
      },
      function () {
        $(this).find("img").attr({src:"../../images/icons/favorite_not.png"});
        var ListText = $(this).find('.FavoriteToggleIcon').attr("title");
        var ListID = ListText.match(/\d+/);
        $.ajax({
            url: "include/AJAX.inc.php",    
            type: "GET",
            data: "action=favorite&ItemType=0&ItemID=" + ListID,        
            success: function () {}     
        });
      }
     );
});

如果初始状态不是一个收藏夹,它运行得非常好。但如果它最初是一个收藏夹,你必须双击才能改变图像。这会导致 AJAX 两次触发,本质上使其在图像响应之前成为一个收藏夹然后不再是收藏夹。用户认为他已经将其添加到收藏夹中,因为图像发生了变化,但实际上并没有。有人可以帮忙吗?

@Jason:你打算在某个时候评估/评论/接受其中一个答案吗? - Tomalak
4个回答

1
给favoriteToggle添加一个定义状态的class。使用该class来定义图标的css样式,而不是替换图片。这样可以轻松确定favoriteToggle的状态。
$(function() {
$('.FavoriteToggle').click(function(){
    var $this = $(this);
    var id = $this.find('.FavoriteToggleIcon').attr("title").match(/\d+/);
    if ($this.hasClass('isFavorite')){
        $this.removeClass('isFavorite');
    } else {
        $this.addClass('isFavorite');
    }
    $.ajax({
        url: "include/AJAX.inc.php",    
        type: "GET",
        data: "action=favorite&ItemType=0&ItemID=" + id,        
        success: function () {}     
    });
})
});

添加到你的CSS中:
.FavoriteToggle .icon{
    background: url("../../images/icons/favorite_not.png");
}
.FavoriteToggle.isFavorite .icon{
    background: url("../../images/icons/favorite.png");
}

这样做可以定义一个状态的类,因此您可以通过它执行更多操作,而不仅仅是更改图像。它还可以使您在JavaScript中定义图像路径,而这通常是不明智的。


0

不知道这是否符合您的要求 - 但我通常将其用作切换功能 - 并且通过一些额外的PHP代码,我甚至可以将其调整为一个或另一个初始状态:

<style type="text/css">
<!--
.mybox_edit { 
display: none; 
} 
-->

</style>

<script language="JavaScript" type="text/JavaScript">
<!--

function toggleBox( box_id ) { 
var box_edit = document.getElementById(box_id + "_edit"); 
var box_show = document.getElementById(box_id + "_show"); 

// is it hidden? 
if ( box_show.style.display == 'none' ) { 
box_show.style.display = 'block'; 
box_edit.style.display = 'none'; 
} else { 
box_show.style.display = 'none'; 
box_edit.style.display = 'block'; 
} 
}
//-->
</script>

这可能有效,但它绝对不是jQuery。我正在加载jQuery库,并希望充分利用它的开销。 - Jason Morhardt

0
$(function () {
  // toggle on click
  $('.FavoriteToggle').click ( function() {
    // prevent duplicate AJAX request with a "loading" flag
    if (!this.isLoading) {
      var $img   = $(this).find("img");
      var ListID = $(this).find('.FavoriteToggleIcon').attr("title").match(/\d+/);

      // flag that we are currently loading something
      this.isLoading = true;       

      // determine the action from the current state of the img 
      if ($img.attr("src").indexOf("favorite.png") > -1)
        var actionVerb = "unFavorite";
      else
        var actionVerb = "mkFavorite";

      $.ajax({
        url: "include/AJAX.inc.php",    
        type: "GET",
        data: {action: actionVerb, ItemType: 0, ItemID: ListID },
        success: function($i) {
          return function() { 
            // change image on success only
            if ($i.attr("src").indexOf("favorite.png") > -1) {
              $i.attr("src", "../../images/icons/favorite_not.png";
            else
              $i.attr("src", "../../images/icons/favorite.png";
          };
        }($img),
        error: function(xhr, textStatus, errorThrown) { 
          // make some note of the error
          alert(textStatus);
        }
        complete: function(p) {
          return function(xhr, textStatus) { 
            // set loading flag to false when done
            p.isLoading = false; 
          };
        }(this)
      });
    }
  });
});

未经测试,但你应该能够理解。

整个 if ($img.attr("src").indexOf("favorite.png") 的部分可以通过向 <img> 添加一个 favorite CSS 类来更轻松地完成。例如,在主函数中:

var actionVerb = $img.is(".favorite") ? "unFavorite" : "mkFavorite";

并且,在success回调函数中:

if ($i.is(".favorite"))
  $i.attr("src", "../../images/icons/favorite_not.png";
else
  $i.attr("src", "../../images/icons/favorite.png";

// now toggle the CSS class
$i.toggleClass("favorite")

0

好的,这是我最终得出的结果,一个简化版的PetersenDidit's post

$('.FavoriteToggle').click(function() {
    var id = $(this).attr("title").match(/\d+/);
    if ($(this).hasClass('isFavorite')) {
        $(this).removeClass('isFavorite');
    } else {
        $(this).addClass('isFavorite');
    }
    $.ajax({
        url: "include/AJAX.inc.php",
        type: "GET",
        data: "action=favorite&ItemType=0&ItemID=" + id,
        success: function() {
        }
    });
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接