Polímero - Shadow DOM e estilo
Shadow DOM é uma nova propriedade do DOM usada para construir componentes.
Example
No código a seguir, o componente de cabeçalho inclui o título da página e o botão de menu.
<header-demo>
<header>
<h1>
<button>
Shadow DOM permite localizar os filhos em uma subárvore com escopo definido, que é conhecido como shadow tree.
<header-demo>
#shadow-root
<header>
<h1>
<button>
A raiz da raiz da sombra é chamada de topo da árvore de sombra e o elemento que está anexado à árvore é chamado de host sombra (header-demo). Este host sombra inclui uma propriedade chamada shadowRoot, que especifica a raiz sombra. A raiz da sombra identifica o elemento do host usando uma propriedade do host.
Shadow DOM e composição
A árvore de sombra pode ser renderizada em vez dos filhos do elemento, se houver um elemento no DOM de sombra. Os filhos do elemento podem ser renderizados adicionando o elemento <slot> à árvore de sombra.
Por exemplo, use a seguinte árvore de sombra para <header-demo>.
<header>
<h1><slot></slot></h1>
<button>Menu</button>
</header>
Adicione os filhos ao elemento <my-header> como -
<header-demo>Shadow DOM</header-demo>
O cabeçalho substitui o elemento </slot> pelos filhos especificados acima como -
<header-demo>
<header>
<h1>Shadow DOM</h1>
<button>Menu</button>
</header>
</header-demo>
Conteúdo substituto
O conteúdo de fallback pode ser exibido quando não há nós alocados para o slot. Por exemplo -
<my-element>
#shadow-root
<slot id = "myimgicon">
<img src = "img-demo.png">
</slot>
<slot></slot>
<my-element>
Você pode fornecer seu próprio ícone para um elemento como -
<my-element>
<img slot = "myimgicon" src = "warning.png">
<my-element>
Distribuição multinível
Você pode alocar o elemento de slot para um slot, o que é conhecido como distribuição multinível.
Por exemplo, pegue dois níveis de uma árvore de sombra conforme mostrado abaixo -
<parent-element>
#shadow-root
<child-element>
<!-- display the light DOM children of parent-element inside child-element -->
<slot id = "parent-slot">
<child-element>
#shadow-root
<div>
<!-- Render the light DOM children inside div by using child-element -->
<slot id = "child-slot">
Considere o seguinte código -
<parent-element>
<p>This is light DOM</p>
<parent-element>
A estrutura de uma árvore achatada é semelhante à seguinte.
<parent-element>
<child-element>
<div>
<slot id = "child-slot">
<slot id = "parent-slot">
<p>This is light DOM</p>
Shadow DOM usa as seguintes APIs de Slot para verificar a distribuição -
HTMLElement.assignedSlot - Aloca o slot para um elemento e retorna nulo, se não houver alocação de um elemento para um slot.
HTMLSlotElement.assignedNodes - Ele fornece a lista de nós junto com o slot e retorna os nós distribuídos, quando você define a opção flatten como true.
HTMLSlotElement.slotchange - Este evento é disparado quando há mudanças nos nós distribuídos do slot.
Retargeting de evento
Ele especifica o destino do evento no qual o elemento pode ser representado no mesmo escopo do elemento de escuta. Ele fornece um evento de um elemento personalizado, que parece vir da tag do elemento personalizado, em oposição a um elemento interno.
Example
O exemplo a seguir mostra o uso de retargeting de evento no Polymer.js. Crie um arquivo chamado index.html e coloque o seguinte código nele.
<!doctype html>
<html>
<head>
<title>Polymer Example</title>
<script src = "bower_components/webcomponentsjs/webcomponents-lite.js"></script>
<link rel = "import" href = "bower_components/polymer/polymer.html">
<link rel = "import" href = "retarget-event.html">
</head>
<body>
<template id = "myapp" is = "dom-bind">
<retarget-event on-tap = "clicky"></retarget-event>
</template>
<script>
var myval = document.querySelector('#myapp');
myval.clicky = function(e) {
console.log("The retargeted result:", Polymer.dom(myval));
console.log("Normal result:", e);
};
</script>
</body>
</html>
Agora, crie outro arquivo chamado retarget-event.html e inclua o código a seguir.
<link rel = "import" href = "bower_components/polymer/polymer-element.html">
//it specifies the start of an element's local DOM
<dom-module id = "retarget-event">
<template>
<span>Click on this text to see result in console...</span>
</template>
<script>
Polymer ({
is: 'retarget-event',
});
</script>
</dom-module>
Output
Para executar o aplicativo, navegue até o diretório do projeto criado e execute o seguinte comando.
polymer serve
Agora abra o navegador e navegue até http://127.0.0.1:8081/. A seguir será a saída.
Clique no texto acima e abra o console para ver um evento redirecionado, conforme mostrado na captura de tela a seguir.
Shadow DOM Styling
Você pode definir o estilo do DOM de sombra usando as propriedades de estilo, que herdam do host para a árvore de sombra.
Example
<style>
.mydemo { background-color: grey; }
</style>
<my-element>
#shadow-root
<style>
//this div will have blue background color
div { background-color: orange; }
</style>
<div class = "mydemo">Demo</div>
DOM Templating
A subárvore DOM pode ser criada para um elemento usando o modelo DOM. Você pode criar a raiz de sombra para o elemento e copiar o modelo em uma árvore de sombra adicionando o modelo DOM a um elemento.
O modelo DOM pode ser especificado de duas maneiras -
Crie um elemento <dom-module>, que deve corresponder ao nome de um elemento junto com um atributo id.
Defina um elemento <template> dentro de <dom-module>.
Example
<dom-module id = "my-template">
<template>I am in my template!!!</template>
<script>
class MyTemplate extends Polymer.Element {
static get is() { return 'my-template' }
}
customElements.define(MyTemplate.is, MyTemplate);
</script>
</dom-module>
Definir o estilo DOM de sombra de um elemento
Shadow DOM permite definir o estilo dos elementos personalizados usando propriedades de estilo, como fontes, cores de texto e classes, sem aplicá-lo fora do escopo do seu elemento.
Vamos estilizar o elemento host usando o :hostseletor (um elemento anexado ao DOM sombra é chamado de host). Crie um arquivo chamado Polymer-app.html e adicione o seguinte código a ele.
<link rel = "import" href = "../../bower_components/polymer/polymer-element.html">
<dom-module id = "polymer-app">
<template>
<style>
:host {
color:#33ACC9;
}
</style>
<h2>Hello...[[myval]]!</h2>
</template>
<script>
class PolymerApp extends Polymer.Element {
static get is() { return 'polymer-app'; }
static get properties() {
return {
myval: {
type: String, value: 'Welcome to Tutorialspoint!!!'
}
};
}
}
window.customElements.define(PolymerApp.is, PolymerApp);
</script>
</dom-module>
Execute o aplicativo conforme mostrado no capítulo anterior e navegue atéhttp://127.0.0.1:8000/. A seguir será a saída.
Estilo de conteúdo com ranhura
É possível criar slots no modelo de um elemento, que são ocupados em tempo de execução.
Example
O exemplo a seguir descreve o uso de conteúdo encaixado no modelo do elemento. Crie um arquivo index.html e adicione o seguinte código nele.
<!doctype html>
<html>
<head>
<title>Polymer Example</title>
<link rel = "import" href = "bower_components/polymer/polymer.html">
<link rel = "import" href = "slotted-content.html">
</head>
<body>
<slotted-content>
<div slot = "text">This is Polymer.JS Slotted Content Example</div>
</slotted-content>
</body>
</html>
Agora crie outro arquivo chamado slotted-content.html e inclua o código a seguir.
<link rel = "import" href = "bower_components/polymer/polymer-element.html">
<dom-module id = "slotted-content">
<template>
<style>
::slotted(*) {
font-family: sans-serif;
color:#E94A9D;
}
</style>
<h2>Hello...[[prop1]]</h2>
<h3>
<div><slot name='text'></slot></div>
</h3>
</template>
<script>
Polymer ({
is: 'slotted-content', properties: {
prop1: {
type: String,
value: 'Welcome to Tutorialspoint!!',
},
},
});
</script>
</dom-module>
Execute o aplicativo conforme mostrado no exemplo anterior e navegue até http://127.0.0.1:8081/. A seguir será a saída.
Usando Módulos de Estilo
Você pode compartilhar os estilos entre os elementos junto com os módulos de estilo. Especifique os estilos no módulo de estilo e compartilhe-os entre os elementos.
Example
O exemplo a seguir mostra como usar o módulo de estilo entre os elementos. Crie um arquivo index.html e adicione o seguinte código nele.
<!doctype html>
<html>
<head>
<title>Polymer Example</title>
<link rel = "import" href = "bower_components/polymer/polymer.html">
<link rel = "import" href = "style-module.html">
</head>
<body>
<style-module></style-module>
</body>
</html>
Crie outro arquivo chamado style-module.html com o código a seguir.
<link rel = "import" href = "bower_components/polymer/polymer-element.html">
<dom-module id = "style-module">
<template>
<!-- here, including the imported styles from colors-module page -->
<style include="colors-module"></style>
<style>
:host {
font-family: sans-serif;
color: green;
}
</style>
<h2>Hello...[[prop1]]</h2>
<p class = "color1">Sharing styles with style modules 1...</p>
<p class = "color2">Sharing styles with style modules 2...</p>
<p class = "color3">Sharing styles with style modules 3...</p>
</template>
<script>
Polymer ({
is: 'style-module', properties: {
prop1: {
type: String, value: 'Welcome to Tutorialspoint!!',
},
},
});
</script>
</dom-module>
Agora, crie mais um arquivo denominado colors-module.html , que fornece os módulos de estilo para os elementos, conforme mostrado no código a seguir.
<link rel = "import" href = "bower_components/polymer/polymer-element.html">
<dom-module id = 'colors-module'>
<template>
<style>
p.color1 {
color: #EA5AA5;
}
p.color2 {
color: #4B61EA;
}
p.color3 {
color: #D3AA0A;
}
</style>
</template>
</dom-module>
Execute o aplicativo e navegue até http://127.0.0.1:8081/. A seguir será a saída.
Use propriedades personalizadas
As propriedades CSS personalizadas podem ser usadas para definir o estilo da aparência do elemento em seu aplicativo usando o elemento Polymer. As propriedades personalizadas fornecem variáveis CSS em cascata, que podem ser usadas fora do ambiente de elementos personalizados que evitam a dispersão dos dados de estilo em uma folha de estilo.
As propriedades personalizadas podem ser definidas de forma semelhante às propriedades CSS padrão, que herdam da árvore DOM composta. No exemplo anterior, você pode ver as propriedades CSS personalizadas definidas para os elementos.
De acordo com a herança CSS, se não houver estilo definido para um elemento, ele herdará o estilo de seu pai, conforme mostrado no código a seguir.
<link rel = "import" href = "components/polymer/myelement-style.html">
<myelement-style>
<style is = "myelement-style">
p {
color: var(--paper-red-900);
}
paper-checkbox {
--paper-checkbox-checked-color: var(--paper-red-900);
}
</style>
</myelement-style>
<body>
<p><paper-checkbox>Check Here</paper-checkbox></p>
</body>