Forum Discussion
Changing state directly from JavaScript?
I'm back finding that I'd really like to do this again. I'd love to have something like:
player.SetState("nameofobject", "state name");
- MathNotermans-99 months agoCommunity Member
As Articulate updates HTML and changes structure of it all also without warning to developers upfront old code especially when targeting existing HTML structure often fails. Then you have to figure out what change Articulate did and fix your code accordingly. So im checking now whether states are as before...or maybe something changed and they might be easier accessible.
When checking a simple SL with states in Firefox you will notice a state basically is an invisible DIV as before. When switching to it using a trigger...it is shown and the original state is hidden.
Basically nothing has changed on this thus.
It is possible to find all DIVs related to an element ( say it has statenames: 'Over', 'Down', 'Custom1', 'Custom2' ) and then target the element...hide all states and show the one you want to show with javascript.
Im gonna see if i can get that working...
First tests show that this is ( more or less ) the structure any image with states has.The main element:
.slide-object-stategroup.shown;A div with class of .group in it
Then the first basic image that is shown has this class
( all images in SL get converted to inline SVG )
div.slide-object-vectorshape.shown;
div.slide-object-vectorshape:nth-child(1);This is my custom state i added. A hidden DIV below it.
div.slide-object-vectorshape.hidden;
div.slide-object-vectorshape:nth-child(1);
Next step is trying to use this structure to get all divs in a specified state-group.
If i can get those ( and im quite sure i can ) then i can hide all, and show any of the states at will using javascript.- MathNotermans-99 months agoCommunity Member
Oh my, this really remembers me what i dislike in Storyline development. The HTML generated when adding images manually too Storyline differs to when in 'Edit State-mode' you either use 'Duplicate State' and then change the state by importing another image.. or when you use 'Add Pictures as States'.
For now i use ' Duplicate State' and change the image. That seems workable. The other approaches on creating new States give complete other HTML structure. But this really is a Articulate/Storyline thing. As they want to keep it backwards compatible with older versions ( at least as much as possible ) they tend to inherit weird behaviour from old versions too.
- MathNotermans-99 months agoCommunity Member
First steps working properly. Based upon duplicating states for new states. As mentioned in my earlier posts... Storyline makes different HTML when creating the states differently. I do think thats really bad coding...but...it is what it is...
The code below gets an specific element and gets all divs in in it with an data-model-id attribute, thus only the states.let baseElement = document.querySelector("[data-acc-text='myElement']");
let parent = baseElement.parentNode;
let allDIVS = parent.getElementsByTagName("div");
for (let i = 0; i < allDIVS.length; i++) {
let actualClassName = allDIVS[i].className;
let dataModelID = allDIVS[i].getAttribute('data-model-id');
console.log(i+" : "+actualClassName+" | "+dataModelID);
if(dataModelID != null ){
console.log(i+" dataModelID: "+dataModelID);
}
}
Now you can hide all of them...and show any of them.
Thats for a next one :-)
PS: the statename as is in Storyline is nowhere referenced in the HTML. - MathNotermans-99 months agoCommunity Member
Allthough i do have some hickups in showing the proper state...
this code hides all states of a given element.let baseElement = document.querySelector("[data-acc-text='myElement']");
let parent = baseElement.parentNode;
let allDIVS = parent.getElementsByTagName("div");
hideAllStates();
function hideAllStates(){
for (let i = 0; i < allDIVS.length; i++) {
let dataModelID = allDIVS[i].getAttribute('data-model-id');
if(dataModelID != null ){
allDIVS[i].classList.remove('shown');
allDIVS[i].classList.add('hidden');
}
}
}
Then you can target a state and show that.let baseElement = document.querySelector("[data-acc-text='myElement']");
let parent = baseElement.parentNode;
let allDIVS = parent.getElementsByTagName("div");
showState();
function showState(){
for (let i = 0; i < allDIVS.length; i++) {
let dataModelID = allDIVS[i].getAttribute('data-model-id');
if(dataModelID != null ){
allDIVS[3].classList.remove('hidden');
allDIVS[3].classList.add('shown');
}
}
}
As said this only works when duplicating states. If you make them any other way, Storyline makes up other HTML and this wont work. Also there still are some things to fix in the showing part... but basically it works.
- MathNotermans-98 months agoCommunity Member
Fully working setup/sample of this showing here...
https://www.linkedin.com/posts/mathnotermans_tls-tilburguniversity-states-activity-7192818872926773248-79Xm?utm_source=share&utm_medium=member_desktop