Created
March 26, 2018 17:25
-
-
Save jonurry/f04be3c611e620844d2c66b2fa6f2870 to your computer and use it in GitHub Desktop.
15.3 Looping a triangle (Eloquent JavaScript Solutions)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <style> | |
| button { | |
| background-color: whitesmoke; | |
| } | |
| .selected { | |
| background-color: white; | |
| } | |
| </style> | |
| <tab-panel> | |
| <div data-tabname="one">Tab one</div> | |
| <div data-tabname="two">Tab two</div> | |
| <div data-tabname="three">Tab three</div> | |
| </tab-panel> | |
| <script> | |
| function clickTab(e) { | |
| let tabs = e.target.parentNode.parentNode.querySelectorAll('[data-tabname]'); | |
| for (let tab of tabs) { | |
| if (tab.getAttribute('data-tabname') == e.target.textContent) { | |
| tab.hidden = false; | |
| } else { | |
| tab.hidden = true; | |
| }; | |
| }; | |
| e.target.parentNode.childNodes.forEach((node) => { | |
| node.className = ''; | |
| }); | |
| e.target.className = 'selected'; | |
| }; | |
| function asTabs(node) { | |
| let buttons = document.createElement('div'); | |
| let first = true; | |
| for (let tab of node.children) { | |
| let button = document.createElement('button'); | |
| button.textContent = tab.getAttribute('data-tabname'); | |
| button.onclick = clickTab; | |
| if (first) { | |
| button.className = 'selected'; | |
| tab.hidden = false; | |
| first = false; | |
| } else { | |
| tab.hidden = true; | |
| } | |
| buttons.appendChild(button); | |
| } | |
| node.insertBefore(buttons, node.firstChild); | |
| } | |
| asTabs(document.querySelector("tab-panel")); | |
| </script> |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hints
One pitfall you might run into is that you can’t directly use the node’s
childNodesproperty as a collection of tab nodes. For one thing, when you add the buttons, they will also become child nodes and end up in this object because it is a live data structure. For another, the text nodes created for the whitespace between the nodes are also inchildNodes, but should not get their own tabs. You can usechildreninstead ofchildNodesto ignore text nodes.You could start by building up an array of tabs, so that you have easy access to them. To implement the styling of the buttons, you could store objects that contain both tab panel and its button.
I recommend writing a separate function for changing tabs. You can either store the previously selected tab, and only change the styles needed to hide that and show the new one, or you can just update the style of all tabs every time a new tab is selected.
You might want to call this function immediately, to make the interface start with the first tab visible.