2014-04-07 10 views
5

Zasadniczo mam element na stronie, który może być wstawiany w wielu różnych lokalizacjach. Nie ma on ustawionego koloru tła, ale w zależności od koloru tła miejsca, w którym został wstawiony, mogę wprowadzić kilka zmian.Jak uzyskać efektywny kolor tła przezroczystego elementu za pomocą javascript/jQuery

Moje pytanie brzmi: jak uzyskać efektywny kolor tła dla elementu, nawet jeśli ten kolor tła mógł zostać odziedziczony po rodzicu (potencjalnie aż po ciało).

Oto uproszczony przykład, gdzie chciałbym znaleźć background-color z .color-me

<div class="cont"> 
    <div class="color-me">what's my background-color?</div> 
</div> 

I codepen: http://codepen.io/evanhobbs/pen/FbAnL/

+0

Jestem prawie pewien, że to niemożliwe. Lub jeśli jest to niezwykle trudne do wdrożenia. Dlaczego tego potrzebujesz? Jestem pewien, że musi być prostszy sposób. –

+0

Dzięki. Używam spin.js (http://fgnass.github.io/spin.js/) owiniętego w widok szkieletu i muszę przekazać kolor pokrętła jako opcję dla init. Ale widok może być wstawiony zarówno na jasnym, jak i ciemnym tle, więc musiałby mieć inny kolor. Czy to ma sens? –

+1

@EvanHobbs, złożoność pojawia się, gdy trzeba zacząć brać pod uwagę obrazy tła, gradienty, wartości 'rgba' i krycie.Uzyskanie koloru najbliższego obiektu macierzystego przy nieprzejrzystym kolorze tła jest stosunkowo proste, może to nie być rzeczywisty kolor za elementem. – zzzzBov

Odpowiedz

5

Jest to możliwe, biorąc pod uwagę kilka (dość duże) zastrzeżenia. zzzzBov sumuje je dobrze w komentarzu na pytanie:

... złożoność jest w momencie trzeba zacząć biorąc pod obrazami konto tła, gradienty, wartości RGBA i zadymienia. Uzyskanie koloru najbliższego obiektu macierzystego przy nieprzejrzystym kolorze tła jest stosunkowo proste, może to nie być rzeczywisty kolor za elementem.

Z tymi zastrzeżeniami w miejscu, w zasadzie trzeba uzyskać kolor tła elementu, a jeśli jest przezroczysty, przejdź do elementu nadrzędnego i tak dalej.

Różne przeglądarki mają różne poglądy „przezroczysty”, oto przykład obejmujące większość z nich: Updated Pen

$(function() { 
    var bc; 
    var $elm = $(".color-me"); 
    while (isTransparent(bc = $elm.css("background-color"))) { 
    if ($elm.is("body")) { 
     console.log("Gave up"); 
     return; 
    } 
    $elm = $elm.parent(); 
    } 
    console.log("Effective color: " + bc); 

    function isTransparent(color) { 
    switch ((color || "").replace(/\s+/g, '').toLowerCase()) { 
     case "transparent": 
     case "": 
     case "rgba(0,0,0,0)": 
     return true; 
     default: 
     return false; 
    } 
    } 
}); 

Nie jestem wcale pewien, że to jest możliwe ze wszystkimi przeglądarkami, a zwłaszcza nie te, które oddać wartość rgb (nie rgba) dla obliczonego koloru.

+0

w rzeczywistości nie działa dla wielu elementów z tą samą klasą na stronie, ponieważ pokazuje ten sam wynik. –

+0

@ Good.luck: To jest przykładowy kod i działa tylko dla pierwszego dopasowania danego selektora (w końcu jest tylko jeden w pisaku). Jeśli chcesz przeglądać zapałki, przeglądasz zapałki i robisz to dla każdego z nich. –

+0

tak, ten będzie działał dla wszystkich elementów, przepraszam, myślałem, że wysłałeś dokładny kod. –

1

wolę jsfiddle ale tutaj jest zaktualizowaną codepen .. http://codepen.io/anon/pen/nhDGC Dodano anonimowa funkcja więc z niego korzystać wystarczy zadzwonić $('.yourselector').getBg();

jQuery.fn.getBg = function() { 
return $(this).parents().filter(function() { 

    var color = $(this).css('background-color'); 

    if(color != 'transparent' && color != 'rgba(0, 0, 0, 0)' && color != undefined) 
    { return color; 
    } 
}).css('background-color'); 
}; 

$(function() { 
    //console.log($('.cont').css('background-color')); 
    console.log($('.color-me').getBg()) 
    $('.color-me').append($('.color-me').getBg()); 

    console.log($('.color-me2').getBg()) 
    $('.color-me2').append($('.color-me2').getBg()); 
}); 

Filtruje rodzice + powróci gdy znajdzie kolor tła istniejącego.

+0

To działa dobrze, ale warto wspomnieć, że to nie sprawdzi oryginalnego elementu, więc jeśli chcesz, możesz zmień drugi wiersz na następujący: return $ (this) .parents(). addBack(). filter (function() { Który następnie dodaje oryginalny element do łańcucha. –

0

Oto elegancki sposób rozwiązania tego problemu (przepraszam, wolę CoffeeScript). Zaczyna szukać od siebie, ale zawsze możesz po prostu użyć $el.parents().each ->.

findClosestBackgroundColor = ($el) -> 
    background = 'white' 
    $.merge($el, $el.parents()).each -> 
     bg = $(this).css('background-color') 
     if color isnt 'transparent' and !/rgba/.test(color) 
     background = bg 
     return false 
    background 

DEMO: Zastosowanie coffeescript.org skompilować to javascript i uruchomić to w konsoli na dowolnej stronie, która ma jQuery włączone.

Powiązane problemy