Pobieranie wartości style - javascript.

0

Witam.
Mam taką stronkę:

<style>
.divek{
  width: 100px;
  float: left;
}
</style>
<div class="divek">asdasd</div>

Chcę teraz przeszukać wszystkie divy i wyświetlić wartości styli:

onload=function (){
  var obj = document.getElementsByTagName("div");
  for(var i=0; i<obj.length; i++){
    alert(obj[i].getAttribute("width"));
  }
}

Pokazuje mi null, co jest nie tak?

0

Atrybut jest czymś innym niż styl CSS ustawiony dla klasy. Twój element nie ma ustawionego atrybutu "width".

Aby odczytać styl trzeba odwołać się do pola .**style **(niestety to chyba! działa tylko dla stylów typu inline, a nie dla stylów klasy).

2

Co jest nie tak?

Wywołanie el.getAttribute('width') podaje wartość atrybutu width na elemencie el. Więc gdybyś miał coś takiego:

<div class="divek" width="50" foo="bar"></div>

to wywołanie getAttribute('width') zwróciłoby dla divka wartość 50, a wywołanie getAttribute('foo') powinno zwrócić bar. getAttribute podaje więc wartość atrybutu ustawionego na elemencie. Tyle że to dla Ciebie bezużyteczne, bo wg specyfikacji, element div nie ma nawet atrybutu width. Jak go sobie tam dopiszesz, to nie ustawi on szerokości. Nie zrobi on niczego, podobnie jak atrybut o zmyślonej nazwiefoo ustawiony na bar też niczego nie zrobi. Obrazki img mają atrybut width i ustawia on szerokość obrazku, ale nie o tym tu mówimy. Ty chcesz szerokość elementu ustawioną poprzez style.

To, co mówi @Deti, zadziałałoby dokładnie tak, jak napisał w nawiasie. Jeśli element el ma style zdefiniowane czy to za pomocą JavaScriptu, czy to za pomocą atrybutu style, to możesz się odwołać do tego stylu za pomocą el.style.nazwaStylu.

Czyli jakbyś miał coś takiego:

<div class="divek" style="width: 50px;"></div>

to wywołanie obj[i].style.width powinno zwrócić sensowną wartość 50px. Ale u Ciebie tak nie ma w HTML-u. Szerokość ustawiasz nie bezpośrednio w atrybucie style, tylko w osobnym arkuszu stylów (i bardzo słusznie robisz!). Czyli el.style.width by tej szerokości nie wyłapało.

Potrzebujesz tutaj pobrania aktualnej, wyliczonej wartości stylu -- niezależnie od tego skąd ten styl pochodzi (czy to z zewnętrznego pliku ze stylami, czy to z zagnieżdżonego arkusza, czy z atrybutu style lub od skryptu JS).

Powinieneś użyć getComputedStyle. Pogoogluj o tym. Zwróć jednak uwagę, że w IE nie ma tej funkcji, tylko jest troszkę inna, więc będziesz musiał "napisać" własną funkcję działającą jakgetComputedStyle. Piszę w cudzysłowach, bo ta funkcja była już napisana pięć milionów razy. Wystarczy, że ją skądś przekleisz, np. stąd: http://www.quirksmode.org/dom/getstyles.html . Funkcja nazywa się tam getStyle i użyjesz jej tak:

alert(getStyle(obj[i], 'width'));
0

Wielkie dzięki, o to mi chodziło:)
Mam w takim razie jeszcze jedno pytanko, jak ustawić jakiś atrybut?
Mam coś takiego:

function setStyle(el, attr, val){
  eval("document.getElementById('"+el.id+"').style."+attr+"='"+val+"';");
  var obj = document.getElementsByClassName(el.className);
  for(var i=0; i<obj.length; i++) /* dla innych elementów mających to samo className */
    eval("document.getElementById('"+obj[i].id+"').style."+attr+"='"+val+"';");
}

Sęk w tym że nie mogę już stosować np. "background-color"(tylko backgroundColor) tak jak w getStyle i w ogóle ta moja funkcja setStyle jest... beznadziejna.
(Chcę mieć możliwość dynamicznej zmiany css'a i innych styli bez odświeżania strony - fajnie jakby się dało operować na np. border-top-style).

3

Aaaaaaaaaaaaa!

NIGDY NIE UŻYWAJ eval() w ten sposób bo osobiście wsadzę łapy w monitor i cię UDUSZĘ! ;)

W ogóle nie używaj eval(), w 99.9999993% przypadków, gdy chcesz go użyć, tak naprawdę jest niepotrzebne. eval() jest wolne, niebezpieczne i nie chroni przed błędami składni. Narzędzia do sprawdzania jakości kodu JS w ogóle nie pozwalają na użycie tej funkcji.

JavaScript ma mnóstwo sposobów na ominięcie evala(). Są to sposoby szybsze, bezpieczniejsze, bardziej przejrzyste.

Tutaj np. użyłeś eval(), bo zapewne nie znałeś jednej z podstawowych notacji obiektowych w JavaScripcie. W JS nie musisz zawsze pisać obiekt.nazwaWlasnosci. Możesz też pisać obiekt["nazwaWlasnosci"] (dzięki czemu nazwa własności może zawierać nawet spacje, np. obiekt["nazwa własności"]). W nawiasach kwadratowych możesz podać po prostu string z nazwą własności, ale możesz też podać jakiekolwiek wyrażenie, które może zostać zamienione na string.

Poniższe linie są równoważne:

obj.nazwaWlasnosci = "abc";
obj["nazwaWlasnosci"] = "abc";
obj["nazwa" + "Wlasnosci"] = "abc"; // tak tak! łączymy stringi -- nie ma problemu

Taki sam efekt da poniższy kod:

var zmiennaZNazwaWlasnosci = "nazwaWlasnosci";
obj[zmiennaZNazwaWlasnosci] = "abc";

I tego ostatniego przykładu użyjemy, żeby przerobić to co Ty tam nasz w tym brzydkim evalu().

Masz tak:

// bleeeeeeee!
eval("document.getElementById('"+obj[i].id+"').style."+attr+"='"+val+"';");

To to samo co:

// ładniej
document.getElementById(obj[i].id).style[attr] = val;

Prawda, że czyściej? I szybciej i lepiej.

Tak naprawdę, tę linijkę możesz jeszcze uprościć, bo masz tam coś bez sensu.

Wykorzystujesz pole id z obiektu obj[i], żeby za pomocą document.getElementById() dostać się do... obj[i]. Czyli mówisz: mam tu pewien element w zmiennej obj[i]. Wezmę jego id i użyję document.getElementById, które zwróci mi... ten sam element, który już miałem w zmiennej obj[i]. LOL :). Trochę się zakręciliśmy.

Zamiast document.getElementById(obj[i].id) możesz więc napisać po prostu obj[i].

Czyli:

// jeszcze ładniej
obj[i].style[attr] = val;

Co do tego, że musisz używać backgroundColor zamiast background-color to co Ci to w sumie przeszkadza? To aż taki przypał?

Jeśli tak Ci to przeszkadza, to możesz na początku funkcji zmienić nazwę stylu z CSS-owej (z myślnikami) na JS-ową (bez myślników i w notacjiWielbłądziej). Można to zrobić, dodając na początek funkcji takie coś:

attr = attr.replace(/-(.)/g, function(wholeMatch, firstLetterOfNextWord) {
  return firstLetterOfNextWord.toUpperCase();
});

Może lepiej by było zapisać sobie JS-ową nazwę stylu w nowej zmiennej żeby nie modyfikować parametru funkcji (to raczej zła praktyka), ale to już drobnostka.

Aha: ta funkcja zadziała bez problemu dla border-top-style.

Ogólnie z Twoją funkcją setStyle są pewne problemy koncepcyjne. IMO ona powinna tylko ustawiać styl elementu el, a nie wszystkich elementów o tej samej klasie. To sugeruje, że być może chcesz użyć tej funkcji w zły sposób, gdy istnieje lepsza alternatywa do takiego zmieniania stylu. Co dokładniej chcesz zrobić?

0

To document.getElementById(obj[i].id) wiązało się z tym że stosowałem eval - rozumiem błąd ;]
...backgroundColor zamiast background-color... - mam w tablicy wypisane atrybuty które będą poddawane modyfikacji i jednak wolałbym mieć jedną tablice.

var styleattr   = new Array("width", "height", "margin", "float", "background-color", "display");
var styleattrjs = new Array("width", "height", "margin", "float", "backgroundColor", "display");

IMO ona powinna tylko ustawiać styl elementu el, a nie wszystkich elementów o tej samej klasie. - chcę zmieniać ten styl dla wszystkich elementów w danej klasie.
I jeszcze takie małe pytanko, jeśli można: Mam 2 divy, jeden w drugim - jak ustawić onmousemove, aby po najechaniu na "dziecko" funkcja onmousemove(i inne tego typu) nie działała w "rodzicu" tylko w "dziecku"? Bo efekt mam taki że jak jeżdżę po "dziecku" to wykonuje mi się onmousemove w 2 divach.
Wielkie dzięki za pomoc!

1

Nie mam teraz czasu/chęci żeby to sprawdzać, ale prawdopodobnie chodzi tu o bąbelkowanie zdarzeń (event bubbling). Pogooglaj lub od razu zerknij do http://www.quirksmode.org/js/events_order.html . Tam nawet jest coś o mousemove.

Prawdopodobnie będziesz musiał w jednej z funkcji obsługi zdarzenia wywołać evt.stopPropagation(). Jeśli to ma działać w IE, to musisz wykonać evt.stopPropagation() jeśli evt.stopPropagation istnieje (to dla normalnych przeglądarek) lub wykonać window.event.cancelBubble = true.

Jeszcze taki mały hint, skoro już optymalizujemy kod. Generalnie nie używaj konstruktora Array(), tylko literału tablicy, czyli nawiasów kwadratowych.

Poniższe linie są równoważne parami:

var pustaTablica = new Array();
var pustaTablica = [];

var styleattr = new Array("width", "height", "margin", "float", "background-color", "display"); // Twój kod
var styleattr = ["width", "height", "margin", "float", "background-color", "display"]; // To samo, zwięźlej

1 użytkowników online, w tym zalogowanych: 0, gości: 1