Разве этот цвет диапазона не должен быть зеленым?

Разве цвет промежутка не должен быть зеленым, в Chrome он красный.

Спецификация HTML говорит, что он должен быть зеленым, в Firefox он зеленый.

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

var div = document.createElement("div");
document.body.appendChild(div);

var link = document.createElement("link");
link.href = "data:text/css,div { color: red }";
link.rel = "stylesheet";

var div = document.createElement("div");
document.body.appendChild(div);

var link = document.createElement("link");
link.href = "data:text/css,div { color: red }";
link.rel = "stylesheet";

document.head.appendChild(link);
document.querySelector("span").style.color = getComputedStyle(div).color;

link.remove();
div.remove();
div { color: green }
<span>This should be green</span>


person Suraj Jain    schedule 22.01.2018    source источник
comment
Мне кажется зеленым? Фаерфокс 57   -  person Emil S. Jørgensen    schedule 22.01.2018
comment
Он красный на Chrome 63   -  person Serge K.    schedule 22.01.2018
comment
@EmilS.Jørgensen Внимательно прочитайте вопрос.   -  person Suraj Jain    schedule 22.01.2018
comment
@EmilS.Jørgensen в Firefox он зеленый. У меня он красный в Chrome   -  person George    schedule 22.01.2018
comment
В сафари зеленый   -  person Sergey    schedule 22.01.2018
comment
Почему кто-то отрицает это и голосует за закрытие, это настоящий вопрос.   -  person Suraj Jain    schedule 22.01.2018
comment
Я думаю, что он должен быть красным, потому что в точке вашего вызова getComputedStyle был добавлен стиль динамической ссылки. Так что здесь я думаю, что Chrome делает это правильно.   -  person Keith    schedule 22.01.2018
comment
Почему он должен быть зеленым? Вы меняете цвет определенного элемента через его атрибут style. Это более конкретно, чем правило, влияющее на каждый div.   -  person Andreas    schedule 22.01.2018
comment
@Andreas developer.microsoft.com/en-us/microsoft -край/платформа/проблемы/   -  person Suraj Jain    schedule 22.01.2018
comment
Из-за отрицательных голосов я больше не задаю вопросы на этом сайте. Как этот вопрос получает отрицательный голос, одна попытка, и вот что я получаю. Закрытие. Сайт давно мертв.   -  person Suraj Jain    schedule 22.01.2018
comment
@SurajJain Это минус. Не принимайте это так близко к сердцу.   -  person zfrisch    schedule 22.01.2018
comment
Мой комментарий остается в силе. Побеждает самое конкретное правило стиля. И это тот, где вы меняете цвет div на красный. Я не понимаю, почему это должно быть зеленым О.о.   -  person Andreas    schedule 22.01.2018
comment
@zfrisch Это происходит в каждом посте и действительно демотивирует, почему бы не принять это на свой счет.   -  person Suraj Jain    schedule 22.01.2018
comment
Интересно, что getComputedStyle выдает разные результаты… Но при попытке в devtools оба возвращают одну и ту же строку цвета.   -  person niorad    schedule 22.01.2018
comment
Может быть, вы могли бы сказать нам, почему он должен быть зеленым, а не красным? Я согласен с @Andreas. Кроме того, пожалуйста, очистите свой код, чтобы избежать этих отрицательных голосов.   -  person Serge K.    schedule 22.01.2018
comment
почему бы не принять на свой счет - потому что это ни в коем случае не личная атака. Чтобы быть справедливым по отношению к отрицательным, вы не объяснили, почему вы ожидаете результатов, которые вы ожидаете. Вы только что выгрузили блок javascript и ожидаете, что мы его проверим.   -  person Turnip    schedule 22.01.2018
comment
@SurajJain, потому что это не форум. Это сайт вопросов и ответов. Сначала это кажется грубым, потому что, когда вы новичок, трудно понять форматирование и причины, по которым вас могут заминусовать, но, честно говоря, это помогает упростить ссылки на вопросы и ответы в будущем. Чтобы ответить на ваш вопрос, вы не должны принимать это на свой счет, потому что это не личное, это поддержание качества, и, очевидно, к нему может быть применена человеческая ошибка. Кто-то, наверное, видел, что в их браузере ваш вопрос был излишним, так как они были в файрфоксе. Это не конец света. Это не нападение.   -  person zfrisch    schedule 22.01.2018
comment
Специфика CSS: css-tricks.com/specifics-on-css-specificity   -  person Andreas    schedule 22.01.2018
comment
green per HTML spec. Интересно, к какой части спецификации это тоже относится? Логически прокручивая код в голове, должно быть red..   -  person Keith    schedule 22.01.2018
comment
@Кит Обновлено.   -  person Suraj Jain    schedule 22.01.2018
comment
@Андреас Обновлено   -  person Suraj Jain    schedule 22.01.2018
comment
Таким образом, вычисляемый стиль получается до загрузки новой таблицы стилей. У вас нет доказательств этого.   -  person Serge K.    schedule 22.01.2018
comment
@СержК. Асинхронный обработчик выполняется только после того, как стек пуст.   -  person Suraj Jain    schedule 22.01.2018
comment
The HTML spec uses fetch Но здесь используется uri данных, я только что проверил спецификацию и не вижу упоминания о том, что это должно быть async, и для меня это тоже не имеет смысла.   -  person Keith    schedule 22.01.2018
comment
@Keith В целом данные: декодирование URI и анализ CSS могут быть дорогостоящими операциями, и требование их синхронизации не имеет смысла. Поэтому я не уверен, почему Blink делает все это синхронно.   -  person Suraj Jain    schedule 22.01.2018
comment
@SurajJain Даже если операция выборки будет асинхронной и завершится после выполнения JS, ваш CSS является встроенным, поэтому в нем нет операции выборки, он загружается до выполнения JS .   -  person Serge K.    schedule 22.01.2018
comment
@СержК. Вот почему span должен быть зеленым   -  person Suraj Jain    schedule 22.01.2018
comment
@СержК. getComputedStyle(div).color дает зеленый цвет, поскольку цвет div был зеленым.   -  person Suraj Jain    schedule 22.01.2018
comment
@SurajJain На самом деле, да. Подумав об этом, я согласен. Если URL-адрес является ссылкой или uri данных, он должен вести себя последовательно. Он должен быть зеленым, очевидно, Chrome не ждет.   -  person Keith    schedule 22.01.2018
comment
@Keith Вы можете удалить свой отрицательный голос.   -  person Suraj Jain    schedule 22.01.2018
comment
@SurajJain Я не могу удалить отрицательный голос, которого я не делал .. :)   -  person Keith    schedule 22.01.2018
comment
Нет, он не должен быть зеленым. 1. Ваш CSS проанализирован. (div зеленый) 2. Вы добавляете CSS с помощью JS (div красный) 3. Вы вызываете getComputedStyle -› div красный   -  person Serge K.    schedule 22.01.2018
comment
@Keith О, я думал, что вы проголосовали против, люди здесь обычно делают только такие проголосования, без особого штрафа, есть 5 отрицательных голосов. Так что я думал, что вы сделали. Спасибо   -  person Suraj Jain    schedule 22.01.2018
comment
@СержК. Я думаю, дело в том, что даже если это uri данных, он должен быть загружен async, если вы будете следовать коду, используя это правило, он действительно будет зеленым. Интересная тема, на самом деле я собираюсь проголосовать.. :)   -  person Keith    schedule 22.01.2018
comment
@ Кит О, я понял. Но это не меняет моей точки зрения, вы не можете быть уверены (даже если это асинхронный), что асинхронный вызов завершится или не завершится после getComputedStyle. Возможно, getComputedStyle заставляет браузер завершать такие запросы до возврата.   -  person Serge K.    schedule 22.01.2018
comment
@СержК. Вы знаете, что вызов может завершиться раньше, но javascript не будет смотреть на него, пока его стек не станет пустым. Есть ли путаница?   -  person Suraj Jain    schedule 22.01.2018
comment
@Turnip Извините, обновлено.   -  person Suraj Jain    schedule 22.01.2018
comment
@СержК. Разве ваши сомнения развеялись?   -  person Suraj Jain    schedule 22.01.2018
comment
@Andreas Пожалуйста, посмотрите вопрос еще раз.   -  person Suraj Jain    schedule 22.01.2018
comment
@SurajJain Нет. Я не понимаю, почему вы уверены, что getComputedStyle будет вызываться до того, как ссылка будет добавлена ​​и проанализирована.   -  person Serge K.    schedule 22.01.2018
comment
Поскольку, скажем, асинхронная функция завершается первой, то и обработчик, ожидающий ее завершения, не будет выполняться до тех пор, пока стек не будет очищен. так работает цикл событий. Имеет ли это смысл   -  person Suraj Jain    schedule 22.01.2018


Ответы (2)


Чтобы упростить анализ, я сократил вашу выборку, удалив повторяющиеся и нерелевантные строки; для воспроизведения проблемы достаточно следующего:

var div = document.createElement("div");
document.body.appendChild(div);

var link = document.createElement("link");
link.href = "data:text/css,div { color: red }";
link.rel = "stylesheet";
document.head.appendChild(link);

document.querySelector("span").style.color = getComputedStyle(div).color;
div {color:green}
<span>This is a span</span>
<div>this is a div</div>

Итак, что здесь происходит, есть встроенный CSS, который говорит, что div должен быть зеленым; вы создаете ссылку text/css, которая устанавливает красный цвет div и добавляете ее в заголовок документа. Затем вы используете getComputedStyle, чтобы скопировать цвет из div в диапазон.

В Safari, Chrome и Edge обе линии заканчиваются красным; в Firefox диапазон зеленый, а div красный.

НО! при первой загрузке или если вы загрузите эту страницу в Safari или Chrome с чистым и пустым кешем*, вы увидите то же поведение, что и в Firefox: зеленый интервал и красный разд. Edge никогда не ведет себя как FF, он всегда красный для обоих даже при первой загрузке.

* (В Safari вы можете просто использовать приватное окно просмотра. Могу поклясться, что в какой-то момент я видел то же самое в Chrome, но больше не могу воспроизвести; возможно, я ошибался.)

Поэтому вот моя гипотеза о том, что происходит:

  • В Safari, когда сгенерированная ссылка на таблицу стилей никогда ранее не использовалась, она является асинхронной, поэтому getComputedStyle выбирает цвет из встроенного стиля. При более поздних загрузках сгенерированная таблица стилей уже находится в кеше, когда запускается getComputedStyle, поэтому ее правило вступает в силу.
  • В Firefox ссылки на таблицы стилей всегда обрабатываются как асинхронные, поэтому getComputedStyle всегда выбирает встроенное правило.
  • В других браузерах ссылка на таблицу стилей интерпретируется синхронно (возможно, потому, что браузер может сказать, что data URI не требует сетевого времени?), поэтому обрабатывается до запуска getComputedStyle.

Это достаточно странный пограничный случай, и я не уверен, какое поведение можно описать как «согласно спецификации».

person Daniel Beck    schedule 22.01.2018
comment
Спасибо за ответ. - person Suraj Jain; 22.01.2018
comment
А в хроме?\ - person Suraj Jain; 22.01.2018
comment
Chrome такой же, как сафари: чистый кеш заставляет его работать как Firefox. - person Daniel Beck; 22.01.2018
comment
Хром в моем случае так не работает. В любом случае он красный. - person Suraj Jain; 22.01.2018
comment
Почему это состояние гонки? - person Suraj Jain; 22.01.2018
comment
Состояние гонки, в котором происходит первым, getComputedStyle или вычисление сгенерированной таблицы стилей. Re Chrome: я могу поклясться, что в какой-то момент я видел, как он ведет себя как Safari, но я больше не могу это воспроизвести. - person Daniel Beck; 22.01.2018
comment
Правильный. (Что бы это ни стоило, я также протестировал Edge; он ведет себя как Chrome, всегда красный.) - person Daniel Beck; 22.01.2018
comment
На самом деле это не состояние гонки, так как асинхронные операции всякий раз, когда они происходят, будут выполняться в конце, когда стек пуст. Я прав? - person Suraj Jain; 22.01.2018
comment
Ясно, что нет, учитывая, что каждый браузер обрабатывает это совершенно по-разному. :) Но вы правы, я использовал несколько расплывчатое определение состояния гонки, я уберу этот текст. - person Daniel Beck; 22.01.2018
comment
Почему бы и нет, разве это не то, что должно произойти - person Suraj Jain; 22.01.2018
comment
Вы, похоже, твердо решили, что так и должно быть, но поставщики браузеров, похоже, разные. Я не знаю, что выборка должна быть асинхронной для URI данных. - person Daniel Beck; 22.01.2018
comment
Я имею в виду, что обработчик асинхронной операции будет выполнен в конце, а не в том случае, если выборка асинхронна или нет. - person Suraj Jain; 22.01.2018
comment
¯\_(ツ)_/¯ Кажется, это соответствует поведению FF и сафари с очисткой кеша. - person Daniel Beck; 22.01.2018
comment
Я имел в виду, что у вас есть асинхронное событие, не будет ли javascript просматривать очередь событий только тогда, когда стек пуст, тогда он будет просматривать очередь и выполнять ожидающий обработчик событий. - person Suraj Jain; 22.01.2018
comment
Я думаю, что проблема здесь в том, что некоторые поставщики браузеров сразу видят uri данных, декодируют и обновляют DOM, в некоторых отношениях это в обычных ситуациях действительно не должно быть проблемой, поскольку событие onload, вероятно, все еще вызывается. Было бы очень странно, если бы любой код Javascript полагался на асинхронную операцию в каком-либо конкретном порядке выполнения, поэтому в большинстве случаев это не будет проблемой. Представленный код представляет собой очень странный пограничный случай, который, скорее всего, легко исправить разработчиками Chrome, поместив все данные: uri в вызов типа setImediate. Это похоже на несоответствие библиотек Promise.then. - person Keith; 22.01.2018
comment
@Keith Если этот асинхронный вызов завершится первым, то стек также сначала завершит свое выполнение, а когда он станет пустым, выполнится обработчик асинхронного вызова. Я прав? - person Suraj Jain; 22.01.2018
comment
@SurajJain If that async call finishes first Я думаю, что все становится интереснее. Если любой вызов href всегда должен считаться async теоретически, он никогда не должен заканчиваться первым и всегда вызываться в конце, я полагаю, это зависит от того, что говорит спецификация. Возьмем спецификацию обещания -> Promise.resolve("first").then((r) => console.log(r)); console.log("second"); Несмотря на то, что first может быть разрешено мгновенно, результат должен быть second, first.. Но я помню, что некоторые библиотеки промисов без жалоб действительно выполняли бы first, second. - person Keith; 22.01.2018

Попробуйте HTML или HTML5 (это Chrome):

<span type="color:green">shouldn't this be green</span>
person Noah Pinero-Wohr    schedule 22.01.2021