Автор Тема: Получение CSS стилей у элемента без атрибута style  (Прочитано 834 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн CreatoR [?]

  • Администратор
  • *
  • Сообщений: 7787
  • Репутация: 2278
  • Пол: Мужской
  • AutoIt is simple, subtle, elegant
    • CreatoR's Lab
    • Награды
  • Версия AutoIt: 3.3.10.2
Есть ли возможность получить CSS стиль у элемента, у которого отсутствует атрибут style?

Код: (html) [Выделить]
  1. <div id="test"></div>

сам стиль элемента ведь может задаваться в заголовке (head), через #test {...}, так вот мне и нужно его узнать на лету, не прибегая к крайним мерам (парсинг заголовка страницы).

Вроде есть cssText, но не работает...
Пример:
Код: AutoIt [Выделить]
#include <IE.au3>

$oIE = _IECreate('', 0, 0)
_IEDocWriteHTML($oIE, '<html><head><style type="text/css">#test {border: thin solid;float: left;text-align: center;}</style></head><body><div id="test">hi</div></body></html>')
$oTest = _IEGetObjById($oIE, 'test')

;Тут я бы хотел увидеть "border: thin solid;float: left;text-align: center;"
ConsoleWrite($oTest.style.cssText() & @CRLF)

_IEQuit($oIE)


 :think:


Правила, Поиск, Супер тема


AutoIt is simple, subtle, elegant.


«Не оказываю тех. поддержку через ПМ/ICQ, и по электронной почте - для этого есть форум. (C)»
«Законы Мэрфи неоспоримы!»


Мои работы

Русское сообщество AutoIt


Оффлайн Garrett [?]

  • Глобальный модератор
  • *
  • Сообщений: 3679
  • Репутация: 934
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.12.0
CreatoR  [?]
Цитировать
мне и нужно его узнать на лету
Код: AutoIt [Выделить]
$oIE = _IECreate('', 0, 0)
_IEDocWriteHTML($oIE, '<html><head><style type="text/css">#test {background-color: lightblue; border: thin solid; float: left; text-align: center;}</style></head><body><div id="test">hi</div></body></html>')
$oElem = _IEGetObjById($oIE, 'test')
$oWind = $oIE.document.parentWindow

$oSCntrl = ObjCreate("ScriptControl")
With $oSCntrl
   .Language = 'JScript'
   .AddObject('window', $oWind, False)
   .AddCode('function getStyle(elem){ return window.getComputedStyle ? window.getComputedStyle(elem, "") : elem.currentStyle; }')
   $oEl = .Run('getStyle', $oElem)
EndWith

MsgBox(0, "", StringFormat( "#test {\n\t" _
                           &"background-color: %s;\n\t" _
                           &"border-width: %s;\n\t" _
                           &"border-style: %s\n\t" _
                           &"float: %s\n\t" _
                           &"text-align: %s\n}", _
                           $oEl.getPropertyValue("background-color"), _
                           $oEl.getPropertyValue("border-left-width"), _
                           $oEl.getPropertyValue("border-left-style"), _
                           $oEl.getPropertyValue("float"), _
                           $oEl.getPropertyValue("text-align")))

_IEQuit($oIE)


P.S. Win7 x86 IE11
« Последнее редактирование: Март 23, 2017, 18:48:25 от Garrett »

Скорблю и помню.




Оффлайн CreatoR [?]

  • Администратор
  • *
  • Сообщений: 7787

  • Автор темы
  • Репутация: 2278
  • Пол: Мужской
  • AutoIt is simple, subtle, elegant
    • CreatoR's Lab
    • Награды
  • Версия AutoIt: 3.3.10.2
Garrett
Мне нужно получить "#test {background-color: lightblue; border: thin solid; float: left; text-align: center;}", я не знаю заранее что там внутри, какие там свойства.

А вообще если подумать, на самом деле мне нужно наверное присваивать стили выбранному элементу (при чём и его дочерним элементам), при том что я заранее не знаю какие стили используются на странице.
Можно конечно получить стили:

Код: AutoIt [Выделить]
Func _IEGetStyleSheets($oIE)
    Local $oCSSs = $oIE.Document.StyleSheets
    Local $sCSS = ''
   
    If IsObj($oCSSs) Then
        For $oCSS In $oCSSs
            $sCSS &= $oCSS.cssText & @CRLF
        Next
       
        $sCSS = '<style type="text/css">' & @CRLF & StringStripWS($sCSS, 3) & @CRLF & '</style>'
    EndIf
   
    Return $sCSS
EndFunc


и тогда не трогать элементы, а просто использовать в заголовке глобальные стили.
Но было бы конечно лучше как бы расширить классы до их используемых стилей:

Код: (html) [Выделить]
  1. <div class="myclass" style="float: left;">
тут class="myclass" должен "превратиться" в стили и подставиться в атрибут style (если он имеется конечно, если нет - то создать его).
Кстати интересно, в таком случае style игнорируется (если класс задан)? или они совместно действуют?

Оффлайн Garrett [?]

  • Глобальный модератор
  • *
  • Сообщений: 3679
  • Репутация: 934
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.12.0
CreatoR  [?]
Цитировать
мне нужно наверное присваивать стили выбранному элементу (при чём и его дочерним элементам)
Так?
Код: AutoIt [Выделить]
#include <IE.au3>

$oIE = _IECreate('')
_IEDocWriteHTML($oIE, '<html><head><style type="text/css">#test {background-color: lightblue; border: thin solid; float: left; text-align: center;}</style></head><body><div id="test">hi</div></body></html>')
$oElem = _IEGetObjById($oIE, 'test')
$oWind = $oIE.document.parentWindow
$oDoc = $oIE.document

$oSCntrl = ObjCreate("ScriptControl")
With $oSCntrl
   .Language = 'JScript'
   .AddObject('window', $oWind, False)
   .AddObject('document', $oDoc, False)
   .AddCode('function getStyle(elem){ return window.getComputedStyle ? window.getComputedStyle(elem, "") : elem.currentStyle; }')
   .AddCode('function setStyle(newStyle){ var styleElement = document.getElementById("styles_CreatoR"); if (!styleElement){ styleElement = document.createElement("style"); styleElement.type = "text/css"; styleElement.id = "styles_CreatoR"; document.getElementsByTagName("head")[0].appendChild(styleElement); } styleElement.appendChild(document.createTextNode(newStyle)); }')
   $oEl = .Run('getStyle', $oElem)
EndWith

; смотрим
MsgBox(0, "", StringFormat( "#test {\n\t" _
                           &"background-color: %s;\n}", _
                           $oEl.getPropertyValue("background-color")))

Sleep(1000)

; добавляем
With $oSCntrl
   $oEl = .Run('setStyle', '#test {width: 300px; background-color: #FF9933 !important;}')
   $oEl = .Run('getStyle', $oElem)
EndWith

; смотрим
MsgBox(0, "", StringFormat( "#test {\n\t" _
                           &"background-color: %s;\n}", _
                           $oEl.getPropertyValue("background-color")))
Sleep(1000)

_IEQuit($oIE)


P.S. Win7 x86 IE11

Русское сообщество AutoIt

Re: Получение CSS стилей у элемента без атрибута style
« Ответ #3 Отправлен: Март 23, 2017, 23:28:26 »

Оффлайн CreatoR [?]

  • Администратор
  • *
  • Сообщений: 7787

  • Автор темы
  • Репутация: 2278
  • Пол: Мужской
  • AutoIt is simple, subtle, elegant
    • CreatoR's Lab
    • Награды
  • Версия AutoIt: 3.3.10.2
Garrett  [?]
Цитировать
Так?
Не совсем.
Попробую описать получше...

Мне нужно из некой страницы получить элемент (div), и отобразить его в своём Embed IE, так вот я бы хотел чтобы при отображений сохранились стили той страницы откуда я взял элемент.
Вот как я делаю сейчас:

Код: AutoIt [Выделить]
#include <IE.au3>

$sURL = 'https://autoit-script.ru'
$sID = 'upper_section'

$oMy_IE = _IECreate('about:blank')
$oTmp_IE = _IECreate($sURL, 0, 0, 0, 0)

$oDiv = _IEGetObjById($oTmp_IE, $sID)

$oHead = $oMy_IE.document.head
$oStyle = $oMy_IE.document.createElement('Style')
$oStyle.setAttribute('type', 'text/css')
$oStyle.innerText = _IEExpandRelativePath(_IEGetStyleSheets($oTmp_IE), $sURL)
$oHead.insertBefore($oStyle)

_IEBodyWriteHTML($oMy_IE, _IEExpandRelativePath($oDiv.OuterHtml, $sURL))
_IEAction($oMy_IE, 'visible')

_IEQuit($oTmp_IE)

Func _IEGetStyleSheets($oIE)
    Local $oCSSs = $oIE.Document.StyleSheets
    Local $sCSS = ''
   
    If IsObj($oCSSs) Then
        For $oCSS In $oCSSs
            $sCSS &= $oCSS.cssText & @CRLF
        Next
       
        $sCSS = StringStripWS($sCSS, 3)
    EndIf
   
    Return $sCSS
EndFunc

;Кстати тут бы не помешала какая то альтернатива (для выпрямления ссылок), потому что это не надёжно (например ссылки типа "../" не выпрямляет)
Func _IEExpandRelativePath($sHtml, $sURL)
    $sHtml = StringRegExpReplace($sHtml, '(?i)(url\("|url":")//', '\1http://')
    $sHtml = StringRegExpReplace($sHtml, '(?i) href=(")?//', ' href=\1http://')
    $sHtml = StringRegExpReplace($sHtml, '(?i) src=(")?//', ' src=\1http://')
    $sHtml = StringRegExpReplace($sHtml, '(?i)(url\("|url":")\.\./', '\1' & $sURL & '/../')
    $sHtml = StringRegExpReplace($sHtml, '(?i) href=(")?/', ' href=\1' & $sURL & '/')
    $sHtml = StringRegExpReplace($sHtml, '(?i) src=(")?/', ' src=\1' & $sURL & '/')
   
    Return $sHtml
EndFunc


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

Оффлайн CreatoR [?]

  • Администратор
  • *
  • Сообщений: 7787

  • Автор темы
  • Репутация: 2278
  • Пол: Мужской
  • AutoIt is simple, subtle, elegant
    • CreatoR's Lab
    • Награды
  • Версия AutoIt: 3.3.10.2
OffTopicКстати, вот как я придумал сделать выпрямитель ссылок:

Код: AutoIt [Выделить]
Func _IEExpandRelativePath($oSrcIE, $sDstHtml)
    Local $aURLs = StringRegExp($sDstHtml, '(?i)(?:url(?:\(|":)|(?:href|src)=)"([^"]+?)"', 3)
   
    For $i = 0 To UBound($aURLs) - 1
        $oA = $oSrcIE.document.createElement('a')
        $oA.href = $aURLs[$i]
        $sDstHtml = StringRegExpReplace($sDstHtml, '(?i)(url(?:\(|":)|(?:href|src)=)"' & $aURLs[$i] & '"', '\1' & $oA.href)
        $oA.remove()
    Next
   
    Return $sDstHtml
EndFunc


Т.е создаётся временный элемент ссылки (а), куда помещается относительная ссылка, и уже там она автоматический выпрямляется.
Впрочем это не быстрее, а возможно даже дольше обрабатывает...
« Последнее редактирование: Март 24, 2017, 02:30:36 от CreatoR »

Оффлайн Garrett [?]

  • Глобальный модератор
  • *
  • Сообщений: 3679
  • Репутация: 934
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.12.0
CreatoR
Долго я "мозг морщил", взвешивал все за и против, в итоге написал оптимальное решение (IMHO).  :think:

Цитировать
Мне нужно из некой страницы получить элемент (div), и отобразить его в своём Embed IE
Тут дело в том, что один DIV может тянуть за собой несколько родительских, которые в свою очередь влияют на стиль.
Решение:
- для каждого случая своё.

Цитировать
так вот я бы хотел чтобы при отображений сохранились стили той страницы откуда я взял элемент.
IMHO, копирование ссылок достаточно в данном случае.
Однако, может быть недостаточным в других случаях.
Решение:
- опять же, для каждого случая своё.
(нажмите для показа/скрытия)

P.S. Win7 x86 IE11

Оффлайн CreatoR [?]

  • Администратор
  • *
  • Сообщений: 7787

  • Автор темы
  • Репутация: 2278
  • Пол: Мужской
  • AutoIt is simple, subtle, elegant
    • CreatoR's Lab
    • Награды
  • Версия AutoIt: 3.3.10.2
Garrett
Решение хорошее, возьму его на заметку, но увы мою проблему оно не решает, с шапкой этого форума - это был пример, мне нужно нечто более универсальное.

OffTopicКстати а что по поводу выпрямления ссылок, есть идеи как это ускорить, или может есть метод получше? :think:

Спасибо.

Русское сообщество AutoIt

Re: Получение CSS стилей у элемента без атрибута style
« Ответ #7 Отправлен: Март 27, 2017, 04:34:38 »

Оффлайн Garrett [?]

  • Глобальный модератор
  • *
  • Сообщений: 3679
  • Репутация: 934
  • Пол: Мужской
    • Награды
  • Версия AutoIt: 3.3.12.0
CreatoR  [?]
Цитировать
но увы мою проблему оно не решает
Если данные не конфиденциальные, то ссылка была бы кстати.

Цитировать
Кстати а что по поводу выпрямления ссылок, есть идеи как это ускорить, или может есть метод получше?
Честно говоря не пойму о чём вы? Если о ссылках в HTML и CSS, то они уже возвращаются скриптом абсолютными.
(нажмите для показа/скрытия)
« Последнее редактирование: Март 27, 2017, 08:24:26 от Garrett »

Оффлайн CreatoR [?]

  • Администратор
  • *
  • Сообщений: 7787

  • Автор темы
  • Репутация: 2278
  • Пол: Мужской
  • AutoIt is simple, subtle, elegant
    • CreatoR's Lab
    • Награды
  • Версия AutoIt: 3.3.10.2
Garrett  [?]
Цитировать
Если данные не конфиденциальные, то ссылка была бы кстати.
Это может быть любой сайт.
Ну допустим, один из тех где есть проблемы - это http://m.facebook.com/

Вот пример как я делаю на данный момент:

Код: AutoIt [Выделить]
#include <IE.au3>

$sURL = 'https://m.facebook.com'
$sID = 'tag=div|id=RE:u_.+?|role=article'

$oMain_IE = _IECreate('', 0, 0)
$oEmbed = _IEEmbed_Create()

_IENavigate($oMain_IE, $sURL, 1)

$sHtml = '<html><head>' & @CRLF & '<meta charset="utf-8" />' & @CRLF & _IEGetStyleSheets($oMain_IE) & @CRLF & '</head><body>'

$aoContent = _IEGetObjByParams($oMain_IE, $sID, True)

If IsArray($aoContent) And IsObj($aoContent[1]) Then
    For $i = 1 To $aoContent[0]
        $sHtml &= @CRLF & '<div id="FB" style="padding: 20px; border: 2px solid black;>' & $aoContent[$i].OuterHtml & '</div><br />' & @CRLF
    Next
EndIf

$sHtml &= '</body></html>'

_IEDocWriteHTML($oEmbed, $sHtml)
_IEAction($oEmbed, 'visible')
_IEQuit($oMain_IE)

Func _IEEmbed_Create()
    Local $oEmbed = _IECreate('', 0, 0)
   
    _IEPropertySet($oEmbed, 'Silent', True)
    _IEPropertySet($oEmbed, 'ToolBar', False)
    _IEPropertySet($oEmbed, 'AddressBar', False)
    _IEPropertySet($oEmbed, 'MenuBar', False)
    _IEPropertySet($oEmbed, 'StatusBar', False)
    _IEPropertySet($oEmbed, 'Resizable', False)
   
    Return $oEmbed
EndFunc

Func _IEGetObjByParams($oObj, $sParams, $bRetAllObjcts = False)
    Local $aParams = StringRegExp($sParams, '(?i)(.*?)=(.*?)(?:\||$)', 3)
    If Mod(UBound($aParams), 2) <> 0 Then Return SetError(1, 0, 0)
   
    Local $oTags = _IETagNameAllGetCollection($oObj)
    Local $iCount = @extended, $vTag, $bRegExp
    Local $aFound_Tags[$iCount]
   
    For $oTag In $oTags
        For $i = 0 To UBound($aParams) - 1 Step 2
            $aParams[$i] &= (($aParams[$i] = 'class' Or $aParams[$i] = 'tag') ? 'name' : '')
           
            $vTag = $oTag.getAttribute($aParams[$i])
            If Not $vTag Then $vTag = Execute('$oTag.' & $aParams[$i])
           
            $bRegExp = StringLeft($aParams[$i + 1], 3) = 'RE:'
            $sNextParam = $aParams[$i + 1]
           
            If $bRegExp Then
                $sNextParam = StringTrimLeft(StringReplace($aParams[$i + 1], '~', '|'), 3)
            EndIf
           
            If ($bRegExp And Not StringRegExp($vTag, '(?i)' & $sNextParam)) Or (Not $bRegExp And String($vTag) <> String($sNextParam)) Then
                ContinueLoop 2
            EndIf
        Next
       
        ;Tag is ok (matched params)
        $aFound_Tags[0] += 1
        $aFound_Tags[$aFound_Tags[0]] = $oTag
    Next
   
    If $aFound_Tags[0] > 0 Then
        ReDim $aFound_Tags[$aFound_Tags[0] + 1]
       
        If $bRetAllObjcts Then
            Return $aFound_Tags
        EndIf
       
        Return $aFound_Tags[1]
    EndIf
   
    Return SetError(2, 0, 0)
EndFunc

Func _IEGetStyleSheets($oIE)
    Local $oCSSs = $oIE.Document.StyleSheets
    Local $sCSS = ''
   
    If IsObj($oCSSs) Then
        For $oCSS In $oCSSs
            $sCSS &= $oCSS.cssText & @CRLF
        Next
       
        $sCSS = '<style type="text/css">' & @CRLF & StringStripWS($sCSS, 3) & @CRLF & '</style>'
    EndIf
   
    Return $sCSS
EndFunc


Перед запуском нужно убедиться что в фейсбуке произведён вход в аккаунт из под Internet Explorer.
Здесь я убрал выпрямление ссылок, и в коде страницы явно видно что ссылки относительные.

Вот в этом примере хотелось бы увидеть как можно получая блоки кода, расширить указанные в них стили (по классу или в явном виде) до их реальных значений, также и с ссылками.

Русское сообщество AutoIt

Re: Получение CSS стилей у элемента без атрибута style
« Ответ #9 Отправлен: Март 29, 2017, 01:16:14 »

 

Похожие темы

  Тема / Автор Ответов Последний ответ
7 Ответов
4051 Просмотров
Последний ответ Апрель 05, 2010, 12:55:24
от amel27
2 Ответов
3281 Просмотров
Последний ответ Июнь 09, 2010, 09:23:36
от beaver
7 Ответов
3375 Просмотров
Последний ответ Июль 11, 2011, 11:45:26
от Pelerin
3 Ответов
1740 Просмотров
Последний ответ Июнь 07, 2012, 01:22:56
от running-frag
13 Ответов
8321 Просмотров
Последний ответ Февраль 27, 2012, 14:06:48
от Kaster
3 Ответов
1987 Просмотров
Последний ответ Сентябрь 05, 2013, 23:48:34
от PACHOM
1 Ответов
1160 Просмотров
Последний ответ Ноябрь 14, 2013, 22:02:27
от AZJIO
17 Ответов
2710 Просмотров
Последний ответ Май 19, 2014, 16:53:40
от Коршун
3 Ответов
1033 Просмотров
Последний ответ Июнь 24, 2014, 22:47:10
от Medic84
3 Ответов
1260 Просмотров
Последний ответ Январь 11, 2016, 11:41:38
от LuciferKo