Обновление отображаемых текстовых элементов после динамического изменения класса CSS с помощью JQuery - PullRequest
0 голосов
/ 04 июля 2018

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

Проблема, которую я пытаюсь решить, - обновить этот цвет с помощью AJAX без перезагрузки страницы.

Я применяю цвет, назначая класс, который соответствует каждому пользователю и истории, которую он отправляет:

<span class="<%= "contrib-u#{snippet.user.id}-s#{@story.id}" %>">
  (code to display text submission)
</span>

Я создаю классы для каждого пользователя, которые соответствуют этому формату contrib-u1-s2 (вклад для пользователя 1, история 2), используя JQuery один раз при загрузке приложения:

$(document).one 'turbolinks:load', ->                                               
  build_contribution_styles()                                                       

build_contribution_styles = ->                                                      
  req = $.get('/contributions/index')                                               

  req.done (data) ->                                                                
    user_sheet = document.styleSheets[5]                                            

    for contribution in data                                                        
      user_sheet.addRule(                                                           
        ".contrib-u" + contribution['user_id'] + "-s" + contribution['story_id'], 
        "color: #" + contribution['color']                                          
      )

Пока это прекрасно работает. Представление каждого пользователя для каждой истории правильно окрашено на основе этих динамически созданных классов.

Далее я предоставляю пользователю текстовое поле, чтобы он мог выбрать новый цвет для своих представлений:

<%= text_field_tag :snippet_color,
  current_user.get_contribution_color(@story),
  class: "jscolor centered-text",
  data: {user_id: current_user.id, story_id: @story.id}
%>

Затем в JQuery я присоединяю прослушиватель событий к этому текстовому полю, чтобы обновить базу данных и классы вновь выбранным цветом:

$(document).on 'turbolinks:load', ->                                                                                         
  $('#snippet_color').change (e) -> handle_snippet_color_change(e, @)                                                                                                                              

handle_snippet_color_change = (e, input) ->                                         
  data = {                                                                          
    contribution: {                                                                 
      story_id: $(input).data('story-id'),                                          
      user_id: $(input).data('user-id'),                                            
      color: $(input).val()                                                         
    }                                                                               
  }                                                                                 

  req = $.post('/contributions/update', data)                                       

  req.done (data) ->                                                                
    els = $('.contrib-u' + data['user_id'] + '-s' + data['story_id'])                                                                                                                                                                                                                                            
    els.css('color', data['color'])

Это тоже хорошо работает, но только после перезагрузки страницы. Обновления класса не применяются к элементам до тех пор.

Это несколько смущает меня, потому что есть ряд других случаев, когда я динамически изменяю стиль CSS элемента с помощью javascript, и он изменяется без обновления страницы. Например, много раз в этом приложении я выбираю элемент и переключаю его свойство display, чтобы скрыть или показать его.

Я нашел несколько источников информации о «перезагрузке стиля CSS без обновления страницы», но ни один из них, похоже, не решает эту конкретную проблему. Одно из предложений заключалось в том, чтобы поместить эти новые правила CSS в тег стиля на странице с этими элементами, чтобы они автоматически обновлялись без перезагрузки, но в моем случае это не имеет значения.

РЕДАКТИРОВАТЬ: рабочий раствор

Теперь он работает, удалив предыдущее правило и добавив обновленное правило в таблицу стилей:

req = $.post('/contributions/update', data)

req.done (data) ->                                                                      
  selector = '.contrib-u' + data['user_id'] + '-s' + data['story_id']          
  sheet = document.styleSheets[5]                                              
  rules = sheet.cssRules                                                       

  for i in [0...rules.length]                                                  
    if rules[i].selectorText is selector                                       
      sheet.deleteRule(i)                                                      
      sheet.addRule(selector, "color: #" + data['color'])

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...