Este artigo foi traduzido por máquina.

HTML5

Detecção de navegador e recursos

P. Sascha Corti

 

Hoje em dia, se você estiver criando um site, não vai querer simplesmente que ele tenha uma ótima aparência; você vai querer que ele se sobressaia por muito tempo. Isso significa que seu site precisa funcionar não apenas nos navegadores de hoje, mas também nas futuras versões. Neste artigo, apresentarei algumas dicas e práticas recomendadas que ajudarão você a atingir esse objetivo.

Um pouco de histórico

Hoje, todos os navegadores da Web são criados com um objetivo comum: processar páginas da Web ideal de acordo com as especificações mais recentes.

Isso nem sempre era o caso. No passado, como fornecedores de navegador raced se torne predominante, mais implementado os recursos que estavam em alta demanda, mesmo se eles ainda não foram padronizados. Obviamente, cada navegador fazia em sua própria maneira. Aqui está um exemplo de como definir a transparência em CSS variados.

Internet Explorer antes de versão 8 compreendido CSS a seguir:

    .transparent {      /* Internet Explorer < 9 */
        width: 100%;
        filter:alpha(opacity=50);
    }

enquanto o Firefox tinha seu próprio atributo:

    .transparent {
        /* Firefox < 0.9 */
        -moz-opacity:0.5;
    }

como fez Safari:

    .transparent {
        /* Safari < 2 */
        -khtml-opacity: 0.5;
    }

Agora, no entanto, no CSS3, há uma forma unificada para definir a transparência de um elemento:

    .transparent {
        /* IE >= 9, Firefox >= 0.9, Safari >= 2, Chrome, Opera >= 9 */
        opacity: 0.5;
    }

Embora possa parecer bom para um navegador ir à frente para oferecer suporte a recursos fora do padrão, faz a vida de um desenvolvedor da Web mais difícil do que precisa ser, porque ele tem que cumprir todas as várias implementações do recurso em consideração ao adicioná-lo a uma página.

Marcação consistente

É a melhor maneira de certificar-se de que sua página da Web serão processados de forma otimizada em todos os navegadores enfocar a marcação que é certo ser suportado em todas as versões atuais dos navegadores.Até muito recentemente, isso era HTML 4.01, um padrão de 10 anos com recursos muito limitados.

Hoje, todos os navegadores estão convergindo em direção a HTML5 rico — mas muitas das novas especificações resumidas em um termo geral, incluindo a marcação de HTML5, suas APIs, como o DOM níveis 2 e 3, CSS3, SVG e EcmaScript 262, são ainda em desenvolvimento e, portanto, sujeitos a alterações.Os fornecedores de navegador estão continuamente adicionando suporte para novos recursos de HTML5, mas na prova bastante diferentes.

Firefox e Opera é geralmente muito rápido para adotar novas especificações de HTML5, às vezes, mesmo aqueles em desenvolvimento antecipado e sujeitos a alteração ou que têm problemas de segurança.Embora isso pode ser interessante para desenvolvedores testar os novos recursos, ele pode levar a páginas da Web que quebra entre versões do navegador devido às alterações drásticas entre uma especificação e sua implementação.Essa é uma experiência frustrante para desenvolvedores e usuários.Um exemplo disso foi Websockets entre Beta 7 e 8 de desativação do Firefox 4 por razões de segurança.

Cromo, que também é muito rápido adotar novos padrões de HTML5, stirred recentemente a comunidade de HTML5 com o anúncio que ele foi abandonando o suporte para o codec de vídeo h. 264 populares para HTML5 <video> elementos e switching em vez disso, o padrão de WEBM de royalties.Embora isso possa ser boa para os desenvolvedores que pagam licenças h. 264 no momento, ele adiciona outra opção que os desenvolvedores terão para controlar para oferecer suporte a tantos navegadores possível.

A Microsoft está mais lento implementar os padrões, mas ela mas trabalha junto com o W3C criar suítes de teste, ajudando a minimizar a ambigüidade nas especificações e construir uma base técnica para ajudar a trabalhar em homogenizing a maneira como seus navegadores processam HTML5 de fornecedores.Para ver o trabalho mais recente nessa área, dê uma olhada no Internet Explorer 10 plataforma Preview, que pode ser encontrado em IE Test Drive.Você também desejará fazer check-out de HTML5labs onde de corpos de especificações Microsoft antecipadas e instáveis de protótipos de padrões da Web, como o W3C.Consulte a seção, "maior interoperabilidade através do suporte a padrões," do guia de 9 do Internet Explorer para desenvolvedores para obter informações detalhadas sobre como 9 do Internet Explorer suporta as diversas especificações de HTML5 hoje.

Ainda assim, porque os novos padrões de HTML5 permanecem um movimento de destino, e porque a maioria dos usuários de Internet não usa as versões mais recentes dos vários navegadores da Web, atendendo a marcação da direita é cada vez mais importante.

Detecção de navegador

Uma abordagem para lidar com as diferenças entre os navegadores é usar a detecção do navegador.A maneira mais comum para isso é usar JavaScript para consultar o cabeçalho agente do usuário:

    <script type="text/javascript">
      if ( navigator.userAgent.indexOf("MSIE")>0 )
      {
        // Run custom code for Internet Explorer.
    }
    </script>

O problema dessa abordagem é dupla. Primeiro, ele combina vários suposições sobre os recursos do navegador oferece suporte em uma seleção. Uma única pressuposição errada pode quebrar o site. Então, como um desenvolvedor, você tem que controlar exatamente quais recursos oferece suporte a cada versão de um navegador específico.

O segundo problema é que essa verificação de navegador não considera versões do navegador e, portanto, não está obsoleta. Mesmo se ele funciona com a versão atual de um navegador, a próxima versão talvez não exijam — ou pior, pode remover suporte completamente para — uma solução alternativa que a detecção de navegador foi usada para adicionar ao site.

Portanto, se você tiver que usar a detecção do navegador, verifique se você considera a versão e só usa essa abordagem para detectar navegadores herdados, como mostrado na a Figura 1.

Figura 1 detectando navegadores herdados

    <script type="text/javascript">
      functiongetInternetExplorerVersion()
      // Returns the version of Internet Explorer or a -1 for other browsers.
    {
        var rv = -1;
        if(navigator.appName == 'Microsoft Internet Explorer')
        {
          var ua = navigator.userAgent;
          varre  = newRegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
          if(re.exec(ua) != null)
          rv = parseFloat( RegExp.$1 );
        }
        return rv;
      }
      functiononLoad()
      {
        var version = GetInternetExplorerVersion()
        if (version <= 7 && version > -1)
        {
          // Code to run in Internet Explorer 7 or earlier.
    }
      }
    </script>

A página de Biblioteca MSDN, "detectando navegadores mais efetivamente," tem mais informações, e você encontrará um artigo abrangente sobre como usar o objeto navigator e expressões regulares para detectar os vários navegadores e suas versões exatas em Tutoriais de JavaScript.

Começando com a versão 5, o Internet Explorer tem uma maneira exclusiva para detectar navegadores usando comentários condicionais. Essa sintaxe estende os comentários do HTML padrão. Você pode usar esses comentários condicionais com uma CSS para implementar determinados Internet Explorer específicos que você deseja que outros navegadores para ignorar as regras de CSS. No exemplo a seguir, "ie7.css" é carregado somente se o Internet Explorer 7 ou anterior for detectado:

    <!--[if lte IE 7]>
      <style TYPE="text/css">
        @import url(ie7.css);
      </style>
    <![endif]-->

Informações detalhadas sobre como usar comentários condicionais podem ser encontradas na página Biblioteca MSDN, "sobre comentários condicionais."

Dada a todos os problemas e limitações de detecção do navegador, no entanto, vamos examinar uma alternativa.

Detecção de recurso

Uma abordagem muito melhor para tratamento de diferenças entre navegadores da Web é usar a detecção de recurso. Antes de usar um recurso que você sabe que tem implementações diferentes nos vários navegadores, você executa um teste pequeno que procura a disponibilidade de um objeto específico, método, propriedade ou o comportamento. Na maioria dos casos isso pode ser feito pela tentativa de criar uma nova instância do recurso em questão e se esse instanciação retorna algo diferente de null, o navegador em execução saberá que esse recurso. Caso contrário, você pode acompanhar testando a disponibilidade de uma solução alternativa ou uma implementação de legado proprietária do recurso.

Comparando o navegador e o detecção de recurso

Vamos usar os diagramas no figuras 2, 3 e 4 para ajudar a visualizar como as duas abordagens funcionam em várias situações.

Possible Code Paths Through the Test Site
Figura 2 caminhos de código possível através do Site de teste

Results with Well-Known Browser Configurations
Figura 3 resultados com configurações conhecidas do navegador

Ao se deparar com configurações do navegador já conhecidos, ambos os métodos funcionarem, mas a detecção do navegador tem fixa suposição de que o recurso a e b do recurso são suportados pelo navegador, enquanto a detecção de recurso testa individualmente para cada recurso.

Unknown Browser Configuration
Figura 4 configuração desconhecida do navegador

É quando se depara com uma configuração de navegador desconhecido que as coisas ficam interessantes. Detecção de recurso manipula esse bem e descobre que o navegador é capaz de exibir um recurso, mas precisa que o código de fallback para b de recurso. Detecção de navegador, por outro lado, escolhe um caminho com base no nome do navegador ou escolhe o caminho padrão porque nenhuma das combinações consultado/versão de navegador corresponde. De qualquer forma, neste exemplo a página não processa corretamente porque há um caminho de código que conecta todos os segmentos de código válido mesmo que a página realmente contém todo o código necessário para exibir adequadamente nesta configuração desconhecida do navegador.

Exemplos de detecção de recurso

Há duas recomendações muito importantes ter em mente ao usar a detecção de recurso:

  • Sempre teste primeiro padrões como navegadores oferecem suporte freqüentemente o padrão mais recente, bem como a solução de legado.
  • Sempre destino só relacionadas a recursos em uma única verificação, efetivamente minimizando as suposições de capacidades do navegador.

Agora vamos examinar alguns exemplos de detecção de recurso.

O script a seguir cria dois caminhos de código. Ele primeiro verifica se o navegador dá suporte a window.addEventListener e se não for, testes, a disponibilidade do legacy apresentam window.attachEvent:

    <script type="text/javascript">
      if(window.addEventListener) {
        // Browser supports "addEventListener"
        window.addEventListener("load", myFunction, false);
      } else if(window.attachEvent) {
        // Browser supports "attachEvent"
        window.attachEvent("onload", myFunction);
      }
    </script>

Outra boa abordagem é encapsular a detecção de recurso em um conjunto de funções que podem ser usados em todo o código. Aqui é uma prática recomendada para detectar se o navegador oferece suporte a HTML5 <canvas> elemento e em caso afirmativo, certifica-se de que o método canvas.getContext('2d') está funcionando bem. Essa função simplesmente retorna true ou false, facilitando a reutilização.

    <script type="text/javascript">
      functionisCanvasSupported()
      {
        var elem = document.createElement('canvas'); 
        return!!(elem.getContext && elem.getContext('2d');
      }
    </script>

Uma coisa deve ter em mente quando usando a detecção de recurso é sempre usá-lo em recentemente criado elementos ou objetos de forma a evitar a possibilidade de que qualquer outro script na página tiver modificado o elemento ou objeto, pois ela foi criada, que poderia levar a resultados aleatórios ou irregular.

Detecção de recurso também funciona diretamente para alguns elementos HTML, como, por exemplo, HTML5 <video>, <audio> e <canvas> na forma de um "retorno". O navegador exibe o primeiro sub-elemento suportado da parte superior e oculta visualmente os elementos abaixo.

A forma mais fácil tem esta aparência:

    <video src="video.mp4">
        Your browser doesn't support videos natively.
    </video>

Um navegador que ofereça suporte a <video> elemento mostrará o vídeo "MP4", enquanto um navegador que não se voltará para o texto fornecido. Mas fallback também funciona em vários formatos de vídeo na marca do vídeo:

    <video>
        <source src="video.mp4" type="video/mp4" />
        <source src="video.webm" type="video/webm" />
        Your browser doen't suppport videos natively.
    </video>

Nesse caso, um navegador que ofereça suporte a HTML5 <video> primeiro tentará carregar vídeo mp4. Se ele não oferece suporte a esse formato, ele se voltará para o vídeo codificado em webm. Deve esse formato não ter suporte ou deve o navegador não suporte <video> ele voltará para o texto.

Obviamente, faz mais sentido para o retorno para um player de vídeo plug-in em vez do texto, caso o navegador não oferece suporte a HTML5 <video> em todos os. O exemplo a seguir utiliza um player de vídeo do Silverlight:

    <video>
        <source src="video.mp4" type='video/mp4' />
        <source src="video.webm" type='video/webm' />
        <object type="application/x-silverlight-2">
            <param name="source" value="http://url/player.xap">
            <param name="initParams" value="m=http://url/video.mp4">
        </object>
        Download the video <a href="video.mp4">here</a>.
    </video>

Uma lógica semelhante funciona bem em CSS. Em CSS, propriedades não reconhecidas são simplesmente ignoradas. Portanto, quando você deseja adicionar propriedades múltiplas experimentais, prefixado-fornecedor, conforme mostrado com "border-radius", abaixo, basta você incluir todas as variações no seu código. Isso pode se sentir um pouco impreciso, mas é fácil de usar e de todo o trabalho feito para casos como esse. Observe que é uma prática recomendada para colocar os prefixos específicos do fornecedor que deseja incluir primeiro e a marcação padrão pela última vez.

    <style type="text/css">
        .target
        {
            -moz-border-radius: 20px;
            -webkit-border-radius: 20px;
            border-radius: 20px;
        }
    </style>

Uma grande vantagem do suporte a detecção de recurso é que ele também funciona com navegadores que você ainda não estávamos pensando ao criar sua página e até mesmo com futuras versões dos navegadores porque ele não depende de suposições sobre quais recursos de um navegador dá suporte.

Desenvolvendo e testando o detecção de recurso

O Ferramentas de desenvolvedor F12 9 do Internet Explorer são ótimos para desenvolvimento e teste de detecção de recurso em muitos navegadores. Você pode usá-los para depurar script passo a passo e alterar usuário seqüência do agente do navegador, bem como para informar ao Internet Explorer para usar o mecanismo de processamento das versões anteriores**.**As figuras 5, 6, 7 e 8 mostrar alguns exemplos de como você pode usar essas ferramentas.

Using Breakpoints while Debugging JavaScript in Internet Explorer 9
Figura 5 usando pontos de interrupção durante a depuração do JavaScript no Internet Explorer 9

Running in “Document Mode: IE9 standards,” the bBrowser Uses the Modern addEventListener Method
Figura 6 em execução no "modo de documento: padrões IE9," o bBrowser usa o método de addEventListener moderno

Running in “Document Mode: IE7 standards,” the Debugger Falls Back to the Legacy attachEvent Method
Figura 7 executado no "modo de documento: padrões do IE7," o depurador cai volta para o método attachEvent de legado

You Can Change the Internet Explorer User Agent String on the Fly and Even Add Your Own Strings, Including Those for Mobile Browsers
Figura 8, você pode alterar o agente de usuário do Internet Explorer String sem interrupções e até mesmo adicionar suas próprias seqüências de caracteres, incluindo aqueles para os navegadores portáteis

Gerenciando o detecção de recurso em grandes projetos

Ao criar um projeto da Web complexo, criando e gerenciando todo o código de detecção de recurso podem ser entediantes. Felizmente, há grandes bibliotecas de JavaScript disponíveis que ajudá-lo nesse esforço, isto é, Modernizr e jQuery.

Modernizr possui detecção interna para a maioria dos recursos HTML5 e CSS3 que é muito fácil de usar em seu código. Ele tem muito amplamente adotado e constantemente aprimorado. Tanto Modernizr quanto jQuery são fornecidos com o ASP.Ferramentas de NET MVC.

Dê uma olhada no código em Figura 9, que detecta a capacidade do navegador para exibir as fontes da web sem usar o Modernizr e, em seguida, o código da a Figura 10 que usam Modernizr.

Figura 9 sem Modernizr

function(){
  var
    sheet, bool,
    head = docHead || docElement,
    style = document.createElement("style"),
    impl = document.implementation || { hasFeature: function()
      { return false; } };
    style.type = 'text/css';
    head.insertBefore(style, head.firstChild);
    sheet = style.sheet || style.styleSheet;
    var supportAtRule = impl.hasFeature('CSS2', '') ?
function(rule) {
        if (!(sheet && rule)) return false;
          var result = false;
          try {
            sheet.insertRule(rule, 0);
            result = (/src/i).test(sheet.cssRules[0].cssText);
            sheet.deleteRule(sheet.cssRules.length - 1);
          } catch(e) { }
          return result;
        } :
        function(rule) {
          if (!(sheet && rule)) return false;
          sheet.cssText = rule;
          return sheet.cssText.length !== 0 &&
            (/src/i).test(sheet.cssText) &&
            sheet.cssText
              .replace(/\r+|\n+/g, '')
              .indexOf(rule.split(' ')[0]) === 0;
        };
    bool = supportAtRule('@font-face { font-family: "font";
    src: url(data:,); }');
    head.removeChild(style);
    return bool;
  };

Figura 10 com Modernizr

    <script type="text/javascript" src"modernizr.custom.89997.js"></script>
    <script type="text/javascript">
      if(Modernizr.fontface){
        // font-face is supported
      }
    </script>

Adicionando suporte para recursos faltando

Detecção de recurso não elimina a sobrecarga de elaboração de uma solução alternativa quando testado navegador não oferece suporte a um recurso que você precisa. A amostra de vídeo HTML5 anterior, usando o Silverlight como fallback era uma solução óbvia. Mas e sobre outros recursos de HTML5, como <canvas> ou as novas marcas de semânticas, tais como <nav>, <section> e <article>, <aside>, ou o novo <header> e <footer>?

Um número crescente de prontas "fallbacks" para muitos recursos do HTML5, conhecidas como correções e polyfills, pode aliviar esse fardo. Eles são fornecidos na forma de bibliotecas CSS e JavaScript ou às vezes, mesmo que o Flash ou do Silverlight controles que você pode usar em seu projeto, adicionando recursos de HTML5 ausentes para navegadores sem suporte contrário-los.

A idéia geral é que os desenvolvedores devem ser capazes de desenvolver com as APIs HTML5, e scripts podem criar os métodos e objetos que devem existir. O desenvolvimento dessa maneira obsoleta significa que quando os usuários atualizarem, não precisa alterar o código e usuários serão movidos para a melhor experiência nativa corretamente.

A diferença entre as correções e polyfills é que correções imitam apenas um recurso e cada um tem sua própria API exclusiva, enquanto polyfills emular o recurso HTML5 propriamente dito e sua API exata. Assim, em termos gerais, usar um polyfill reduz a inconveniência de ter de adotar uma API exclusiva.

O HTML5 entre navegador Polyfills coleção no github contém uma lista crescente de correções disponíveis e polyfills.

Modernizr, por exemplo, inclui o "HTML5Shim" para suporte à semântica de marca, mas é fácil carregar outras correções e polyfills se Modernizr detecta que um recurso não é suportado.

Adicionando suporte dinamicamente

Você pode estar se perguntando, "Não adicionar todas essas bibliotecas de script fazer minha página enorme e lentos para carregar?"

Bem, é verdade que usando muitas dessas bibliotecas de suporte pode sobrecarregar consideravelmente seu site da Web, faz sentido para carregá-los dinamicamente somente quando forem realmente necessários. No caso de uma correção ou polyfill, a prática recomendada é carregá-los somente quando você tiver detectado que o navegador não suporta o recurso nativo do HTML5.

Novamente devemos está com sorte porque há uma grande biblioteca que dá suporte exatamente nesse cenário: yepnope.js

Yepnope é um carregador de recursos assíncronos que trabalha com JavaScript e CSS e totalmente dissocia o pré-carregamento de execução. Isso significa que você tem controle total sobre quando o recurso é executado e você pode alterar a ordem sem interrupções. Yepnope será integrado no Modernizr 2, mas também pode ser usado por conta própria. Vamos dar uma olhada em sua sintaxe:

    <script type="text/javascript" src="yepnope.1.0.2-min.js"></script>
    <script type="text/javascript">
        yepnope({
            test : Modernizr.geolocation,
            yep  : 'normal.js',
            nope : ['polyfill.js', 'wrapper.js']
        });
    </script>

Este exemplo da página Yepnope testa a capacidade do navegador para usar o HTML5 geolocalização usando Modernizr.Se suportado, seu próprio código (normal.js) será carregado; Caso contrário, será carregada uma polyfill personalizado (que consiste em polyfill.js e wrapper.js).

Os pontos mais importantes estão resumidos na a Figura 11.

Figura 11 Detecção do navegador e recurso detecção Dos e dicas sobre

  FAZER NÃO
Detecção de navegador

Tente evitar totalmente.

ou

Teste para um navegador específico e versão.

Fazer suposições para futuros navegadores testando apenas o nome do navegador.
Detecção de recurso O teste de padrões pela primeira vez. Suponha que recursos não relacionados em um teste.

Recursos:

Saiba mais sobre a detecção de navegador e o recurso em:

P. Sascha Corti works Suíça Microsoft como desenvolvedor especialista voltada para os Microsoft platform e desenvolvedor de ferramentas do sistema, e ele apresenta as mais recentes tendências à comunidade de desenvolvedores suíço.Atualmente, ele se concentra na plataforma do Windows 7 do telefone e de tecnologias da Web.

Financiar os estudos envolvidos ciências da computação na ETH Zurich e gerenciamento de informações com a Universidade de Zurique.

Há sete anos Sascha era um desenvolvedor de software e o arquiteto de um grande banco Suíço e trabalhou como um especialista de engenharia e tecnologia de sistemas para várias empresas hi-tech American, incluindo Silicon Graphics e Microsoft.

Você pode ler sobre suas atividades mais recentes no seu weblogs em http://techpreacher.corti.com e https://blogs.msdn.com/swiss_dpe_team/ ou siga-lhe Twitter @TechPreacher.

Graças aos seguintes especialistas técnicos para revisão deste artigo: Justin Garret eThomas Lewis