Alternative to Polymer's dom-if that progressively compares two properties rather than just binding to a single boolean property
if-diff allows the server to display content that should be initially displayed, then adjusts what is displayed as conditions in the browser change.
For example, suppose today is Monday. The server could generate the syntax below:
<!-- Polymer notation --> <if-diff if lhs="[[dayOfWeek]]" equals rhs="Monday" tag="manicMonday" m="1"></if-diff> ... <if-diff if lhs="[[dayOfWeek]]" equals rhs="Tuesday" tag="rubyTuesday"></if-diff> ... <div data-manic-monday="1"> <div>I wish it was Sunday</div> </div> <div data-ruby-tuesday="0"> <template> <div>Who could hang a name on you</div> </template> </div> ...
Generally, as will see, a data-* value of "1" should be interpreted as "matches", so assuming your css is consistent with that interpretation, the user will immediately see the desired text "I wish it was Sunday" before a single byte of JS is downloaded. Since the text for Tuesday is not yet applicable, embedding the content inside a template tag will allow the browser to ignore whatever is inside until needed. Only if the day changes would we need to display Tuesday. At that point, the template needs to be cloned (and discarded). So to fill in the details:
- The "tag" attribute refers to a data-* attribute / dataset.* property. The case is based on the property name.
- Only downstream sibling elements are checked for the data-* attribute. This is to encourage unidirectional data flow, and keeping related things physically close.
- Speaking of which, the optional m attribute indicates the maximum number of elements that are getting affected by the if-diff tag. Placing the if-diff element right above the elements it affects, and specifying "m" accurately, will improve performance and help reduce greenhouse emissions.
- if-diff sets the data-* attribute to "1" when the condition is true, "-1" if not. It is up to the application's css styling to interpret how this should display.
- If if-diff encounters a data-* value of "0", this signifies there's exactly one template inside the DOM element, which needs cloning before changing to "1". It will leave the template untouched if the condition is not satisfied.
- The "if" attribute / property is actually an active participant in the logical evaluation. If that attribute / property is false, then the evaluation will be false no matter what. And as the demo below indicates, not_equals is also supported.
<!-- Polyfills Needed for retro browsers --> <script src="https://cdn.jsdelivr.net/npm/@webcomponents/webcomponentsjs/webcomponents-loader.js"></script> <!-- End Polyfills --> <script type="module" src="https://email@example.com/if-diff.iife.js"></script> <script type="module" src="https://firstname.lastname@example.org/dist/p-d.iife.js"></script> </div>
Commonality with p-d.p-u (a kind of dom-bind alternative)
Not only does if-diff share the same fetish for unidirectional data flow as p-d.p-u, they share a number of common modules. As a result, while if-diff weighs around 1.6kb and p-d weighs around 1.9kb, combine them together, and due to the magic of code reuse, the combined size is ~2.5kb minified and gzipped.
Go to sleep mode
It is quite common to have a user interface with multiple tabs, each tab depending on some common filters / inputs. if-diff can be used in this scenario, and to help improve performance, it can toggle the disabled attribute on the target elements. If the elements themselves know how to "go to sleep" when disabled, and then sync up with the new filters / inputs when disabled is removed, that could provide the most optimal performance.
Install the Polymer-CLI
First, make sure you have the Polymer CLI installed. Then run
polymer serve to serve your element locally.
$ npm install if-diff
Viewing Your Element
$ polymer serve Open http://127.0.0.1:8081/
- @bower_components/iron-flex-layout#polymerelements/iron-flex-layout#1 - 2
- @bower_components/iron-location#PolymerElements/iron-location#1 - 2
- @bower_components/marked-element#polymerelements/marked-element#1 - 2
- @bower_components/prism-element#PolymerElements/prism-element#1 - 2