2013-07-31 8 views
2

Мне нужно знать, был ли элемент стилизован с использованием стиля: первая буква, и это должно быть общее решение, поэтому я не буду зависеть от имен классов или специальных атрибутов стиля. Там в любом случае? Пример:Обнаружение: первая буква javascript

<p class="initial">First</p> 
<p>Second</p> 

.initial:first-letter { 
float: left; 
font-size: 1.5em; 
font-weight: bold; 
} 

$('p').click(function(){ 
    // how to determine if :first-letter is applied to current paragraph? 

}); 
+2

Почему бы не просто проверить, если '.initial' класс применяется к пункту? Если оно применяется, то вы знаете, что применяется стиль псевдо-элемента ': first-letter' - если есть первая буква, которая (и браузер поддерживает': first-letter'). – crush

+0

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

+1

Мне было бы интересно узнать об ошибке Chrome. У вас есть ссылка на отчет об ошибке Chrome, или jsfiddle, который может его демо? Может ли быть какой-то другой способ, чем то, как вы пытаетесь? Кроме того, если это известная ошибка, есть ли вероятность, что они могут исправить ее в следующей версии? (вы проверяли, есть ли ошибка в канарейской версии или ночных клубах?) – Spudley

ответ

3

Если ваш CSS является само- прошел, вы можете:

  1. Получить список всех CSS блоков
  2. Отфильтровывать CSS блоки, которые не содержат :first-letter в селектор блока
  3. It прокрутите список оставшихся блоков CSS и запустите matchesSelector() с целевым элементом в качестве приемника и селектором текущего блока CSS в качестве аргумента.
    1. Если matchesSelector() возвращает true, то действующие правила блока CSS влияют на первую букву целевого элемента.
    2. В противном случае переходите к следующему CSS блока в списке

Если CSS не резидентных и CDN не отправляет заголовки CORS, то вы не можете прочитать исходный файл CSS из-за проблем с конфиденциальностью, и это невозможно.

Я также не рассмотрел, как правило, каскадирование из алгоритма. Еще один удар по дороге - выяснить, какие псевдоселекторы влияют на matchesSelector ложным способом.

Как считают:

p.webkitMatchesSelector("p:first-letter") //false 

Так можно было бы удалить pseudos как :first-letter из строки, прежде чем пытаться соответствовать как они не имеют никакого отношения (но pseudos как :nth-child не потому, что они действительно влияют на соответствие).

Demo http://jsfiddle.net/PBuzb/5/ (имейте в виду, что проблемы я уже упоминал, не обрабатываются очень хорошо здесь) (база кода первоначально Давка)


Почему не разрешается читать источник CSS в поперечном происхождения ситуация?

Причина, по которой вы можете показывать изображения, запускать css/js и т. Д.из других доменов, НО абсолютно не получить доступ к их данным каким-либо образом - это конфиденциальность.

Корпус проще всего сделать для изображений. Предположим, что я вошел в систему на facebook, а facebook использует url для частной фотографии, например http://facebook.com/myprofile.png. Теперь я иду на evil.com, а evil.com может загружать изображение, потому что я вошел в систему на facebook, , чтобы facebook предоставил им это изображение. Как правило, они не могут получить доступ к изображению или украсть его в любом случае, но если мы включили доступ к данным перекрестного происхождения , они могли бы теперь получить доступ к моей личной фотографии и распространить ее.

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

И да, основная проблема заключается в том, как браузеры отправляют файлы cookie с запросом на перекрестный поиск, если браузер не отправил файлы cookie при запросе изображений facebook/css с сайта evil.com, то facebook не смог ответить специфичным для пользователя css или мои личные фотографии, потому что печенья были необходимы, чтобы узнать меня.

Теперь представьте, если браузеры не отправили файлы cookie. Evil.com все равно мог получить доступ к данным интрасети таким образом, потому что мой браузер имеет доступ к интрасети. Возможность показать http://intranet/Myboss.jpg как изображение на сайте evil.com - это не проблема, но Evil.com может читать данные изображения и, таким образом, иметь возможность копировать и распространять его, является проблемой.

+0

Эй, это мой код ... lol – crush

+1

@crush lol yea Я уже говорил вам теперь: P Это так утомительно, чтобы написать код, чтобы получить все блоки css, поэтому я бы не сделал демо без вас так спасибо :) – Esailija

+0

Does document.styleSheets не работает для неавторизованных файлов CSS без заголовков CORS, потому что я подумал, что он уже загружен и проанализирован браузером, поэтому проблем с безопасностью не должно быть? –

1

Вы не можете.

Псевдоэлементы и их стили недоступны из вашего JS-кода.

Самый близкий, который вы можете сделать, это проверить, имеет ли элемент соответствующий класс, который будет запускать стили first-letter, и сделать предположение в вашем JS-коде, что если класс существует, то должен быть применен стиль first-letter.

Существует не какой-либо другой способ, не разбирающий ваш путь через весь файл CSS вручную.

Это также относится и к другим псевдо-селекторов и псевдо-элементов (вы найдете целый ряд подобных вопросов здесь просят аналогичные вопросы :before и :after, с подобными ответами)

+1

Ну, вам не нужно его вручную анализировать, вы можете просто использовать 'document.styleSheets'. Но это самый простой шаг. – Esailija

+0

ну, может быть, не обязательно делать полный процесс синтаксического анализа, но вам нужно будет пройти через каждый селектор, найти те, у которых есть селектора ': first-letter', а затем выяснить, соответствует ли ваш данный элемент любому из этих элементов.Это звучит неплохо, но может стать беспорядочным, если у вас много CSS (и * очень * беспорядочно, если у вас есть несколько стилей с первой буквой, применимых к одному и тому же элементу) – Spudley

+0

выяснить, соответствует ли элемент данному селекторному тексту просто вызовите 'matchesSelector', это угловые случаи и такие вещи, как' * 'не отображаются в тексте правила селектора, который трудно получить правильно: P – Esailija

2

Вы можете выполнить итерацию по cssRules, построить массив всех правил ::first-letter, а затем проверить, имеет ли элемент одно из этих правил.

Working DEMO (Испытано в Chrome только)

(function() { 
    var firstLetterRules = []; 

    var loadRules = function() { 
     var stylesheets = document.styleSheets; 

     for (var i = 0; i < stylesheets.length; i++) { 
      var stylesheet = stylesheets[i]; 
      var rules = stylesheet.cssRules; 

      for (var k = 0; k < rules.length; k++) { 
       var rule = rules[k]; 

       if (rule.selectorText.indexOf("::first-letter") !== -1) { 
        //It is a ::first-letter selector. Add the rule to a list of ::first-letter rules. 
        firstLetterRules.push(rule.selectorText.toUpperCase()); 
       } 
      } 
     } 
    }; 

    window.hasFirstLetterStyle = function(element) { 
     var fullSelector = element.nodeName; 

     if (element.className != '') 
      fullSelector += '.' + element.className; 

     fullSelector = fullSelector.toUpperCase() + "::FIRST-LETTER"; 

     for (var i = 0; i < firstLetterRules.length; i++) { 
      if (fullSelector == firstLetterRules[i]) 
       return true; 
     } 

     return false; 
    }; 

    loadRules(); 
})(); 

var element = document.getElementById("init"); 

if (hasFirstLetterStyle(element)) { 
    console.log("Element has a first-letter style rule."); 
} 
+0

Могут быть некоторые случаи, которые этого не поймают. Прямо сейчас, это только соответствует полностью квалифицированным правилам CSS. Я попытаюсь изменить его, чтобы еще больше простить. Например, в настоящий момент оно не будет соответствовать правилу '* :: first-letter'. и он не будет соответствовать '.initial :: first-letter'. Предполагается, что правило будет обозначать имя тега. Я исправлю это через секунду. – crush

Смежные вопросы