Атрибуты fontawesome не обновляются с помощью jquery

Я использую SVG с потрясающим шрифтом, у меня были проблемы с scope ранее, но теперь у меня возникла новая проблема - я спросил об этой проблеме в комментарии к другому моему вопросу, и мне сказали, что это совершенно отдельная проблема.

Вот мой текущий код:

$('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 () выше не работает, кажется, что элемент нельзя изменить изнутри функции успеха?)

Теперь, когда я делаю 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>

и я использую отличный шрифт CDN версии v5.0.8.

Я пробовал несколько вещей, например, редактирование атрибутов напрямую, как вы видите здесь, и обнаружил, что это правильный способ сделать это из этот вопрос StackOverflow, и я также попытался отредактировать фактический класс объекта SVG ($ (this) в контексте), но у него также не было эффект.

Когда я проверяю элемент объекта, хром сообщает мне, что код активирован, потому что тег элемента вроде «мигает», но на самом деле никакие данные не меняются.

Что не так?


person GrumpyCrouton    schedule 13.03.2018    source источник
comment
Ваш спиннер никогда не уходит, потому что вы никогда не говорите ему об этом. По крайней мере, в предоставленном вами коде. Если вы console.log () ответите, будет ли он == 1 при первом щелчке?   -  person Ryan Gibbs    schedule 13.03.2018
comment
@RyanGibbs Что ты имеешь в виду, я никогда не говорю об этом? В функции успеха он либо превращается в значок пустого поля, либо на значок флажка. Счетчик активируется только непосредственно перед вызовом ajax, два кода атрибута внутри функции успеха должны вернуть его в обычное состояние. Что касается it == 1, это зависит от обстоятельств. Каждый второй щелчок поворачивает возвращаемое значение, потому что это логическое значение. Итак, первый щелчок может == 0, второй - == 1, затем 0 и т. Д.   -  person GrumpyCrouton    schedule 13.03.2018
comment
@RyanGibbs Проблема в том, что внутри функции успеха ничего не меняет по какой-то причине на странице - это то, что я пытаюсь понять.   -  person GrumpyCrouton    schedule 13.03.2018
comment
Извините, не обращайте на это внимания. Я неправильно понял, что вы делали со свойством значка данных.   -  person Ryan Gibbs    schedule 13.03.2018
comment
@RyanGibbs Все хорошо :)   -  person GrumpyCrouton    schedule 13.03.2018
comment
Обновление @RyanGibbs упрощает понимание   -  person GrumpyCrouton    schedule 13.03.2018
comment
Итак, я читал об этом и думаю, что это связано с тем, как он заменяет ‹i› на ‹svg›. В документации указано, что вы должны использовать .toggleClass (), чтобы удалить старый класс и каждый раз добавлять новый. Однако мне не удалось заставить это работать в jsfiddle.   -  person Ryan Gibbs    schedule 13.03.2018
comment
@RyanGibbs Если это правда, то почему первоначальное изменение значка загрузки работает нормально?   -  person GrumpyCrouton    schedule 13.03.2018
comment
Хорошо, я разобрался. Отправляю ответ для вас.   -  person Ryan Gibbs    schedule 13.03.2018


Ответы (2)


См. обновление ниже ...

Исходный ответ:

Такое поведение происходит из-за комбинации использования ключевого слова this и способа обработки анимированных значков с потрясающим шрифтом. Как мы обсуждали в комментариях, он заменяет тег на один, однако, читая их документацию, я увидел, что он делает это с каждым изменением, это очень динамично.

Проблема в том, что когда вы передаете ключевое слово this в свой контекст ajax, вы блокируете этот экземпляр элемента управления svg, но после этого он заменяется. Поэтому, когда вы возвращаете this, вы видите, что класс в старом элементе управления успешно изменился, но новый элемент управления по-прежнему имеет счетчик.

Решением этой проблемы является использование «$ ('[data-fa-i2svg]')» вместо «$ ('this')» в вашей успешной функции обратного вызова. Это нацелено на текущий элемент управления.

Я нашел это решение здесь:

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

В нем говорится: «Если вам абсолютно необходимо прикрепить события к значку, вы можете использовать атрибут data-fa-i2svg, но вам нужно разрешить динамическое создание элемента svg».

Обновление:

Использование селектора «$ ('[data-fa-i2svg]')» не работает, если у вас есть несколько значков на одной странице, поскольку он обновит их все.

Вы можете установить свойство font awesome, которое будет вкладывать 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');
    }
} 
person Ryan Gibbs    schedule 13.03.2018
comment
Как это будет работать, если на странице есть несколько значков, которые работают одинаково? - person GrumpyCrouton; 13.03.2018
comment
В самом низу документации говорится, что вы можете переключиться на вложенный файл svg. FontAwesomeConfig = {autoReplaceSvg: 'гнездо'}. Затем вы можете использовать селектор, нацеленный на ‹i›, и изменить дочерний элемент этого ‹i›. - person Ryan Gibbs; 13.03.2018
comment
Спасибо, что нашли время посмотреть и ответить на мой вопрос, я очень ценю это. - person GrumpyCrouton; 13.03.2018

Ответ Райана Гиббса точен, но его решение не совсем то, что мне нужно.

Райан заявил, что:

Такое поведение происходит из-за комбинации использования ключевого слова this и способа обработки анимированных значков с потрясающим шрифтом.

а также:

Решением этого является использование «$ ('[data-fa-i2svg]')» вместо «$ ('this')» в вашей успешной функции обратного вызова. Это нацелено на текущий элемент управления.

Однако это изменило ВСЕ значки на странице. Мне это кажется очень странным поведением по умолчанию, но независимо от моего решения было просто назначить идентификатор каждому значку, связанному с этим событием onclick.

Я использовал свой уже уникальный uid из моей базы данных, чтобы назначить идентификатор с именем taskid-#, это должно работать независимо от того, сколько их находится на странице, потому что идентификатор всегда уникален.

Затем в моем успешном обратном вызове вместо использования $(this) я просто вызвал элемент напрямую по его идентификатору, который, похоже, сработал.

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');
    }
}
person GrumpyCrouton    schedule 13.03.2018