2012-06-04 11 views
15

Chcę wyświetlać różne pliki javascript w zależności od tego, czy przeglądarka obsługuje przejście CSS3, czy nie. Czy istnieje lepszy sposób wykrywania wsparcia przejścia niż mój kod poniżej?Wykryj obsługę przejścia z JavaScriptem

window.onload = function() { 
    var b = document.body.style; 
    if(b.MozTransition=='' || b.WebkitTransition=='' || b.OTransition=='' || b.transition=='') { 
     alert('supported'); 
    } else { 
     alert('NOT supported') 
    } 
} 
+6

Nie chcę aby to biblioteka dla tego. – user1087110

+0

Sprawdź ten wątek: http://stackoverflow.com/a/13081497/104380 – vsync

Odpowiedz

3

Modernizor wykryje to za Ciebie. Użyj this link, aby utworzyć niestandardową wersję do pobrania, która zawiera tylko przejścia 2D CSS3 i/lub 3D.

Po jej uruchomieniu, można albo test dla klasy csstransitions na html Tag (CSS) lub w JavaScript, test jeśli Modernizr.csstransitions jest true.

Więcej docs: http://modernizr.com/docs/#csstransitions

+12

Dzięki. Ale nie chcę dodawać do tego biblioteki :) – user1087110

+0

Dlaczego nie? Nie ma sensu odnawiać koła! –

+0

Program budujący Modernizr pozwala wybrać tylko te funkcje, które chcesz wykryć, co daje najmniejszy możliwy kod. To było wielokrotnie testowane i udoskonalane, więc to naprawdę najlepszy sposób na zrobienie tego rodzaju rzeczy. – Blazemonger

36

Myślę też w tym modernizr jest przesadą. Poniższa funkcja powinna działać dla dowolnej funkcji.

function detectCSSFeature(featurename){ 
    var feature = false, 
    domPrefixes = 'Webkit Moz ms O'.split(' '), 
    elm = document.createElement('div'), 
    featurenameCapital = null; 

    featurename = featurename.toLowerCase(); 

    if(elm.style[featurename] !== undefined) { feature = true; } 

    if(feature === false) { 
     featurenameCapital = featurename.charAt(0).toUpperCase() + featurename.substr(1); 
     for(var i = 0; i < domPrefixes.length; i++) { 
      if(elm.style[domPrefixes[i] + featurenameCapital ] !== undefined) { 
       feature = true; 
       break; 
      } 
     } 
    } 
    return feature; 
} 

var hasCssTransitionSupport = detectCSSFeature("transition"); 

Zainspirowany https://developer.mozilla.org/en-US/docs/CSS/Tutorials/Using_CSS_animations/Detecting_CSS_animation_support

+4

Jak opisałem w elm.style [featurename] jako pusty ciąg. Dodałem! == undefined przy pierwszej kontroli; if (elm.style [nazwa funkcji]! == undefined) {feature = true; } i teraz działa. – Stoffe

1

Oto kolejny kod testowania. Może to przesada, ale funkcja próbuje ustawić właściwość CSS na obiekt DOM, a następnie odczytać z niej.

Nigdy nie testowałem tego kodu na dużej ilości egzotycznych przeglądarek, ale jest to bezpieczniejsze niż sprawdzanie dostępności CSS. Ach, tak, może odróżnić wsparcie transformacji 2D od wsparcia transformacji 3D! Po prostu podaj wartości właściwości CSS, które chcesz przetestować!

Dodatkowym atutem tego kodu jest wykrycie obsługiwanego prefiksu dostawcy (jeśli istnieje). Możliwe wartości powrotne:

false, gdy funkcja nieobsługiwana lub

{ 
    vendor: 'moz', 
    cssStyle: '-moz-transition', 
    jsStyle: 'MozTransition' 
} 

gdy funkcja obsługiwana

/** 
* Test for CSS3 feature support. Single-word properties only by now. 
* This function is not generic, but it works well for transition and transform at least 
*/ 
testCSSSupport: function (feature, cssTestValue/* optional for transition and transform */) { 
    var testDiv, 
     featureCapital = feature.charAt(0).toUpperCase() + feature.substr(1), 
     vendors = ['', 'webkit', 'moz', 'ms', 'o'], 
     jsPrefixes = ['', 'Webkit', 'Moz', 'ms', 'O'], 
     defaultTestValues = { 
      transition: 'left 2s ease 1s', 
      transform: 'rotateX(-180deg) translateZ(.5em) scale(0.5)' 
      // This will test for 3D transform support 
      // Use other values if you need to test for 2D support only 
     }, 
     testFunctions = { 
      transition: function (jsProperty, computed) { 
       return computed[jsProperty + 'Delay'] === '1s' && computed[jsProperty + 'Duration'] === '2s' && computed[jsProperty + 'Property'] === 'left'; 
      }, 
      transform: function (jsProperty, computed) { 
       return computed[jsProperty].substr(0, 9) === 'matrix3d('; 
      } 
     }; 

    /* test given vendor prefix */ 
    function isStyleSupported(feature, jsPrefixedProperty) { 
     if (jsPrefixedProperty in testDiv.style) { 
      var testVal = cssTestValue || defaultTestValues[feature], 
       testFn = testFunctions[feature]; 
      if (!testVal) { 
       return false; 
      }  

      testDiv.style[jsPrefixedProperty] = testVal; 
      var computed = window.getComputedStyle(testDiv); 

      if (testFn) { 
       return testFn(jsPrefixedProperty, computed); 
      } 
      else { 
       return computed[jsPrefixedProperty] === testVal; 
      } 
     } 
     return false; 
    } 

    //Assume browser without getComputedStyle is either IE8 or something even more poor 
    if (!window.getComputedStyle) { 
     return false; 
    } 

    //Create a div for tests and remove it afterwards 
    if (!testDiv) { 
     testDiv = document.createElement('div'); 
     document.body.appendChild(testDiv); 
     setTimeout(function() { 
      document.body.removeChild(testDiv); 
      testDiv = null; 
     }, 0); 
    } 

    var cssPrefixedProperty, 
     jsPrefixedProperty; 

    for (var i = 0; i < vendors.length; i++) { 
     if (i === 0) { 
      cssPrefixedProperty = feature; //todo: this code now works for single-word features only! 
      jsPrefixedProperty = feature; //therefore box-sizing -> boxSizing won't work here 
     } 
     else { 
      cssPrefixedProperty = '-' + vendors[i] + '-' + feature; 
      jsPrefixedProperty = jsPrefixes[i] + featureCapital; 
     } 

     if (isStyleSupported(feature, jsPrefixedProperty)) { 
      return { 
       vendor: vendors[i], 
       cssStyle: cssPrefixedProperty, 
       jsStyle: jsPrefixedProperty 
      }; 
     } 
    } 

    return false; 
} 

GitHub: https://github.com/easy-one/CSS3test

0

Z modernizr 3.0 (alfa), należy może generować niestandardowe kompilacje lokalnie. Może to rozwiązać wyżej wspomniany problem "przesady" - chociaż nie jestem do końca jasny w tej kwestii (ale zakładam, że jest to rozmiar). Nowe API dostarcza metodę "kompilacji", do której możesz przekazać json zawierający testy, które chciałbyś dołączyć do kompilacji.

Używam czegoś takiego w moim haszyszu, ale łyk nie jest potrzebny - wystarczy prosty skrypt węzła.

gulp.task('js:modernizr', function() { 
    var modConfig = JSON.parse(fs.readFileSync('modernizr-config.json', { 
      encoding: 'utf8' 
     })); 
    modernizr.build(modConfig, function(res) { 
     fs.writeFileSync('modernizr.js', res); 
     return true; 
    }); 
}); 

A przykładem 'modernizr-config.json' pliku byłoby

{ 
    "classPrefix": "", 
    "options": [ 
    "addTest", 
    "atRule", 
    "domPrefixes", 
    "hasEvent", 
    "html5shiv", 
    "html5printshiv", 
    "load", 
    "mq", 
    "prefixed", 
    "prefixes", 
    "prefixedCSS", 
    "setClasses", 
    "testAllProps", 
    "testProp", 
    "testStyles" 
    ], 
    "feature-detects": [ 
    "css/transforms", 
    "css/transforms3d", 
    "css/transformstylepreserve3d", 
    "css/transitions", 
    "touchevents", 
    "workers/webworkers", 
    "history" 
    ] 
} 

Pełne plik konfiguracyjny jest zawarty w pakiecie modernizr.

Dzięki takiemu podejściu można skorzystać z dobrze utrzymanego pakietu testowego Moderniser za pomocą instalatorów pakietów i łatwo dodawać/usuwać testy w razie potrzeby. Mniej testów, oczywiście mniejszy plik.

Opcja „setClasses” doda powiązany klasę testową do HTML, ale można również skorzystać z 3,0 zdarzeń asynchronicznych tak:

Modernizr.on('csstransitions', function(bool) { 
    if (bool === true) // do transition stuffs 
}