Событие jQuery, которое срабатывает после загрузки CSS? - PullRequest
24 голосов
/ 03 апреля 2010

У меня есть пара ссылок на моей странице (внутри <div id="theme-selector">), которые позволяют вам изменять таблицы стилей CSS:

$('#theme-selector a').click(function(){
  var path = $(this).attr('href');
  $('head link').remove();
  $('head').append('<link type="text/css" href="'+path+'" rel="stylesheet" />');
  return false;
});

Теперь, после того как я изменил стиль на странице, я хочу получить новый цвет фона, используя следующий код (который я ставлю после вызова $('head').append):

var bgcolor = $('body').css('background-color');
alert(bgcolor); 

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

В настоящий момент все, о чем я могу думать, это использовать setTimeout(function(){}, 5000);, что не очень хорошо, потому что, если загрузка всего CSS на странице займет больше или меньше.

Дайте мне знать, если мне нужно что-то прояснить, и я смогу предоставить больше кода.

Ответы [ 6 ]

19 голосов
/ 03 апреля 2010

Вместо того, чтобы создавать новый элемент ссылки и добавлять его в заголовок, вы можете извлечь содержимое таблицы стилей с помощью вызова AJAX и вставить его в блок встроенных стилей. Таким образом, вы можете использовать «полный» обратный вызов jQuery, чтобы отключить проверку.

$('#theme-selector a').click(function(){
  var path = $(this).attr('href');
  $.get(path, function(response){
   //Check if the user theme element is in place - if not, create it.
   if (!$('#userTheme').length) $('head').append('<style id="userTheme"></style>');

   //populate the theme element with the new style (replace the old one if necessary)
   $('#userTheme').text(response);

  //Check whatever you want about the new style:
  alert($('body').css('background-color'));
  });
});

На самом деле я не тестировал этот код, поэтому могут быть некоторые ошибки синтаксиса-y, но логика должна быть достаточно надежной.

12 голосов
/ 04 апреля 2010

Событие load можно наблюдать для любого элемента, связанного с URL-адресом. Разве это не работает для вас при загрузке таблицы стилей css? http://api.jquery.com/load-event/

Попробуйте что-то вроде этого:

var path = $(this).attr('href');
$('head link').remove();
var styleSheet = $('<link type="text/css" href="'+path+'" rel="stylesheet" />');
styleSheet.load(function(){alert("Loaded");});
$('head').append(styleSheet);

Редактировать: Как указано ниже, это работает только в IE, кто бы мог подумать?

0 голосов
/ 10 июля 2018

Здесь мы ищем способ удалить критический CSS (элемент) после того, как на 100% уверены, что внешние листы загружены и обработаны . Это позволило бы мне использовать универсальный, но визуально приятный критический внутренний CSS во всем мире для нескольких проектов. Поскольку некоторые из критических стилей визуально идут вразрез с лениво загруженными, их необходимо переопределить (слишком много работы) или удалить. Это то, что я хочу, вкратце:

  1. Загрузить документ с критическим внутренним CSS
  2. Lazyload дополнительный CSS после рендеринга и интерактивности документа (хорошо для SEO и UX)
  3. Удалите критический CSS из HTML после того, как были загружены и действительно отображены дополнительные стильные таблицы стилей, чтобы предотвратить мерцание, возникающее во всех других решениях (я много тестировал).

100% -ное рабочее решение (может быть непопулярное) должно использовать setInterval (); после lazyloaded вторичного css, чтобы периодически проверять, действительно ли применен стиль, уникальный для вторичного CSS , Тогда я могу удалить критический CSS (или все, что я хочу сделать ..).

Я создал живую демонстрацию с комментариями к Codepen: https://codepen.io/Marko36/pen/YjzQzd и некоторой информацией в блоге: Запуск события Javascript / jQuery после загрузки CSS .

var CSSloadcheck = setInterval(function () {
    if ($('body').css('opacity') != 1) {
    //when opacity is set to 0.99 by external sheet
      $('style#critical').remove();
      clearInterval(CSSloadcheck);  
  }
}, 100);
0 голосов
/ 24 июля 2013

Вы можете использовать lazyload (плагин jQuery) для загрузки файла css. Он имеет возможность вызывать функцию, когда файл включен.

Пример:

// Load a CSS file and pass an argument to the callback function.
LazyLoad.css('foo.css', function (arg) {
  // put your code here
});
0 голосов
/ 24 июля 2013
var cssLoaded = function()
{
    alert($('body').css('background-color'));
};
$('#theme-selector a').click(function(){
   var path = $(this).attr('href');
   $('head link').remove();
   $('head').append('<link onload="cssLoaded();" type="text/css" href="'+path+'" rel="stylesheet" />');
   return false;
});

успешно протестировано в Chrome 28, IE 10, FF22

0 голосов
/ 03 апреля 2010

Вы можете просто продолжать проверять, остается ли цвет фона прежним, и затем делать свое дело, если оно когда-либо изменится.

oldbackground=getbackground()
function checkbackground(){
    if(oldbackground!=getbackground()){
        oldbackground=getbackground()
        //Do your thing
    }
}
setInterval(checkbackground,100)
...