Matthew Hardin Matthew Hardin - 1 month ago 9
HTML Question

Why is getElementsByClassName() accessing elements in the shadow DOM?

I am using the Polymer framework to build a web application. I have a custom table element which uses other basic Polymer elements as the building blocks. The table element has one column, and several rows of information. I am working on a behavior to highlight information in the table. The highlight behavior will either highlight an entire row in the table, or just specific bits of relevant information in the row.

I created a new custom element in which the tables and the highlight behavior would function. Tables which have rows that get highlighted get a class of highlight.

<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../highlight-behavior/highlight-behavior.html">
<link rel="import" href="../custom-table/custom-table.html">

<dom-module id="test-sync">
<template>
<style>
:host {
display: block;
box-sizing: border-box;
}
</style>

<custom-table class="highlight"></custom-table>
<custom-table class="highlight"></custom-table>
<custom-table class="highlight"></custom-table>
<custom-table class="highlight"></custom-table>

</template>


In an attempt to make a unified method for handling highlight functionality I also assigned the same class to the custom elements which arrange the rows in the table. I fully expected to have to bubble their properties up to the parent (the table) so that the highlight behavior could interact with them.

In the highlight behavior I wrote:

<script>
/** @polymerBehavior HighlightBehavior*/
HighlightBehavior = {

attached: function() {
console.log(this.getElementsByClassName('highlight'));
}
}
</script>


In my log, I expected to only have the four custom-table elements returned. This ended up not being the case, I also got the elements in the custom-table shadow DOM with a class of highlight. Now this is super convenient, but this doesn't make sense to me with what I understand about Polymer. I thought I had to directly query the shadow root in order to get elements contained therein. I would like to know why the castle walls seem to be breached in this case?

Answer

Default is shady DOM and shady DOM doesn't prevent you to access content of elements.

Either enable shadow DOM https://www.polymer-project.org/1.0/docs/devguide/settings

or use the Polymer DOM API https://www.polymer-project.org/1.0/docs/devguide/local-dom

Polymer.dom(this.root).getElementsByClassName('highlight');