Scrolling images and buttons

Is it possible to have a scrolling image within a text box AND a button, drop down or radio button that scrolls with the image? I have some screen shots I'm using that do not fit into the size of the course that need to have clickable areas in order to open other screens and cannot resize the image based on the nature of the course (yes, I'm still working on the same software simulation). I'm asking before I experiment so I don't get caught up in trying to work it out if it either can't be done or is more complex than I have to learn within the time I have for development.


Discussion (29)

Does it have to be responsive or is this strictly a desktop module?

While I would like to develop using responsive design, at this time it is desktop based only.

Can you provide a sample image you are looking to have this functionality with? You might be able to do this with an image map. The scrolling part may present an issue. You might have to either use an SVG image map or there are a few jQuery plugins that recalculate a standard image maps coordinates upon screen redraw (there's one standard JS library too). If you can post an image I'll (and maybe a few others up for a challenge) try to get something working.

I've attached a sample with an explanation of what I'm hoping for - you two might recognize this page based on previous discussions we've had. Thanks to your help, this page is a near perfect simulation of how the software behaves. If I can get the button functionality working...

The other part of this is to know if it will work with radio buttons, text entry boxes, and drop downs. I've attached a couple of screen shots as an example as well.


Does it have to be a textbox? You can add images to textboxes but no button or other images.

Try this (uses jQuery):

It's the custom div that scrolls. There's some jQuery code in the HTML Extension on title level that adds all the elements in the group (all elements with the CSS class "intoDiv") to the custom div so they scroll along.

I've attached your sample with a similar approach, but no jquery required. I copied all relevant elements to a new page, so it's easier to see what happens... your pages tend to be a bit crowded ;-)

The image now has the Class "custommenu". The CSS in the HTML Extension makes it scroll (the div the image is in, not the image itself). The javascript attached to the button makes the button a child of the image div, i.e. it moves with it.


Tim - I'm a little lost on how that template is working. When I look at the JS on the buttons, it looks like that JS just changes the background on the text box onClick. I'm not sure what allows the button to scroll. I'm trying to get the button to scroll with a scrolling image that's visible. I've attached a new sample that shows the scrolling image and the button. They are both at the bottom of the title explorer so they're easier to find.

I'm starting to get how this is working, little by little. I see it working on the page you added, however...

I tried to copy and paste all the elements to my page (ie the Exiting SSIS in the sample), and I can't get it to behave the same way. One thing I noticed is that if I put the task panel search list into a scrolling text box, it breaks it (which makes sense to me in a certain way). Instead of copying and pasting the objects, might I have to create the object then copy/paste the text in order for it to work on other pages? Intuitively, I thought I could just copy/paste over to the other course and get the same functionality. When I copy the page (even without the top of page extension at the chapter level) it works fine, including the hide/show.

You only need the objects that are on page level of Page 2.

It should be possible to copy the elements to another page. The only restriction there is from the code I'm using is that you can have only one element with the class "custommenu". You could have more of course, but the javascript only refers to the first element with that class.

As images and textfields are very similar (from the html perpective) you can produce the same effect with a scrolling textfield as well.

When I copy to a brand new page (or one other page I was working on that didn't have any "duplicate" elements (like the scrolling text box), it works just fine. On the page that's having the issue, the button is visible in the same place it shows up in the Lectora window when I preview through Run or in the browser. I haven't had a chance to publish and test just yet.

I think I've stumbled on to something that may lead us to where the issue may be.

I can create a new page, copy and paste the text box and button and it works. I can also copy and paste to a page I've been working on that does not have the elements that are "duplicate" and it will work.

When I paste the elements so that they are at the topmost layer (bottom of the title explorer), it breaks. On a lark, I pasted them just underneath the first image on the page, and it started working. If I move them anywhere else in the title explorer, it breaks again. This is on the "Exiting SSIS" page in the sample I sent.

Not sure why it does that, but it's a step closer and may be workable even that far "below" all the other elements on that page.

Sorry, I haven't had the time until now to build an example using your image file. Is this what you are looking to do? This uses CSS only imagemapping and its also responsive. Instead of an image embedded into a text box it uses a web window. If there is interest in a tutorial let me know.

Thank you both for the options on this. I'm still running into an issue with copying the elements from the page to another page in my course and I'm not sure what might be happening there, especially with Tim's sample. Even if I create a new page and copy/paste the elements, it fails. I tried copying all the elements into the existing page and matching the order in the title explorer and copying the elements from the existing page over to the page with the working functionality to no avail. I'm stumped as to why it wouldn't copy over correctly.

Can you give a more detailed description about what's not working? - Esp. with the scrolling textfield it should be impossible that's it's not working, it doesn't even require custom CSS.

If you copy the elements to another page and publish or preview in browser, where's the button? Is it visible on the page in the position it has on the page in Lectora or is it not visible?

Trying copying button to your real page. Give your original scrolling textfield the CSS class "textfield". Change the trigger of the Run javascript action on the button from "On: Page show" to "On: Show". "On: Page show" actions are run first. Maybe there are too many elements on your page, so that the textfield isn't yet available when the action is run. For me it worked when the script is executed On: Show, it did not with On: page show. This would also explain why it works for you if you move the textfield up in the title explorer as the elements are created in the sequence they are listed in the title explorer.

Make sure the button is under the textfield in the title explorer, if not the button will be under the image after being attached to the textfield. Also make sure the Javascript refers to the CSS class you've added to the textfield.

The change to "onShow" worked; I was able to move the text field and button to where they need to be on the page. You guys are truly amazing and have been such a huge help with this project. I'm going to try and get approval at some point to get into a CSS and JavaScript class. Another option I know of is Codecademy, though I think it may be a tougher sell to get them to just let me use work time to self-teach versus enrollment in an actual course with reimbursement.

Any suggestions on books I could read that would help get me up to speed beyond what I'm learning from your knowledge?

I was wondering about that as well (some years ago, when I still was a beginner with jQuery), but someone whom I trust to be an expert said, this was the best way to include jQuery:

In this example the whole html extension (which comes from my shared sample) can be deleted as jQuery is not required to make my approach work.

Tim, export and take a look see at the html files. By using "Top of File Scripting" Lectora manages to actually place the code before the DOCTYPE. LOL.

Wanting to second what Jason mentioned. You guys have helped me greatly too. Tim, I used your scrollable div post on my previous project and worked a charm.

Jason, I completed the codecademy courses for HTML & CSS, JS and JQuery. It was a great way to start and I've actually started going back over them a second time to embed the knowledge more.

One thing I am struggling with is although I know the concepts now, adding jQuery interactions to a Lectora file has been a struggle (adding the link is the easy part - I get stuck on loading the actual interaction correctly.) But practice will make perfect with this. Stick with it because I sure as hell am trying to!

Hm, why don't you just try... ;-) With the current version of my code you can have only one target textfield but you can copy the action to several buttons and it should work.

One more quick question on the div solution - Can I use the same RunJS on multiple buttons? For example, in the text field, there's also an Intake Search area, etc. Can I create a button that need to be a child of the text field without having to create separate divs?

If I'm reading the way this works correctly, I can use the same code to add multiple buttons as "children" of the text field...

I'm getting to the experimentation part for sure :) Unfortunately, my trial on my home computer ran out and I'm on such a ridiculous timeline for the project I'm on, experimentation is at a minimum. The current expectation is to have 6 modules of a similar functionality and interactivity ready for release on June 1st. I'm on the second one and started in roughly November. You've seen what I've been doing so far, and I think 2 months on that first one is pretty reasonable when you factor in QA and content revisions.

I'll get there, I promise!


The position on the Lectora page is essential. The object keeps its position after being appended to the other element. If you place an element at x = 100 and y = 100 in Lectora, this is the position from the top and the left with regard to x=0, y=0 of the page. By appending the element to another object you change not the position of the object itself, you change x=0, y=0. The object will still be at x = 100, y = 100, but the new 0-point now is the top left corner of the element you've appended it to. If the object is supposed to be in the top left corner of the target element, place it at 0,0 on the Lectora page.


To adress an object in a script you always have to find a suitable selector to get it. If you don't know one, you can use an easy way you already know: Give the objects a CSS class. Then you can adress the elements in javascript with document.getElementsByClassName("your_class"). This will get you all the objects with the named class. To do something with them, you'll have to use a loop, to do whatever you want with each of the objects one after the other.

I attached your sample again. Your pages have become too complex for me... Check "Page 4". You'll find a radio button group, a drop down, and two buttons that all have the same class. Also check where the elements are placed on the page and where they end up in the textfield.


I'm maybe pushing the envelope in bringing this question back - I'm now trying to do the same thing with drop-down menus (in this example) and will later be doing it with radio buttons and text fields (i.e., this page would have three text fields that go along with it). I tried to find the value to use for appendChild, but after trying "form" and "combo" I had no luck. I saw method drop-down, but didn't think the value could have a space in it.

I'm also struggling with applying the JS to the two buttons (intake and workgroup) to mimic the other page - is it the position in lectora that makes the difference? I'm sadly stumped again.

I was able to get this to work with multiple buttons, but now I'm really pushing the envelope, I think.

I'm trying to do the same thing now with drop-down menus, text entry fields and radio buttons. I think where I'm coming up short is the value for the appendChild value. I tried "form" and "combo" and neither of those worked. This was based on seeing that the button has a type value of "button", but I don't see a type for the drop-down.

Tim, I can't thank you enough for your help and patience with a complete neophyte like myself :) I think what I was missing was attaching a class to each object and facepalmed when I realized it. I'm thinking (and will experiment) that I can do the same for a second textbox image on the page by attaching a different set of classes and appending the extension with the first one copy/pasted and just changing the "appendme" to the new classes for the text box and button, etc. elements. The only thing I wasn't sure of was the j and i variables. When I played with those, the page definitely did not like what I was messing with.

Thanks again - For what it's worth, I gave you and others on the forum credit for helping and inspiring the work I did on the customized audio player. Wouldn't have been possible without your and others' input.

Hi Jason,

we've all been beginners at the start and I'm truely impressed by the speed of your learning. Sharing the results of your development with the community is all I could ask for in return.

With regard to the script:

The first variable "tobeappended" contains a collection of all objects with the class "appendme", i.e. all objects we want to refer to in the loop. In this case I'm using a "while" loop, can't exactly tell why.

The second variable "image" contains a reference to the first element with the class "textfield". This is the target textfield. The naming of the variable may be a little counter-intuitiv, it comes because we used an image as the target element in the beginning. Now, the method "getElementsByClassName" cannot provide you with a direct reference to the object, because there could be multiple elements with the class "textfield". Although we do know there's only one, we still have to tell the script to always take the first. This is done by adding "[0]". Check the sample I've attached, in that I'm using another textfield with the class "textfield" as a second target for different elements.

Both variables i and j are needed to control the loop.

The variable "i" (= 0) is just a value to tell the script when to stop repeating the command between the { }.

The variable "j" contains the length of the collection "tobeappended" minus 1. In my example there are 9 objects with the class "appendme", 6 radio buttons, 1 drop down, 2 buttons. So in the beginning j equals "8". It defines how often the loop is to be repeated. The script collects all the objects and finds 9 elements. Javascript starts counting with "0", so the 9 objects have indexes from 0 - 8. That's why I subtract 1 from the length.

Then the loop starts.

The command says: Append the currently adressed object as a child of the element stored in the variable "image".

The first round of the loop is:

j = 8

Command says:


Make the element with the index equal to the value of "j" in the collection "tobeappended" a child of the object stored in "image". In this round j is equal to 8, so the nineth element is adressed. You'll recognize the same principal used to get the first element with the class "textfield" in "image".

Second line of the command is:


When the nineth element has been appended, subtract 1 from j.

The second round of the loop starts, now with j = 7, adressing the 8th element with the class "appendme".

The nineth round of the loop goes:

j = 0

the first element is appended and j is made equal to -1.

When starting the 10th round of the loop, the script finds that now j (=-1) is not greater or equal to i (=0) any more and stops looping, as the condition defined with "while(j>=i)" isn't met.

The way it's programmed with all the variables, allows you to give the class "appendme" to any number of objects and the script will still work and make them all children of the target textfield. The variables i and j are controled automatically by the script, there's no need to modify them manually.

In the new sample, I've copied the loop to append different objects to a different target. The new loop uses the variable "k" instead of "j", as there are more elements in the new collection. And of course because the first loop ends with "j" being -1, so the new loop wouldn't start at all.



Hey Tim, bringing this topic back for some assistance.

Have been using your intoDiv example. I've noticed that this example works perfectly in Chrome, but not so much in IE. Having a number of issues with Chrome running Lectora modules at work (ugh) and have to resort to IE while it is resolved.

When opening in IE, the vertical scroll bar appears, but it appears disabled and will not scroll or even allow me to click the up/down arrows. Again, works perfectly in Chrome.

I have the External HTML object set as Top of file Scripting:

Before even looking at your code you should know that "Top of File" scripting puts the code ABOVE the DOCTYPE declaration. This is absolutely wrong and while modern browsers do really well working with broken code, it's asking for trouble, especially with IE.

Try adding the jQuery library via header scripting and then after that add your own JS file using another header scripting. Also, for the time being, turn off seamless play while testing.

Also, why do you have style tags in the above?

Discussions have been disabled for this post