Knockout JS: Stop divs binded to visible: from flashing on screen
Wth KnockoutJS, I work around this problem by defining a CSS class called hidden
with display:none
, then I'll add this class and binding to the flashing container:
class="hidden" data-bind="css: { hidden: false }"
I solved this by putting my "flashy" content in a script template and use ko's virtual elements to load the template when the variable is set by another virtual element.
For example:
<!-- ko if: myVariable --><!-- ko template: { name: 'myTemplate' } --><!-- /ko --><script type="text/html" id="myTemplate"> <ul data-bind="foreach: blah..."> <li></li> </ul></script><!-- /ko -->
So when myVariable is set, the content of the script container will be put in place of the template virtual element. With this method you dont see any flashing content :-)
I ended up writing a custom binding to use instead of the default visible
.
function isHidden(el) { var style; style = window.getComputedStyle(el); return (style.display === 'none')}ko.bindingHandlers['cssVisible'] = { 'update': function (element, valueAccessor) { var value, isCurrentlyVisible; value = ko.utils.unwrapObservable(valueAccessor()); isCurrentlyVisible = !isHidden(element); if (value && !isCurrentlyVisible) { ko.utils.toggleDomNodeCssClass(element, 'ko-visible', true); } else if ((!value) && isCurrentlyVisible) { ko.utils.toggleDomNodeCssClass(element, 'ko-visible', false); } }}
Then some CSS to handle visibility
[data-bind*="cssVisible"]:not(.ko-visible) { display: none;}
Usage is the same as the visible
binding
<div data-bind="cssVisible: true"></div>