fontawesome 属性未使用 jquery 更新

fontawesome attributes not updating with jquery

我正在使用超棒的 SVG 字体,之前 我遇到了一些问题,但现在我遇到了一个新问题 - 我在对我的其他问题的评论中询问了这个问题,并被告知这是一个完全不同的问题。

这是我当前的代码:

$('body').on('click','.switchButton', function(){
    $(this).attr('data-prefix', 'fas').attr('data-icon', 'spinner').addClass('fa-pulse');
    $.ajax({
        url: 'tasks/update_table.php',
        type: 'post',
        data: { "uid": $(this).attr('data-uid')},
        context: this,
        success: function(response) { 
            $(this).attr('data-icon', 'check-square').removeClass("fa-pulse");
            if(response == 1) {
                $(this).attr('data-prefix', 'far');
            } else {
                $(this).attr('data-prefix', 'fas');
            }
            console.log(this);
        }
    });
});

(注意:即使是上面的 removeClass() 也 not 起作用,似乎无法从成功函数内部更改元素?)

现在,当我 console.log(this) 时,我得到了一些对我来说很奇怪的结果。

我第一次点击图标,console.log()我得到这个结果:

<svg class="svg-inline--fa fa-square fa-w-14 fa-lg switchButton fa-pulse" data-uid="1" aria-hidden="true" data-prefix="fas" data-icon="check-square" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" data-fa-i2svg="">

之后每次,我总是得到这个结果:

<svg class="svg-inline--fa fa-spinner fa-w-16 fa-lg switchButton fa-pulse" data-uid="1" aria-hidden="true" data-prefix="far" data-icon="check-square" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" data-fa-i2svg="">

而且实际页面上的图标永远不会改变,它只是保持为微调器。我真的不明白这里出了什么问题。这看起来应该是一件很简单的事情,但对我不起作用。

该元素最初在页面上加载为:

<i data-uid="<?=$task['uid'];?>" class="far fa-square fa-lg switchButton"></i>

并且我正在使用 font-awesome CDN 版本 v5.0.8。

我已经尝试了几种方法,比如直接编辑属性,就像你在这里看到的那样,我发现这是 的正确方法,我还尝试编辑实际的 class 的 SVG 对象(上下文中的 $(this) ),但这也没有效果。

当我检查对象上的元素时,chrome 告诉我代码已激活,因为元素标记排序为 "flashes",但数据的 none 实际上已更改。

出了什么问题?

请参阅下面的更新...

原回答:

此行为来自 'this' 关键字的使用和动画 font-awesome 图标的处理方式的组合。正如我们在评论中讨论的那样,它将标签替换为一个标签,但是,在阅读他们的文档时,我看到它在每次更改时都会这样做,它非常动态。

问题是,当您将 'this' 关键字传递到 ajax 上下文中时,您锁定了 svg 控件的那个实例,但之后它被替换了。因此,当您 return 'this' 时,您会看到 class 已在旧控件上成功更改,但新控件仍然具有微调器。

解决方法是在成功回调函数中使用“$('[data-fa-i2svg]')”而不是“$('this')”。以当前控件为目标。

我在这里找到了这个解决方案:

https://fontawesome.com/how-to-use/svg-with-js

上面写着"If you absolutely need to attach events to the icon you can use the data-fa-i2svg attribute but you need to allow for the dynamic creation of the svg element."

更新:

如果同一页面上有多个图标,则使用“$('[data-fa-i2svg]')”选择器不起作用,因为它会更新所有图标。

您可以设置一种很棒的字体 属性,它将 svg 嵌套在原始字体中,然后使用选择器获取该标签的子项。这行得通,但是我认为 GrumpyCrouton 仅使用 $('#taskid-'+uidOfTask); 的改编。在这种情况下可能更优雅。

由于这被标记为解决方案,我在下面包含了他的代码,但请参阅他的回答以获取更多详细信息。

success: function(response) { 
    var element = $('#taskid-'+uidOfTask);
    element.attr('data-icon', 'check-square').removeClass("fa-pulse");
    if(response == 1) {
        element.attr('data-prefix', 'far');
    } else {
        element.attr('data-prefix', 'fas');
    }
} 

Ryan Gibbs 的回答非常准确,但他的解决方案并不是我所需要的。

Ryan 表示:

This behavior comes from a combination of the use of the 'this' keyword and the way that the animated font-awesome icons are handled.

和:

The solution to this is to use "$('[data-fa-i2svg]')" instead of "$('this')" in your success callback function. That targets the current control.

但是,这改变了页面上 ALL 的图标。这对我来说似乎是非常奇怪的默认行为,但不管我的解决方案是为与此 onclick 事件相关的每个图标分配一个 ID。

我使用我的数据库中已经唯一的 uid 分配了一个名为 taskid-# 的 ID,无论页面上有多少,这都应该有效,因为 ID 始终是唯一的。

然后,在我的成功回调中,我没有使用 $(this),而是直接通过它的 ID 调用元素,这似乎有效。

success: function(response) { 
    var element = $('#taskid-'+uidOfTask);
    element.attr('data-icon', 'check-square').removeClass("fa-pulse");
    if(response == 1) {
        element.attr('data-prefix', 'far');
    } else {
        element.attr('data-prefix', 'fas');
    }
}