code icon

CSCI 1720

Intermediate Web

Homework 7 - More CSS & JavaScript

One little thing I'd like to add is for the play/pause buttons to remain highlighted when each is active

js icon

  1. Create a new folder named hw7_js-3 on your external drive
  1. Copy your files and folders from the hw6_js-2 folder to the hw7_js-3 folder. This, again, will be our starting point

    Couple of things to address, here

  • Make sure all references to '(H/h)omework 6' are updated to read '(H/h)omework 7'
  • If the 'controls' attribute is still present in your <audio> element, remove it
  • All of the meta-information in your <head> element should be updated to reflect this new assignment
  • Add at least four <meta name='' content=''> elements, one each for author, date, keywords, and description. You may think of additional meta-elements that would be appropriate here (like, maybe, 'last revised')

css icon CSS

  1. So we need to add a CSS class that will tell the browser how the button should be displayed when it is active. We'll call this class, appropriately enough, .active
  1. Open main.scss in Brackets. Oops! I almost forgot - Launch the Command Line Interface (cmd.exe) and run Sass in your working_directory/homework/hw7_js-3 directory. I'm assuming that by now you have enough practice with Sass that you can handle this without detailed instructions
  1. Add the following and save your file
output page
Fig 2- .active class

Interesting thing to note here: the color is defined using hexidecimal notation with alpha channel information. The last pair defines how transparent the color will be

  1. That will do it for our CSS, for now

jq icon JavaScript

We're going to change the onclick attributes' properties to function calls; then define the functions

  1. Modify the buttons' onclick properties as shown below (adding class='audioControl' to each as well)
output page
Fig 3- Changing the controls

As you can see, we've changed the method call to a function call for a custom function in each control. You may be wondering why we didn't add an audioControl class to our CSS -- we shall see

  1. Now that we have the function call is in place, best to define their respective functions, I guess. Scroll down to the bottom of index.html, where your JavaScript is
  1. Typically, when developing these things, I'll get one bit working; then apply it to the rest. So let's add (after hide())
play function
Fig 4- Setting up the first function

Think for a minute about what we want the page to do. When the user clicks the 'play' button, we want the audio control to start playing the .mp3 and for the button to remain highlighted, providing visual feedback. But what about when the user presses the 'pause' button? Well, we want it highlighted, but what else? That's right - the 'play' button has to be 'un-highlighted'. So we know we're going to need a function to do that

  1. Add the following
output page
Fig 5- Function to clear highlighting
  1. Ok, back to the play() function. Here's a trick with the developer tools that will help you with selecting an element if it doesn't have an ID (ordinarily, you'd just assign an ID to it and use that, but work with me here). With the page displayed in your browser and the developer tools open, use the element selector tool to select the element you want to identify (in this case, the 'play' button)
  1. This will highlight the element in the developer tool. Right-click on the highlighted part, hover over 'Copy', and select 'Copy JS path'
output page
Fig 6- Select an element for identification

This will copy the JavaScript query to the clipboard for you

  1. In your index.html, add a variable assignment and paste in the JavaScript from the clipboard
output page
Fig 7- Pasting JS selector into code

This may look confusing, but it makes sense, if you remember your contextual selectors. It starts with the body element, then progresses down through the DOM until it reaches the desired element. This trick can be real useful when you're developing and don't want to have to refactor all of your code

You can also see how assigning that monstrosity to a shorter variable ('el' is an arbitrary name - short for 'element') will make it easier to refer to it in your code

  1. Now we'll put in a call to 'un-toggle' the active element, whatever it may be (we haven't written it yet, but we know what we want it to do)
output page
Fig 8- Clear active
  1. Now, here's our "meat 'n taters"
output page
Fig 9- Active class and play

Notice here that each time we click the play button, we're resetting the volume to 0.3. There are other ways we could handle this if we wanted the user to be able to pause and resume without resetting the volume, but that's good enough for now

  1. Using the same steps, now, you can complete the pause() function:
output page
Fig 10- pause() function
  1. Volume up and volume down don't need to be highlighted, so the functions for them are pretty straightforward
output page
Fig 11- Volume up/down
  1. Now all that's left to do is create the clearActive() function. This requires a different JS query - querying the class
output page
Fig 12- Query by class

The important distinction here is that imgs is an collection of values, not a single value. The collection is called an HTMLCollection, which is similar to an array, but not quite the same. So we'll want to convert it to an array in order to be able to use the forEach() loop control. Then imgs[0] corresponds to the 'play' button, imgs[1] to the 'pause' button, and so on - but with forEach(), as you'll see, we don't have to worry about the array indeces this time

  1. The function will iterate through all of the objects in the array and remove the active class from each (if it's not there in the first place, nothing happens). We'll use a forEach loop to iterate through the four (see what I did there?) objects - in this case - and remove the class from each
output page
Fig 13- Clearing the active class

Granted, there are only two of the objects ('play' and 'pause') that will ever have the active class added to them, so we could have just explicitly removed the class from each with two lines of code.


But what if we were to add more controls, say 'reverse' and 'fast forward' sometime in the future? Matter of preference, I guess

output page
Fig 14- Order of execution when
user clicks play or pause

So now it's time to test our code

  1. Save your work and refresh the page in your browser. Click the 'play' button. Check that the 'play' button remains highlighted; then click the pause button. The playback should pause and the button should now be highlighted. Click 'play' again and check the volume controls to make sure they work

If there are any errors or anything that doesn't work like it should, it's time to check the console for error messages. Troubleshooting is an essential part of programming (remember - Right-click→Inspect or F12). The error messages will at the very least, give you a line number to start looking

  1. If you have errors you can't resolve, upload your work to the server and send me an email so I can help troubleshoot

Finally (no, seriously)

  1. Remember a while back when I said that drop-caps are nice but easily can be overdone? Looking are our work, I think we kind of did that. So let's go back to our main.scss file and look at the code for the drop-caps
pseudo element
Fig 15- Pseudo element

What we'd like to do is modify the code so that the browser only modifies the first letter of the first paragraph. Ultimately, we'll end up with this

pseudo element
Fig 16- Pseudo element

To understand how we're going to do this, we need to revisit the notion of the parent-child relationship that exists between HTML elements

pseudo element
Fig 17- Parent-child relationship

So we can see that the first paragraph in this construct is the fourth child element of the container-inner element. There is a CSS pseudo class, :nth-child() that allows us to select a specific child or children of a parent element. We can combine these two bits of information to solve our conundrum

  1. Modify the pseudo element like this
pseudo element
Fig 18- Chaining selectors
  1. Update the page's header from 'Homework 6' to 'Homework 7,' if you haven't already. Save your work and refresh the page in the browser. Use the 'developer tools' trick to modify the first letter so it spans three lines of text as shown in Fig. 16 and copy/save the properties/values back in to your code like we did in Homework 6, Steps 13-14

Finally, if all went well, we should have this

screen shot
Fig 19- HW5 Final (final!) result
  1. Once everything is working, log in to the class server with FileZilla
  1. Navigate to your homework folder
  1. Create a new subfolder named hw7_js-3 (alternatively, you can just upload your local hw7_js-3 folder to the homework folder on the server)
  1. Upload all of your files/folders to the new subfolder
  1. Display your page in the browser and Ctrl+click the validation links to check for errors in your HTML and CSS
  1. Correct any errors that may have crept in, save, and re-upload your revised files to the server
  1. Copy/paste the URL into a text file. Name the file hw7_js-3.txt and upload it to the D2L HW5 folder

Have a nice day 😊