Apologies in advance is this is a duplicate. I'm new here and new to javascript. I'll begin by describing what I am aiming to do, then show the code.
Basically. I have a HTML page with a simple navigation bar (the usual ul li arrangement). When one of the options is clicked, it will show the relevant 'page' (which are tags) by removing the .hide class on the target article, and adding the .hide class to the page that was visible. Previously I simply just used the 'getElementByID' to grab each element by id, showing whats' meant to show and hiding whats meant to be hidden.
As you can imagine, it ends up in repeating that many times in a function. I'm looking for a more efficient way to do this. The way I thought I'd try would be to grab all the navigation elements and place them in an array, then grab all the 'page' elements and put them in an array. When the option in the navigation is clicked, it returns the index position in the array, which can be compared the the index position of the pages in the other array. If they match, remove the .hide class to make the 'page' visible. Anything else that doesnt match, add the .hide class to the remaining 'page' elements
Here is my attempt so far:
HTML:
<!doctype html> <html> <head> <title>Practice to improve javascripting</title> <link rel="stylesheet" type="text/css" href="css/style.css" /> <script type="text/javascript" src="js/practice.js"></script> </head>
<body onload="indexNum()"> <div id="pageContainer"> <ul> <li>Test</li> <li>Test</li> <li>Test</li> </ul>
<article id="one"> <h4>Page one</h4> <p>Page one is now displayed</p> </article>
<article id="two" class="hide"> <h4>Page two</h4> <p></p> </article>
<article id="three" class="hide"> <h4>Page three</h4> <p></p> </article>
</div><!-- end of pageContainer div-->
</body> </html>
CSS:
/*CSS Document */
body { background-color:whiteSmoke;
font-family: Verdana, Geneva,sans-serif; font-size: 12pt; margin:0; padding:0;
}
#pageContainer {margin: 20px auto 40px auto;
padding:0; width: 600px; height:auto;
background-color:snow;
border: 1px solid gainsboro; border-radius: 3px; /*end of set-up code*/
}
/*navbar styles*/
ul {
background-color:white;
border: 1px solid violet;
border-radius: 3px;
width: 550px; height: 20px;
margin: 15px auto 15px auto;
list-style-type:none;
padding: 0;
}
li {
float:left;
width:33%; height:20px;
text-align:center;
}
.select li {
background-color:violet;
color: snow; font-weight:bold;
}
a {color: black;}
/*page styles*/
article {
width: 600px; height: 400px;
border-top: 1px solid gainsboro;
margin:0; padding:0;
}
h4, p {margin: 10px 20px 10px 20px}
.hide {display:none;}
and here is my mess of javascript lol:
//create global variables
var nav = document.getElementsByTagName
('a');
var page = document.getElementsByTagName
('article');
/*create a function that will be called on
page load to find the index position of the
navigation buttons:*/
function indexNum(){
nav; //calling the nav global variable
//search array for index positions
for(var index = 0; index < nav.length; index++) {
//store index number in variable?
nav[index].indexNumber = index;
//now search array of page index position
for(var indexPages = 0; indexPages < page.length; indexPages++){
//store index number in variable?
nav[indexPages].indexedNumber = indexPages;
//function to return index of element clicked
nav[index].onclick = function() {
if (this.indexNumber == page[indexPages]) {
page.className = "";
} else if (this.indexNumber !== page[indexPages]) {
page.className = "hide";
}
}
}
}
I'm probably going about this the wrong way, but I want to be able to add as many options on the navigation bar, with the corresponding pages. Even add as many navigation bars (for sub navigation on a page) with as many sub pages. So this is the reason for my madness lol.
Many thanks in advance
Ok, here it goes. I commented every step of the way in the JavaScript so you can learn exactly what's going on here.
This is completely dynamic. You can add and remove articles as needed, and your navigation menu will update automatically and without any limitations.
var doStuff = function () {
// Get all of the articles
var articles = document.getElementsByTagName("article");
// Define an empty array to hold the id's of the articles
var navIds = [];
// Loop through the articles
for (var i = 0; i < articles.length; i++) {
// Get the classes for the current article
var classes = articles[i].classList;
var hidden = false;
// Loop through the class list for the current article
for (var a = 0; a < classes.length; a++) {
// If the current class equals "hide"
if (classes[a] === "hide") {
// Set the variable "hidden" to true
hidden = true;
// Get out of the loop
break;
}
}
// If the article is hidden, add the ID to the navIds array so we can add it to the navigation
if (hidden) {
navIds.push(articles[i].id);
}
}
// If there are hidden articles
if (navIds.length > 0) {
// Clear the navigation
document.getElementById("nav").innerHTML = "";
}
// Loop through the navIds
for (var i = 0; i < navIds.length; i++) {
// Get the nav element (ul)
var navElem = document.getElementById("nav");
// Create a new li element
var liElem = document.createElement("li");
// Add the li element to the nav (ul) element
navElem.appendChild(liElem);
// Create a new a element
var aElem = document.createElement("a");
// Set the href on the new a element
aElem.href = "#"
// Set the "data-article" attribute to the id of the article to show when clicked
aElem.setAttribute("data-article", navIds[i]);
// Here, we're going to set the navigation title to the contents of the h4 element in the article
// Get the current article
var article = document.getElementById(navIds[i]);
// Get the children of the current article
var children = article.childNodes;
// Define an empty variable to hold the h4 element when we find it
var h4Elem;
// Loop through the children of the current article
for (var a = 0; a < children.length; a++) {
// If the current child is an h4 element
if (typeof children[a].tagName !== "undefined" && children[a].tagName.toLowerCase() === "h4") {
// Set the h4Elem variable to the current child element
h4Elem = children[a];
// Get out of the loop
break;
}
}
// Since we defined h4Elem as an empty variable, we need to make sure it's a valid HTMLElement object
if (h4Elem instanceof HTMLElement) {
// Set the Inner HTML of the new a element to the Inner HTML of the article's h4 element
aElem.innerHTML = h4Elem.innerHTML;
}
// Add the new a element to the new li element in the navigation
liElem.appendChild(aElem);
// Add a click event handler on the new a element in the navigation
aElem.addEventListener("click", function () {
// Get all of the articles
var articles = document.getElementsByTagName("article");
// Loop through the articles
for (var i = 0; i < articles.length; i++) {
// Get the classes for the current article
var classes = articles[i].classList;
// Define a hidden variable and set it to false
var hidden = false;
// Loop through the classes of the current article
for (var a = 0; a < classes.length; a++) {
// If the class is "hide"
if (classes[a] === "hide") {
// Set the hidden variable to true
hidden = true;
// Get out of the loop
break;
}
}
// If the article is not hidden
if (!hidden) {
// hide it
articles[i].classList.add("hide");
}
}
// Get the id of the article to show
var elemIdToShow = this.getAttribute("data-article");
// Get the element to show
var elemToShow = document.getElementById(elemIdToShow);
// Remove the hidden class from it
elemToShow.classList.remove("hide");
// Re-run the doStuff() function to regenerate the navigation and event handlers
doStuff();
});
}
}
// Run the doStuff() function
doStuff();
/* Your original CSS, I didn't change anything */
body {background-color: whiteSmoke;font-family: Verdana, Geneva,sans-serif;font-size: 12pt;margin: 0;padding: 0;}
#pageContainer {margin: 20px auto 40px auto;padding: 0;width: 600px;height: auto;background-color: snow;border: 1px solid gainsboro;border-radius: 3px;}
ul { background-color: white;border: 1px solid violet;border-radius: 3px;width: 550px; height: 20px;margin: 15px auto 15px auto;list-style-type: none;padding: 0;}
li {float: left;width: 33%;height: 20px;text-align: center;}
.select li {background-color: violet;color: snow;font-weight: bold;}
a {color: black;}
article {width: 600px;height: 400px;border-top: 1px solid gainsboro;margin: 0;padding: 0;}
h4, p {margin: 10px 20px 10px 20px;}
.hide {display: none;}
<div id="pageContainer">
<ul id="nav"><!-- Empty ul for dynamic navigation --></ul>
<!-- Each article is a separate "page" -->
<article id="one">
<h4>Page one</h4>
<p>Page one is now displayed</p>
</article>
<article id="two" class="hide">
<h4>Page two</h4>
<p>Page two is now displayed</p>
</article>
<article id="three" class="hide">
<h4>Page three</h4>
<p>Page three is now displayed</p>
</article>
</div>
Related
So I'm generating a paragraph.
I want to add <ul> under the 3rd paragraph.
Here is the code snippet:
var i = 0;
for (i = 0; i < 5; i++) {
const para = document.createElement("p");
const node = document.createTextNode("This is new.");
para.appendChild(node);
const element = document.getElementById("div1");
element.appendChild(para);
// add ul under the 3rd paragraph
}
.nav {
background-color: grey;
text-align: center;
width: 90px;
height: 90px;
margin: 0;
padding: 0;
transition: background .5s;
/* .5s how long transition should take */
}
<ul class="nav">
<p>Test</p>
</ul>
Do you want to inject the ul under your 3rd paragraph in the element with id1?
You can have something like:
// On your "add ul under the 3rd paragraph line
if (i == 2){ //Condition for 3rd paragraph (-1 as the loop starts on 0)
const menu = document.getElementsByClassName("nav")[0]; //get the ul you want to add. getElementsByClassName returns a list, so would need to get the item you want to add. You might want to use an id in case you have multiple elements with class nav.
//Finally, add the element on your div1
document.getElementById("div1").appendChild(menu);
}
I have a series of divs with the class name x that are inside of other divs with the class name item. The item divs are inside a section of the main.
What I want to do is create a function that applies equally to every x class div by affecting their respective parent (in this case changing their CSS).
I coded this:
var openbtn = document.getElementsByClassName("x")[0];
openbtn.onclick = function() {
document.body.parentElement.style.backgroundColor = "red";
}
However, this only works on the first x class <div>. When it works, it changes the background color of the section, or main or body element, and not the x class div parent (the item class div).
If you want to handle this with a handler on each .x element, you have to add a handler to each .x element. (But you may not want to do that, keep reading.) That would look like this:
var openbtns = document.getElementsByClassName("x");
for (var n = 0; n < openbtns.length; ++n) {
openbtns[n].addEventListener("click", xClickHandler);
}
...where xClickHandler uses this (or event.currentTarget) to know which .x element was clicked:
function xClickHandler() {
this.parentElement.style.backgroundColor = "red"; // I suggest using a class instead of doing this, btw
}
But, if all of these .x elements are within the same overall container, you can do it with event delegation, like this:
document.querySelector("selector-for-the-overall-container").addEventListener("click", function(event) {
// Find the `.x` that was clicked (which may be `event.target` or may be
// an ancestor node of it
var x = event.target.closest(".x");
if (x && this.contains(x)) {
x.parentElement.style.backgroundColor = "red"; // Again, suggest using a class
}
});
More:
closest
contains
Live Example using the HTML from your comment:
document.getElementById("items").addEventListener("click", function(event) {
// Find the `.x` that was clicked (which may be `event.target` or may be
// an ancestor node of it
var x = event.target.closest(".x");
if (x && this.contains(x)) {
x.parentElement.style.backgroundColor = "red"; // Again, suggest using a class
}
});
.x {
display: inline-block;
width: 10px;
height: 10px;
background-color: blue;
}
section {
background-color: yellow;
padding: 8px;
}
<main id="items">
<section id="design">
<div class="item">
<div class="x"></div>
<h1>Design stuff</h1>
</div>
</section>
<section id="art">
<div class="item">
<h1>Art stuff</h1>
<div class="x"></div>
</div>
</section>
</main>
Add the event listener to each element using a for of loop:
var openbtnList = document.getElementsByClassName("x");
for (let x of openbtnList) {
x.addEventListener("click", clickX, false);
};
function clickX() {
this.parentElement.classList.toggle("red"); // sstyle.backgroundColor = "red";
}
main {
display: flex;
}
.item {
width: 80px;
height: 100px;
padding: 30px;
}
.item::before {
content: " ";
background: url(http://placekitten.com/80/100) center/cover;
width: 80px;
height: 100px;
position: absolute;
}
.x::before {
content: "X";
color: white;
font: 30px/30px sans-serif;
padding: 10px;
position: absolute;
}
.red {
background: rgba(255, 0, 0, 0.5);
}
<main>
<div class="item">
<div class="x"></div>
</div>
<div class="item">
<div class="x"></div>
</div>
<div class="item">
<div class="x"></div>
</div>
</main>
I have this multidimensional array below i'm trying to display the first and last name in the H3 tags, the age in the H4 tags and the person-desc in the P tags and everything inside the tab. I'm not sure the way i am currently displaying the first and last name is the best way to do it. Is there any better / simple way to accomplish this? Any help would be greatly appreciated!
function openCity(evt, cityName) {
var i, tabcontent, tablinks;
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
document.getElementById(cityName).style.display = "block";
evt.currentTarget.className += " active";
}
// Get the element with id="defaultOpen" and click on it
document.getElementById("defaultOpen").click();
var personArr = [];
var person = {["first-Name"]:"John", ["last-Name"]:"Doe", ["age"]:21, ["person-desc"]:"Nice guy currently still studying"};
var person2 = {["first-Name"]:"Paul", ["last-Name"]:"Logan", ["age"]:22, ["person-desc"]:"Hot tempered person in the military"};
var person3 = {["first-Name"]:"Sean", ["last-Name"]:"Kim", ["age"]:32, ["person-desc"]:"Smart guy working as a Doctor"};
var person4 = {["first-Name"]:"Ken", ["last-Name"]:"Chow", ["age"]:12, ["person-desc"]:"Loves travelling works overseas"};
personArr.push(person, person2, person3, person4);
console.log(personArr);
var parent = document.getElementsByClassName('line1')[0].children;
console.log(parent);
var personFlag = 0;
for(var i = 0; i < parent.length; i=i+1){
parent[i].innerHTML += personArr[personFlag]['first-Name'] +' '+ personArr[personFlag]['last-Name'];
personFlag++
}
body {font-family: Arial;}
/* Style the tab */
.tab {
overflow: hidden;
border: 1px solid #ccc;
background-color: #f1f1f1;
}
/* Style the buttons inside the tab */
.tab button {
background-color: inherit;
float: left;
border: none;
outline: none;
cursor: pointer;
padding: 14px 16px;
transition: 0.3s;
font-size: 17px;
}
/* Change background color of buttons on hover */
.tab button:hover {
background-color: #ddd;
}
/* Create an active/current tablink class */
.tab button.active {
background-color: #ccc;
}
/* Style the tab content */
.tabcontent {
display: none;
padding: 6px 12px;
border: 1px solid #ccc;
border-top: none;
}
.line1{
display:inline-block;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<div class="tab">
<button class="tablinks" onclick="openCity(event, 'People')" id="defaultOpen">People</button>
</div>
<div id="People" class="tabcontent">
<div class="line1">
<h3>Name 1 :</h3>
<h3>Name 2 :</h3>
<h3>Name 3 :</h3>
<h3>Name 4 :</h3>
</div>
</div>
</body>
</html>
Generally, and personally speaking, using innerHTML to modify the DOM in the way you're doing is somewhat frowned on. Instead, you'd create a virtual div, or DocumentFragment, and each of the "person" divs to that. Once that's done you can append the parent fragment to the DOM. This prevents additional rerendering and is generally more readable.
With your code, I would replace this part:
var parent = document.getElementsByClassName('line1')[0].children;
console.log(parent);
var personFlag = 0;
for(var i = 0; i < parent.length; i=i+1){
parent[i].innerHTML += personArr[personFlag]['first-Name'] +' '+ personArr[personFlag]['last-Name'];
personFlag++
}
With This:
var parent = document.getElementsByClassName('line1')[0];
var frag = document.createDocumentFragment();
// Iterate through the Person Array
personArr.forEach((person,i) => {
// `person` is the ith member of personArr
var name = document.createElement('h3');
// Update the contents of your h3 element and add it to the fragment.
name.textContent = `Name ${i}: ${person['first-Name']} ${person['last-Name']}`;
frag.appendChild(name);
});
// Add the fragment to the parent :)
parent.appendChild(frag);
A non-es6 version would look like this.
var parent = document.getElementsByClassName('line1')[0];
var frag = document.createDocumentFragment();
// Iterate through the Person Array
for(var i = 0; i < personArr.length; i++) {
var person = personArr[i];
// Create our h3 element, to house the person's name.
var name = document.createElement('h3');
// Update the contents of your h3 element and add it to the fragment.
name.textContent = [
'Name',
i,
':',
person['first-Name'],
person['last-Name']
].join(' ');
frag.appendChild(name);
}
// Add the fragment to the parent :)
parent.appendChild(frag);
Additionally, you would also have to remove all the children from the HTML in order for this to work properly. i.e. make the line1 element look like this:
<div class="line1"> </div>
I'm looking to learn how to do this left menu :
http://js.devexpress.com/New/15_2/#HTML_5_JS_Core
When you scroll down the page, the "active" menu item change.
p.s.
Is there a name for this type of menu?
regards,
yaniv
Scroll Navigation
That is how we call these type of navigation bars. Basically you have to listen to the scroll event and calculate which element is in the viewport at the moment than you add a class to your navigation that marks the current menu element.
There is a nice demo built in jQuery but because jQuery is a thing of the past, I built one in Vanilla JS. See comments for explanations.
There are different ways to define which is the current element. In my Example it is the last one whose top line just passed the top line of the browser.
Working demo
window.onscroll = onScroll;
function onScroll() {
var removeActiveClass = function (elements) {
for (var i = 0; i < elements.length; ++i) {
elements[i].classList.remove('active');
}
}
var anchors = document.querySelectorAll('#menu-center a');
var previousRefElement = null;
for (var i = 0; i < anchors.length; ++i) {
// Get the current element by the id from the anchor's href.
var currentRefElement = document.getElementById(anchors[i].getAttribute('href').substring(1));
var currentRefElementTop = currentRefElement.getBoundingClientRect().top;
// Searching for the element whose top haven't left the top of the browser.
if (currentRefElementTop <= 0) {
//The browser's top line haven't reached the current element, so the previous element is the one we currently look at.
previousRefElement = anchors[i];
// Edge case for last element.
if (i == anchors.length - 1) {
removeActiveClass(anchors);
anchors[i].classList.add("active");
}
} else {
removeActiveClass(anchors);
previousRefElement.classList.add("active");
break;
}
}
}
body, html {
margin: 0;
padding: 0;
height: 100%;
width: 100%;
}
.menu {
width: 100%;
height: 75px;
position: fixed;
background-color:rgba(4, 180, 49, 0.6);
}
#menu-center {
width: 980px;
height: 75px;
margin: 0 auto;
}
#menu-center ul {
margin: 15px 0 0 0;
}
#menu-center ul li {
list-style: none;
margin: 0 30px 0 0;
display: inline;
}
.active {
font-size: 14px;
color: #fff;
text-decoration: none;
line-height: 50px;
}
a {
font-size: 14px;
color: black;
text-decoration: none;
line-height: 50px;
}
.content {
height: 100%;
width: 100%;
}
#portfolio {background-color: grey;}
#about {background-color: blue;}
#contact {background-color: red;}
<div class="menu">
<div id="menu-center">
<ul>
<li><a class="active" href="#home">Home</a></li>
<li>Portfolio</li>
<li>About</li>
<li>Contact</li>
</ul>
</div>
</div>
<div id="home" class="content"></div>
<div id="portfolio" class="content"></div>
<div id="about" class="content"></div>
<div id="contact" class="content"></div>
This is not exactly menu type, it is the way how you can position objects by html.
You can use position:Abosule property to achieve this effect:
http://www.w3schools.com/css/tryit.asp?filename=trycss_position_fixed
By this given divs are "flying" above the res of the page. In your case it could be a menu.
EDIT:
To sync this you need to detect when given anchor is currently seen.
It can be done by jQuery, this is sample draft of code, should explain clue of solution:
// list of header on page
var positions = [
$("#anchor1").offset().top,
$("#anchor2").offset().top,
$("#anchor3").offset().top,
];
var menu_objects= [
"#menu1",
"#menu2",
"#menu3"
];
var $w = $(window).scroll(function(){
// clear old
for(var v in menu_objects)
$(v).css({"color","white"});
for(var i=positions.length-1;i>=0;i--)
{
if(positions[i]>=$w.scrollTop())
{
$(menu_objects[i]).css({"color","red"});
break;
}
}
});
I am trying to create a hovering menu, but it doesn't work. I create a menu and set it with a high z-index value. I then generate a table using javascript, but then I scroll down the table goes in front of my menu buttons.
Edit:
I am just trying to get this to work for FF8.
Edit 2:
This code will actually work. In order to make my buttons appear on top I just set my table z-index to -1;
#blackHead
{
width:100%;
background-color:White;
}
#table
{
position:relative;
width: 40%;
left: 30%;
z-index: -1;
}
#header
{
position: fixed;
top:3%;
left:30%;
width:40%;
z-index: 100;
}
.inv
{
visibility:hidden;
width:30px;
}
.headerButton
{
text-decoration:none;
position:relative;
font-family:Arial;
font-weight:bold;
color:White;
border: solid 1px black;
background-color: Black;
border-radius: 5px;
padding: 5px;
z-index: 101;
}
.headerButton:hover
{
background-color: White;
color: Black;
}
#myTable {
position: absolute;
top:10%;
}
#button1
{
position: absolute;
top:0%;
left:0%;
}
#button2
{
position: absolute;
top:0%;
right:0%;
}
#button3
{
position: absolute;
top:0%;
left:50%;
}
#button4
{
position: absolute;
top:10%;
left:50%;
}
#button5
{
position: absolute;
top:10%;
right:0%;
}
</style>
<html>
<head>
<title>Table</title>
</head>
<body>
<div id="header" class="headerBar">
Create Table
<span class="inv">" "</span>
Update Table
<span class="inv">" "</span>
Quit
<span class="inv">" "</span>
Send Json
<span class="inv">" "</span>
Start Timer
<span class="inv">" "</span>
Stop Timer
</div>
</body>
</html>
<script type="text/javascript">
function create_table() {
// get the reference for the body
var body = document.getElementsByTagName("body")[0];
// creates a <table> element and a <tbody> element
var tbl = document.createElement("table");
tbl.id = "table";
var tblBody = document.createElement("tbody");
tbl.style.zIndex = -1;
// creating all cells
var xmlDoc = getXML();
var x = xmlDoc.getElementsByTagName("Registers");
for (var i = 0; i < x.length; i++) {
// creates a table row
var row = document.createElement("tr");
// Create a <td> element and a text node, make the text
// node the contents of the <td>, and put the <td> at
// the end of the table row
var name = document.createElement("td");
name.style.width = "80%";
var nameText = document.createTextNode(x[i].getElementsByTagName("name")[0].childNodes[0].nodeValue);
name.appendChild(nameText);
row.appendChild(name);
var number = document.createElement("td");
number.style.width = "10%";
var numberText = document.createTextNode(x[i].getElementsByTagName("number")[0].childNodes[0].nodeValue);
number.appendChild(numberText);
row.appendChild(number);
var value = document.createElement("td");
value.style.width = "10%";
var valueText = document.createTextNode(x[i].getElementsByTagName("value")[0].childNodes[0].nodeValue);
value.appendChild(valueText);
row.appendChild(value);
row.addEventListener("dblclick", modify_value, false);
// add the row to the end of the table body
tblBody.appendChild(row);
}
// put the <tbody> in the <table>
tbl.appendChild(tblBody);
// appends <table> into <body>
body.appendChild(tbl);
// sets the border attribute of tbl to 2;
tbl.setAttribute("border", "2");
tbl.style.position = "absolute";
tbl.style.top = "30%";
}
</script>
myTable has position: absolute; - that will always go over something with position: static;
z-index will work, but both elements (the table and the menu have to both have z-index and position: absolute;
Without seeing the HTML it's pretty hard to detect the problem.
Example
Here's a fiddle describing the problem: http://jsfiddle.net/rZysU/
.a1's z-index is set to 1000 but it still is not visible. b1 is visible although its z-index is only 1. (it even is the same with -1)
In General
If you nest HTML elements then each nesting level creates its own z-index stack. If you set the z-index of an element inside a deeper node in the DOM tree then it might happen that although you've set the z-index to a high value it still will be underneath other elements that reside in a higher hierarchy level of the DOM.
Example:
div1
div1a
a (z-index= 100)
b (z-index= 101)
c (z-index= 102)
div1b
d (z-index= -1)
e (z-index= 1)
d will still be drawn on top of a as div1b is given a higher z-index because it is listed after div1a and HTML renderers draw one node after another and define z-indicies by that way if you don't provide it by your CSS definition.