Passo a passo: aplicativo leitor (JavaScript e HTML)

Os aplicativos que incorporam uma experiência de leitura estão se popularizando rapidamente à medida que os computadores tablet se tornam mais predominantes. Aqui destacamos os novos recursos CSS e HTML5 que você pode usar para criar ótimos aplicativos leitores. Depois de ler este artigo, você terá uma compreensão sólida dos principais recursos de layout usados nesses aplicativos e também terá um aplicativo leitor básico com o qual iniciar. Agora, vamos aprender mais sobre a criação de ótimas experiências de leitura no Windows.

Este artigo acompanha a Amostra de modelos de regiões CSS dinâmicas.

Introdução

O Windows 8 oferece aos desenvolvedores e designers uma variedade de novos recursos de HTML5 e CSS3 para a criação de experiências de leitura inéditas e exclusivas. Graças às novas tecnologias, como regiões e grade CSS, você pode especificamente criar publicações digitais que combinam as vantagens dos — layouts fluidos, estilos baseados em marcação, conteúdo acessível e interatividade — HTML com os layouts inovadores que até agora só eram possíveis nos domínios de impressão.

Tradicionalmente, as páginas da Web são renderizadas como colunas únicas de conteúdo vertical. Os parágrafos são empilhados sobre parágrafos e outras imagens, com elementos flutuantes ocasionais para oferecer alguma variedade visual. As "páginas" eram criadas simplesmente segmentando o conteúdo em documentos HTML diferentes; não havia uma maneira baseada na marcação para pegar um fluxo de conteúdo e segmentá-lo em telas de texto individuais. A ausência de controle rígido para a criação de colunas e sua adaptação ao tamanho da tela significava que várias páginas eram otimizadas somente para uma resolução específica, como 1024 × 768. Você pode ver um ótimo exemplo de uma experiência ruim quando um texto otimizado para resoluções pequenas é renderizado em um monitor widescreen de alta resolução. Esta imagem mostra um layout de uma coluna em um monitor com taxa de proporção 4:3.

Coluna única de texto renderizado em um monitor de 4:3.

Esta imagem mostra o mesmo layout em um monitor widescreen com espaço em branco vazio.

Coluna única de texto renderizado em um monitor widescreen.

Em contraste, uma página criada para aproveitar ao máximo o espaço disponível provavelmente apresentaria várias colunas de texto, preenchendo assim a tela e garantindo que cada linha de texto não fosse muito longa facilitar a leitura. Por meio de alguns pequenos refinamentos, os títulos podem aumentar de tamanho para chamarem mais a atenção, e as imagens podem ficar em uma posição mais destacada com o texto envolvendo-as.

Esta imagem mostra um layout de leitor aprimorado para monitores widescreen.

Layout para monitores widescreen

Há muito tempo, os designers de impressão conseguem criar esses layouts facilmente, pois precisam lidar apenas com um tamanho de página fixo conhecido previamente. Para criar páginas que se adaptam de forma inteligente a diferentes tamanhos de tela, use ferramentas, como consultas de grade e mídia CSS, para projetar seu layout.

Este artigo, juntamente com a Amostra de modelos de regiões CSS dinâmicas, descreve como criar layouts com ótima aparência para a leitura adaptada a uma grande variedade de tamanhos de tela. Em Verificando os novos recursos de leitura de CSS, abordamos vários novos recursos que você pode usar para apresentar texto e imagens de formas inovadoras. Em Reunindo recursos para criar uma ótima experiência de leitura, continuamos a mostrar como combinar esses recursos para criar uma experiência de leitura adaptada que reúne um excelente design com layouts fluidos e envolventes.

Verificando os novos recursos de leitura de CSS

Vamos analisar os novos recursos de CSS que você pode usar em seu aplicativo leitor: várias colunas, hifenização, grade, regiões e exclusões.

Várias colunas

O CSS multi-column permite aos designers formatar o conteúdo embutido (como texto) de um elemento—por exemplo, um elemento div ou o body de uma página—em várias colunas adjacentes de tamanho igual, localizadas uma ao lado da outra. Por exemplo, a simples adição da propriedade column-count: 2; das CSS a uma div produz um layout como este na imagem abaixo.

Utilização do CSS Multicolumn em um bloco de texto

Entretanto, o Multi-column tem algumas limitações. As colunas devem ser todas do mesmo tamanho e estar posicionadas uma ao lado da outra. Além disso, o conteúdo de um elemento com várias colunas obedece a propriedade overflow das CSS; isto é, recorta, adiciona uma barra de rolagem ou estouros, criando colunas adicionais ao lado do elemento original. Por essas razões, o CSS Regions pode ser uma opção melhor para layout de texto em situações em que um layout de página mais variado é indicado ou onde há uma possibilidade de que o conteúdo embutido de um elemento possa estourar o elemento. A imagem abaixo mostra novas colunas sendo criadas pelo estouro do elemento de várias colunas.

Novas colunas criadas pelo estouro do elemento de várias colunas

Observação  O CSS multi-column tem uma opção de "equilíbrio" para assegurar que todas as colunas sejam do mesmo comprimento e que a última coluna não seja significativamente menor que as outras. Esse recurso não assegura que as colunas tenham o mesmo número de linhas ou que as linhas se alinhem entre as colunas. O conteúdo de um elemento de várias colunas deve ser formatado para que todos os elementos sejam um múltiplo de uma única altura de linha, incluindo o preenchimento de parágrafos e imagens.

A imagem abaixo mostra como um layout de várias colunas equilibrado (contornado em azul claro) formata o conteúdo em oposição a um layout desequilibrado (contornado em vermelho).

Layouts multicoluna equilibrados e desequilibrados

Observação  Esse exemplo está bem equilibrado porque os elementos dentro das colunas correspondem às dimensões e ao espaçamento das colunas.

O código abaixo mostra como os dois layouts foram criados.



<!DOCTYPEHTML>
<html>

<head>
  <style>

    #div1{
        width: 180px;
        height: 300px;
        column-fill: balance;
        column-count: 2;
        float: left;
        border: solid 2px lightblue;
        margin-right: 8px;
    }
    #div2{     
        width: 180px;
        height: 300px;
        column-fill: auto;
        column-count: 2;
        float: left;
        border: solid 2px red;
        margin-right: 8px;
    }
  </style>
</head>

<body>
<div id="div1" class="div1">
    Hi friend! Hi friend! Hi friend! Hi friend! 
    Hi friend! Hi friend! Hi friend! Hi friend! 
    Hi friend! Hi friend! Hi friend! Hi friend! 
    Hi friend! Hi friend! Hi friend! Hi friend! 
    Hi friend! Hi friend! Hi friend! Hi friend! 
</div>
<div id="div2">
    Hi friend! Hi friend! Hi friend! Hi friend! 
    Hi friend! Hi friend! Hi friend! Hi friend! 
    Hi friend! Hi friend! Hi friend! Hi friend! 
    Hi friend! Hi friend! Hi friend! Hi friend! 
    Hi friend! Hi friend! Hi friend! Hi friend!    
</div>
</body>

</html>



Hifenização

O multi-column permite dispor o conteúdo embutido, como texto, em colunas relativamente estreitas. Mas, o conteúdo dessas colunas pode aparecer irregular, especialmente quando o comprimento médio das palavras é um grande percentual da largura da coluna. Em particular, quando as colunas são combinadas com a propriedade text-align: justify, grandes "rios" de espaços em branco podem aparecer entre as palavras, dando ao conteúdo uma aparência irregular e pouco atraente, conforme exibido aqui.

Texto não hifenizado, totalmente justificado com excesso de espaço em branco

Proporcionalmente, agora oferecemos a capacidade de hifenizar automaticamente as palavras, para que as linhas possam ser mais densamente compactadas e ainda oferecendo uma experiência de leitura forte como exibido aqui.

Texto hifenizado, totalmente justificado com espaço em branco mínimo

A hifenização está definida em parte na Especificação de Texto Nível 3 das CSS do W3C. A hifenização de CSS permite:

  • Especificar o tamanho mínimo de fragmento de palavra que segue e antecede uma quebra de hifenização.
  • Especificar um número máximo de linhas consecutivas hifenizadas.
  • Evitar que as últimas palavras dos parágrafos e das colunas sejam hifenizadas.
  • Especificar um caractere de hifenização personalizado.
A hifenização no Windows 8 e no Internet Explorer 10 tem suporte em diversos idiomas, sendo recomendada para uso para várias colunas e regiões CSS.

Grade

A ideia principal por trás do layout de grade das CSS é dividir uma página em um conjunto definido de linhas e colunas e, depois definir a posição e o tamanho dos elementos com base nessas linhas e colunas usando CSS. Como o tamanho das linhas e colunas pode ser definido como fixo, flexível ou dimensionado para o conteúdo, é fácil criar um layout que preenche completamente a tela inteira, independentemente do tamanho da tela.

Por exemplo, a imagem abaixo mostra um exemplo de um leitor que foi dividido em duas colunas e três linhas com vários elementos. Alguns dos elementos devem permanecer fixos enquanto outros aumentam ou diminuem conforme o tamanho da janela do navegador é alterado.

Fluxo de texto entre as Regiões de uma página

Com o layout de grade das CSS, você pode conseguir esse design iniciando com a marcação abaixo.


<div id="grid">
    <div id="logo">Reader Logo</div> 
    <div id="page">Page</div> 
    <div id="bookmarks">Bookmarks</div> 
    <div id="content">Reader Content</div> 
    <div id="controls">Controls</div> 
</div>


O elemento div nomeado grid é definido como um contêiner de grid pela aplicação do estilo display: grid das CSS. Você pode definir as várias linhas e colunas como flexíveis, que aumentam ou diminuem com base no espaço disponível ou como dimensionamento automático, que dimensiona a linha ou coluna à largura ou à altura do maior elemento posicionado dentro dela.


#grid {
    display: -ms-grid;
    -ms-grid-columns: auto 1fr;
    -ms-grid-rows: auto 1fr auto;
}

Depois que a grade é definida, você pode posicionar elementos individuais em células de grade específicas. Como mostra a marcação abaixo, você não apenas pode especificar que um elemento seja colocado em uma linha e coluna específicas no CSS, mas também pode especificar que um elemento deva abranger várias linhas e colunas, e especificar o alinhamento horizontal ou vertical de um elemento dentro de uma célula ou intervalo de células.



#logo { -ms-grid-column: 1; -ms-grid-row: 1 } 
#page { -ms-grid-column: 1; -ms-grid-row: 3 } 
#bookmarks { -ms-grid-column: 1; -ms-grid-row: 2; -ms-grid-row-align: start } 
#content { -ms-grid-column: 2; -ms-grid-row: 1; -ms-grid-row-span: 2 } 
#controls { -ms-grid-column: 2; -ms-grid-row: 3; -ms-grid-column-align: center }


Os elementos podem ser especificados para ter um tamanho fixo ou para preencher a largura ou altura disponível da célula em que estejam. No exemplo anterior, o elemento content aumenta junto com a tela, enquanto os outros elementos, como o elemento logo, permanecem fixos em tamanho.

Observação  Como a CSS3 (Folha de Estilos em Cascata Nível 3) ainda é uma especificação emergente, todas as propriedades de grade são prefixadas com "-ms-" durante o uso do Internet Explorer 10.

Combinando o recurso de layout de grade com consultas de mídia das CSS3, você pode especificar layouts completamente diferentes para resoluções, proporções e orientações de tela diferentes. Por exemplo, você pode definir um número diferente de linhas ou colunas para diferentes tamanhos de tela, atribuindo menos colunas para um layout vertical de "retrato" e mais colunas para um layout horizontal de "paisagem". Você também pode especificar que as linhas e colunas sejam dimensionadas de forma diferente.

Além disso, como a posição dos elementos em uma grade é independente da ordem em que eles são especificados—isto é, sua posição é ditada exclusivamente pelas CSS em vez de por sua ordem na marcação HTML—é fácil dar aos elementos diferentes organizações em diferentes tamanhos de tela ou mesmo evitar a exibição de alguns elementos inteiramente em alguns layouts.

Regiões

As regiões das CSS permitem a um designer fluir o conteúdo de um elemento que o contém em outro, assim conectando os fluxos de conteúdo em diferentes áreas em uma página ou em várias páginas. Essa habilidade possibilita designs novos e inovadores. Por exemplo, a ilustração abaixo mostra o texto fluindo entre duas regiões em uma página. Observe que, ao contrário das várias colunas das CSS, as regiões permitem que os contêineres tenham tamanhos diferentes e não sejam imediatamente adjacentes uns aos outros.

Fluxo de texto entre várias Regiões de várias páginas

As Regiões também podem ser usadas para a fluência de um único fluxo de conteúdo, como o texto de um artigo, em várias páginas virtuais, como visto na ilustração abaixo.

Content.html fluindo para Master.html via CSS Regions

Observe que "páginas" nesse contexto não são as páginas criadas pelo processo de impressão, como as páginas que são estilizadas usando uma regra "@page" das CSS, mas em vez disso são os elementos div que contêm uma ou mais regiões. Por meio da disposição desses elementos div em uma área rolável (geralmente com pontos de ajuste para simular inversão de páginas), podemos criar uma experiência de leitura paginada onde um único fluxo de conteúdo é exibido em várias páginas de tela inteira e não como uma região de rolagem individual do conteúdo. Além disso, as regiões podem ser combinadas com grades CSS e consultas de mídia para criar páginas que se adaptam precisamente a um tamanho de tela específico, e para gerar o número exato de páginas necessárias para exibir um determinado fluxo de conteúdo.

O diagrama abaixo mostra uma visão geral de alto nível de como as regiões funcionam. O conteúdo de um documento de origem (Content.html) flui em várias regiões em um documento de modelo mestre (Master.html).

Content.html fluindo para Master.html via CSS Regions

É importante observar que as regiões não participam na cascata de estilos CSS em um documento, assim uma regra de estilo disposta em uma região específica (por exemplo, text-color: red) não afeta o conteúdo dentro da região. Mas, as regras de estilo dispostas no próprio documento de conteúdo afetam o conteúdo, embora elas não afetem todos os elementos no documento de modelo mestre.

Da mesma forma, o conteúdo exibido pelas regiões no modelo mestre não existe no DOM (Document Object Model) do modelo mestre; a observação de Master.html através do Explorador do DOM no Microsoft Visual Studio, por exemplo, mostra que cada região está vazia. Em vez disso, o conteúdo exibido pelas regiões existe em um elemento iframe oculto que existe em Master.html e aponta para Content.html.

Exclusões

As exclusões das CSS oferecem uma maneira de fazer com que o conteúdo embutido se ajuste ao redor de um elemento, como uma imagem, um título ou um texto explicativo. As exclusões são similares às flutuações das CSS, exceto que em vez de serem empurradas para um lado ou outro de um bloco que as contêm, as exclusões podem ser posicionadas no meio de um bloco e ter o conteúdo fluindo em torno de ambos os lados, como exibido aqui.

Conteúdo embutido fluindo em torno de uma Exclusão

As exclusões podem interagir com vários elementos circundantes ao mesmo tempo. Por exemplo, uma exclusão pode ser circundada por várias regiões e fazer com que o conteúdo de cada região seja ajustado ao redor dela. Para obter mais informações sobre como fazer isso, consulte Reunir recursos para criar uma ótima experiência de leitura.

Observe que as regiões podem ser apenas blocos retangulares no Internet Explorer 10. Entretanto, várias regiões podem ser colocadas ao lado de outra para criar regiões não retangulares.

Reunir recursos para criar uma ótima experiência de leitura

Agora que já analisamos as tecnologias individuais que você pode usar para criar uma ótima experiência de leitura no Windows 8, vamos discutir como combinar essas tecnologias. Faremos isso juntos examinando a Amostra de modelos de regiões CSS dinâmicas. Primeiro, abordaremos como combinar uma grade, consultas de mídia, regiões e exclusões para criar modelos de páginas individuais. Depois, veremos o código JavaScript que instancia esses modelos de página até que todo o conteúdo do documento de origem tenha sido exibido. Finalmente, veremos o código JavaScript adicional que pode ajustar o número de páginas com base em uma mudança no tamanho da tela ou do tamanho da fonte.

Disposição de modelos de páginas

Esta imagem mostra a página 1 da amostra, incluindo:

  • Um título ("Amostra de modelos de regiões dinâmicas").
  • Duas regiões colocadas como duas colunas paralelas.
  • Uma exclusão definida no meio da página (a imagem de Saturno), o que faz o conteúdo ao redor nas duas regiões circundá-la.
.

Combinação de Grade, Regiões e Exclusões para criar uma página exclusiva

A imagem abaixo ilustra a estrutura da grade da página 1.

Quebra de grade da Página 1 da Amostra de modelos de regiões dinâmicas

Especificamente, a página 1 consiste de um elemento div único que se transforma em uma grade por meio do uso da propriedade display: -ms-grid. Os outros elementos, como regiões e exclusões são estabelecidos nesse div único. Essa grade recebe toda a largura e altura da área do aplicativo, que pode ser a tela inteira ou um subconjunto dela se o aplicativo estiver em modo preenchido ou ajustado.

A Página 1 é dividida em 4 colunas e 5 linhas. Cada coluna tem o tamanho de 1 unidade fracionária (1FR), que representa uma parte de todo o espaço disponível para a grade depois que o tamanho fixo e as faixas de tamanho automático (linhas ou colunas) são dispostos. Nesse caso, como não há nenhuma faixa de tamanho fixo ou automático, cada coluna obtém 25% da largura da área do aplicativo.

Em contraste, a primeira das 5 linhas na página 1 é uma linha de tamanho automático, enquanto as linhas restantes são dimensionadas em frações. O título da página está na linha 1, que ocupa o maior espaço necessário para exibir o título "Amostra de modelos de regiões dinâmicas". A altura restante da área do aplicativo é usada pelas linhas restantes, cada uma delas recebe apenas menos de 25% da área do aplicativo.

Dentro da grade há duas regiões. Cada região se estende por duas colunas e quatro linhas: a primeira região é posicionada na linha 2, coluna 1 (as grades das CSS são indexadas em 1), e a segunda região fica na linha 2, coluna 3. Cada região é simplesmente um elemento div que tem a propriedade -ms-flow-from: content definida. Como cada região compartilha o mesmo nome de fluxo, o fluxo de conteúdo começa com a primeira região, passa para a próxima e avança através das regiões subsequentes em páginas diferentes.

A grade também é usada para posicionar uma exclusão no meio da página. Nesse caso, a exclusão é um elemento div com uma imagem de Saturno posicionada no meio desta por meio do atributo de exibição CSSflexbox. A exclusão é criada pela definição da propriedade -ms-wrap-flow: both. Quando a exclusão estiver posicionada no meio da grade (linha 3, coluna 2, abrangendo duas linhas e duas colunas), qualquer conteúdo embutido que cruze com a exclusão será ajustado em torno dela. Esse comportamento está em contraste com os elementos flutuantes tradicionais, que teriam de ser posicionados em direção a um lado da página.

Observe que as regiões e a exclusão estão posicionadas para se alongarem através das linhas e colunas. Isso acontece porque o aplicativo está sendo executado em um dispositivo com uma resolução de tela diferente ou porque o aplicativo foi alternado entre os modos de tela inteira e preenchida. Conforme o tamanho da resolução do aplicativo é alterado, os elementos na tela também aumentam e diminuem. Esse é claramente o comportamento ideal para regiões, porque queremos que as áreas de texto preencham mas não excedam a área do aplicativo. O texto que não couber em uma região simplesmente será movido para baixo para a próxima região. Dependendo do conteúdo, um designer pode não querer que uma imagem se alongue com o tamanho da tela, preferindo manter a taxa de proporção ou o tamanho absoluto da imagem. Isso é feito facilmente pela alteração das propriedades –ms-grid-row-align e –ms-grid-column-align a partir dos seus valores padrão de stretch.

As próximas duas imagens mostram a quebra de grade das páginas 2 e 3 da Amostra de modelos de regiões CSS dinâmicas. Ambas as páginas são dispostas em uma grade de 4 × 4 onde cada linha e coluna está em um tamanho fracionário igual do espaço disponível. A única diferença substancial entre as páginas (além da óbvia diferença nas imagens de tela de fundo) é que a página 2 apresenta uma região individual que abrange duas linhas e duas colunas no meio da página, enquanto a página 3 apresenta várias regiões irregulares em toda a página. Juntas, todas estas páginas demonstram um único fluxo de conteúdo que atinge várias páginas via regiões das CSS.

Aqui está a página 2.

Quebra de grade da Página 2 da Amostra de modelos de regiões dinâmicas

E aqui está a página 3.

Quebra de grade da Página 3 da Amostra de modelos de regiões dinâmicas

Observação  O conteúdo exibido em todas as três páginas acima está totalmente justificado e hifenizado. Essas propriedades de estilo são definidas no conteúdo (do arquivo content.html) em vez de em qualquer uma das próprias regiões. Isso ocorre porque, como mencionado anteriormente, a cascata de estilos não penetra regiões.

Instanciar modelos de página

Nós discutimos como criar páginas com regiões, uma grade e exclusões. Você pode ver essas páginas como page1.html, page2.html e page3.html no projeto Amostra de modelos de regiões CSS dinâmicas. Entretanto, ainda não examinamos como essas páginas são criadas dinamicamente quando o aplicativo é ativado. Como o número de páginas necessárias para exibir um documento de conteúdo varia de acordo com o tamanho da tela e da fonte—telas menores ou maiores implicam em menos palavras por página e, portanto mais páginas necessárias–devem ser instanciadas dinamicamente em tempo de execução. Agora, vamos falar sobre como instanciar modelos predefinidos em um aplicativo da Windows Store, um de cada vez, até que todo o documento de conteúdo seja exibido. Posteriormente, vamos discutir como adaptar o número de páginas com base nas alterações de tempo de execução para o tamanho da tela ou da fonte.

O exemplo abaixo mostra a estrutura da Amostra de modelos de regiões CSS dinâmicas. Especificamente, um elemento div com o atributo de id de appContainer contém um elemento de origem iframe e um elemento pageContainerdiv que contém as páginas individuais. O iframe aponta para o documento content.html a ser exibido em várias regiões em várias páginas. Como o iframe tem a propriedade -ms-flow-into: content, ele não é exibido. O appContainerdiv e as páginas individuais ocupam todo o espaço disponível na tela alocado para o aplicativo porque todos têm largura e altura definidas como 100% da área do aplicativo.



#sourceIFrame {
    -ms-flow-into: content;
    width: 500px;
    height: 500px;
    border: 1px solid black;
}

#pageContainer
{
    display: -ms-box;
    height: 100vh;
}


Estrutura do aplicativo de amostra

O pageContainerdiv foi configurado como uma flexbox por meio do uso da propriedade display: -ms-box e o elemento body foi definido como overflow: scroll. Como o comportamento padrão de uma flexbox é dispor todos os seus elementos ao lado do outro e, portanto para ser ampliado horizontalmente conforme necessário, o usuário pode rolar as páginas por deslocamento panorâmico horizontal com o mouse ou por entrada por toque.

Observação  Um designer poderia facilmente alternar para um modelo de paginação vertical definindo a propriedade -ms-box-orient: vertical. Além disso, para que a rolagem por toque funcione corretamente, o elemento iframe deve estar no mesmo elemento pai que as páginas que estão sendo roladas. Isso obviamente não é um problema quando o elemento de rolagem é o próprio elemento body mas pode ser um problema em outras configurações de iframe e de páginas.

Agora que já vimos como o aplicativo leitor será finalmente estruturado, precisamos discutir como as páginas são colocadas no aplicativo. Este código de exemplo de regionTemplatePage.js mostra a matriz de pageTemplates.


    var pageTemplates = [
        '/html/page1.html',
        '/html/page2.html',
        '/html/page3.html',
        '/html/pageDefault.html'
    ];

A matriz de pageTemplates aponta para os vários arquivos do pacote do aplicativo que correspondem às páginas que serão instanciadas e os arquivos de referência são usados pela função createPages. A função createPages é chamada por uma função ouvinte de eventos que é acionada pelo evento load do iframe de origem.

O código abaixo mostra createPages, a função que seleciona e instancia modelos de página da matriz de pageTemplates.



    function createPages() {

        var targetPage;

        if (currentPage &gt; (pageTemplates.length - 1)) {
            targetPage = pageTemplates[pageTemplates.length - 1];
        } else {
            targetPage = pageTemplates[currentPage];
        }
              
        var flexboxElement = document.getElementById('pageContainer');
        WinJS.UI.Fragments.render(targetPage, flexboxElement).then(function () {
            msSetImmediate(function () {
                currentPage += 1;
                var flexboxElement = document.getElementById('pageContainer');
                var pages = flexboxElement.querySelectorAll('.page');
                var lastPage = pages[pages.length - 1];
                var regions = lastPage.querySelectorAll(searchClass);
                var lastRegion = regions[regions.length - 1];
                if (lastRegion.msRegionOverflow === 'overflow') {
                    createPages();
                }
            });
        });
    }


Essa função executa três etapas principais: seleciona um modelo, renderiza o modelo e determina se um modelo adicional é necessário. Na primeira etapa, a variável targetPage é definida ao modelo de página apropriado, dependendo do número da página que está sendo renderizada no momento. Por meio de um contador incrementado por createPages, a amostra do SDK é definida para renderizar cada página na matriz de pageTemplates uma vez antes de renderizar a próxima página. Se a amostra tiver atingido o fim da matriz, o último modelo de página será usado até que o conteúdo esteja esgotado.

Quando o modelo da página tiver sido identificado, createPages chama a função de carregador de fragmentos da Biblioteca do Windows para JavaScript para renderizar o modelo selecionado no elemento pageContainer. O carregador de fragmentos toma todo o conteúdo no elemento body do arquivo da página de destino (page1.html na amostra) e o insere em um elemento especificado (nesse caso, o elemento pageContainer). Como o carregador de fragmentos é uma chamada assíncrona, o resto da função createPages deve esperar até depois que a função then estiver ativada.

Depois que then está ativada, createPages navega o DOM para encontrar a última região na última página. createPages testa essa região para descobrir se ainda há conteúdo adicional a ser renderizado a partir do documento de conteúdo. Se a propriedade msRegionOverflow não estiver definida como "overflow", o documento de conteúdo foi totalmente renderizado, na última região ou em uma região em outro lugar na última página. Se a propriedade msRegionOveflow estiver definida como "overflow", o conteúdo adicional continua a ser renderizado. Nesse caso, createPages é chamada e começa novamente.

Observação  A chamada inicial de createPages é encerrada antes que a função then seja ativada por causa da chamada a msSetImmediate. Isso significa que createPages não é verdadeiramente recursiva, porque apenas uma instância de createPages é colocada na pilha de chamadas por vez.

Observação  O mecanismo de seleção de modelos que createPages usa é obviamente algo que pode ser adaptado pelos designers para atender às suas próprias necessidades. Por exemplo, em vez de reutilizar o último modelo repetidamente, a função pode ser alterada para percorrer repetidamente a gama de modelos, desde que haja conteúdo adicional a ser exibido. Como alternativa, a matriz simples e o mecanismo de seleção de modelos usados por createPages podem ser substituído por lógica arbitrariamente complexa que poderia selecionar um modelo de página com base em outros fatores, como a seção de conteúdo da origem que está sendo renderizada ou a resolução específica ou orientação do dispositivo host.

Finalmente, a função createPages é adequada para aplicativos leitores em que cada página é diferente da próxima. Entretanto, alguns aplicativos, como livros eletrônicos, podem requerer maior quantidade de páginas e menos tipos distintos de páginas. Para esses aplicativos, especialmente quando o conteúdo de origem for grande (por exemplo, o texto completo de um livro longo) recomenda-se que vários modelos de páginas sejam carregados simultaneamente. Por exemplo, em vez de um arquivo Page1.html que contém um único modelo, um aplicativo leitor de ebooks pode ter um arquivo Pages.html que contenha vários modelos, cada um deles tendo layout de duas ou três colunas simples. Ao carregar essas páginas em conjunto na memória, o desempenho geral pode ser significativamente aumentado. Observe que seguir essa metodologia pode fazer com que createPages"ultrapasse" o número de páginas necessárias e deixe algumas páginas sem conteúdo. Esse problema pode ser solucionado por meio do uso da função resizePages, que está descrita mais detalhadamente na próxima seção.

Redimensionamento de modelos de página

Anteriormente nós descrevemos como criar modelos de página usando uma grade, regiões e exclusões, e como instanciar esses modelos de páginas no aplicativo em tempo de execução. Entretanto, também é importante ser capaz de alterar o número de páginas em tempo de execução em resposta a eventos externos. Mesmo se o documento do conteúdo permanecer inalterado, as alterações à área do aplicativo podem fazer com que o estado de exibição do aplicativo seja alterado de tela inteira para o modo preenchido ou ajustado, e assim fazer com que as páginas diminuam ou aumentem. As alterações à área do aplicativo podem fazer com que quantidades diferentes de conteúdo caibam em cada página e podem exigir que páginas sejam adicionadas ou removidas do aplicativo.

O exemplo de código abaixo mostra a função resizePages, que permite a adição ou remoção de páginas em resposta a um evento externo. No caso da Amostra de modelos de regiões CSS dinâmicas, resizePages é chamada em resposta a uma mudança no estado de exibição do aplicativo, mas a função também pode ser chamada em resposta a um evento, como o redimensionamento de uma fonte.



    function resizePages() {
        var flexboxElement = document.getElementById('pageContainer');
        var pages = flexboxElement.querySelectorAll('.page');
        var lastPage = pages[pages.length-1];
        
        var regions = lastPage.querySelectorAll(searchClass);
        var lastRegion = regions[regions.length-1];

        if (lastRegion.msRegionOverflow === 'overflow') {
            createPages();
        }
        else {
            var firstRegion = regions[0];
            while (firstRegion.msRegionOverflow === 'empty')
            {
                flexboxElement.removeChild(lastPage);
                currentPage = currentPage - 1;
                lastPage = pages[currentPage-1];
                regions = lastPage.querySelectorAll(searchClass);
                firstRegion = regions[0];
            }
        }
    }


A função resizePages primeiro localiza a última região na última página. Como a função createPages, ela depois testa essa região para determinar se há conteúdo adicional que requer páginas adicionais a serem exibidas. Se não houver conteúdo a ser exibido, resizePages chamacreatePages. Como alternativa, se não houver nenhum conteúdo adicional na última região, a função localiza a primeira região na última página. Se a propriedade msRegionOverflow indicar que a região não está vazia, nós saberemos que o documento do conteúdo termina na última página; nenhuma outra ação é executada porque não há conteúdo pelo menos na primeira região na última página e nenhum conteúdo está estourando a última região. Como alternativa, se a primeira região na última página estiver vazia, não há nenhum conteúdo na última página e ela fica totalmente vazia. A função resizePages remove a última página e chama a si mesma para testar a nova última página.

Em combinação, resizePages e createPages são suficientes para adicionar e remover páginas de um aplicativo. Os designs de modelo de página de exemplo podem se flexionar para preencher uma variedade de tamanhos de telas, mas um designer pode querer ter páginas que se reestruturem em diferentes estados de exibição, orientações ou resoluções de tela, ao contrário de simplesmente ajustar-se para preencher o espaço em excesso. A Amostra de modelos de regiões CSS dinâmicas ilustra como criar modelos de página que se reestruturam em diferentes estados de exibição. A imagem abaixo mostra como o exemplo se reestrutura em uma série de páginas empilhadas verticalmente, onde cada página é uma região individual no modo ajustado. Essa abordagem envolve ocultar todo o conteúdo, exceto uma região por modelo de página, definindo apenas um elemento para ser uma região no modo ajustado e reorientando o elemento pageContainer para exibir as páginas verticalmente.

Página Modelos de regiões dinâmicas no modo ajustado

Para entender como isso é feito, veja a marcação de Page1.html. Há duas regiões na página 1, cada uma com uma identificação e classe específicas atribuídas. Ambas as regiões fazem parte da classe fullregion, enquanto apenas a primeira região faz parte da classe snappedregion. A classe fullregion define seus elementos como tendo a propriedade –ms-flow-from definida como content, o que significa que o material no elemento iframe será exibido com elas. A classe snappedregion é inicialmente definida da mesma forma.

Quando as regras na consulta de mídia do estado de exibição ajustado são ativadas, somente a classe snappedregion ainda define a propriedade –ms-flow-from como content; a classe fullregion define a propriedade em vez de null. Isso tem o efeito de tornar apenas um dos elementos div na página uma região; o conteúdo flui dessa região para regiões em outras páginas. Além disso, como as outras páginas no aplicativo também têm a classe snappedregion definida somente em seus primeiros elementos da região, quando o aplicativo é colocado no modo ajustado, apenas uma região em cada página mostra o conteúdo do documento de origem. O código abaixo mostra o HTML e as CSS da página 1.



    <body>
        <div id="page1" class="page">
            <div id="logoContainer">
                <img id="floatLogo" src="/images/Saturn.jpg" />
            </div>
            <h1 id="title">Dynamic region Templates Sample</h1>
            <div id="page1region1" class="fullregion snappedregion"></div>
            <div id="page1region2" class="fullregion"></div>
        </div>
    </body>
    



.fullregion {
    -ms-flow-from: content;
}

.snappedregion
{
    -ms-flow-from: content;
}

/*In snapped mode the fullregion class no longer receives content from the content stream, but the snappedregion class does.*/
@media (-ms-view-state: snapped)
{
    .fullregion 
    {
        -ms-flow-from: null;
    }

    .snappedregion
    {
        -ms-flow-from: content;
    }

    /*Change the navigation direction to vertical for RTL and LTR languages*/
    #pageContainer
    {
        -ms-box-orient: block-axis;
    }


As classes de estilo, em combinação com as regras de estilo definidas no código abaixo, mostram como o aplicativo é transformado no modo ajustado. Especificamente, todos os elementos exceto a primeira região são definidos como display: none, enquanto a primeira região é definida para ocupar toda a página (menos a primeira linha, que é reservada para o título do artigo). Quando esse processo é replicado em todas as páginas, e a matriz de pageContainer é definida para dispor páginas em uma direção do bloco (vertical no exemplo de código abaixo), o aplicativo se transforma em uma série de regiões de páginas inteiras que mostram partes diferentes do mesmo documento de conteúdo. Em combinação com os algoritmos de resizePages e createPages descritos anteriormente, o aplicativo criará páginas suficientes no modo ajustado para renderizar totalmente o documento de origem.



            /* In snapped mode we set the first region to take up the entire page, and hide all other regions. */
            @media all and (-ms-view-state: snapped)
            {
                #page1region1
                {
                    -ms-grid-row: 2;
                    -ms-grid-column: 1;    
                    -ms-grid-row-span: 4;
                    -ms-grid-column-span: 4;
                    padding: 0;
                }
        
                #page1region2
                {
                    display: none;                
                }
        
                #logoContainer
                {
                    display: none;
                }
                
            }


Observação  O mecanismo básico para ajuste do layout de uma página, como descrito acima, pode ser aplicado a outros designs também. Por exemplo, um designer pode querer adicionar ou remover uma região de uma página dependendo se a página estiver no modo 16:9 ou 4:3. Esse ajuste pode ser feito usando consultas de mídia CSS para modificar as propriedades –ms-flow-from e display conforme necessário. As consultas de mídia também podem ser usadas para alterar a estrutura de uma grade das CSS. Por exemplo, o layout do conteúdo pode mudar de uma grade de 2 × 4 para uma grade de 4 ×, dependendo se a tela estiver no modo retrato ou paisagem. Um designer também pode usar consultas de mídia das CSS para exibir ou não várias imagens ou outros elementos, dependendo da resolução e da orientação da tela.

Sobre o autor

Chris Jones é gerente de programação na equipe de apresentação e composição do Windows. Durante o desenvolvimento do Windows 8, ele trabalhou no estilo do controle das CSS e em recursos de layout, como CSS Regions, CSS3 Floats, Grid, Flexbox e Multi-column. Ele pode ser acessado em cjon@microsoft.com.

Tópicos relacionados

Criando excelentes aplicativos de notícias

 

 

Mostrar:
© 2014 Microsoft