While working with turn.js, I noticed that my pages (modeled in hype element groups) were coming out in the wrong order in the client DOM (check on Chrome and Safari). My page/groups were created some by hand and others by copy/paste and drag into order. After some frustration and hacking, it seems that Hype is emitting elements in a DOM order that does not match the order the elements are shown in the Hype tool. It appears OK visually in the client because of the z-index that does reflect the order of the elements in the tool view, but the DOM order of the element divs is unpredictable and thus hazardous to any other JS frameworks that are expecting a predictable DOM order.
I believe this is a bug in Hype since the DOM output is not predictable.
The Hype runtime DOM order is based on a top-left element location. This is to better help accessibility/assistive devices which use DOM ordering to read out the ordering of elements. We intentionally made this change in Hype v3.6.
I'd be curious as to your use case for depending on a DOM ordering?
As older versions of Hype did DOM elements by z-index; we left this behavior in the app through a hidden default which you can enable by typing this into the terminal:
Great - I'm glad that was able to solve your problem!
That is definitely a reasonable use case for having the option. While there's always hesitation at adding new and difficult to concisely explain options in Hype's UI, I've filed this in our tracker so we can see if other needs come in that might make us re-prioritize it.
Just came to say: I'd really appreciate this option being exposed in the editor. My use case is a series of videos that plays in sequence. Despite putting the first video "on top" of the others in the editor, I could not understand what logic guided their rendering sequence in the DOM, so inevitably they would play out of order.
I'm glad the defaults plist option exists for now, but it'll be a pain to remember to do this on my desktop, laptops, etc, to prevent screwing up the order again.
You could query your DIVs and then sort the resulting node list based on an additional attribute, in this example data-order, before doing whatever logic you are applying. I am assuming you're doing something with code.
function sortByOrder(nodes) {
return Array.from(nodes).sort(function(a, b) {
return a.dataset.order - b.dataset.order;
});
}
Lets assume your element have a class called node and the data-order attribute:
var sceneElm = document.getElementByid(hypeDocument.currentSceneId())
var nodes = sceneElm.querySelectorAll('.node');
var sorted = sortByOrder(nodes);
sorted.forEach(function(node) {
console.log(node); // do somthing with element
});
If you don't want to use a class and only have one list, you can also query for the data attribute.
var nodes = sceneElm.querySelectorAll('[data-order]');
If they are all siblings, what about using the z-index attribute? (you'd technically need to look at each one's parent, since they are all in HYPE_element_container elements)
Thanks for the recommendations. My development preference is always to take advantage of the IDE before writing workarounds. I'm fully aware of code-level solutions to the problem, but reducing my workload and the complexity of the project is always preferable.
As I said - I'm extremely happy that toggling a single boolean flip allowed me to do exactly what I needed in a sensible way in the editor.