Thanks @mbostock for your time and guidance!
Both your off- and on-topic responses are helpful and informative, thank you!
In this particular case, I am trying to learn how to write this for “vanilla” JavaScript, and using Observable to help me better see and understand how the functions work. For this reason, I have been trying to shy away from using JS to create the DOM element, and instead using JS to add additional functionality on top of the tachyons.css page frame written in HTML.
I remain perplexed by this particular problem, as everything looks to me like it should be working.
After setting up the navigation component and giving each element a unique id
and common class
names, I can see that both .querySelectorAll()
and .getElementsByClassName
have correctly returned matches:
page_navigation.getElementsByClassName("link").length // returns 3 - the number of nav elements I've defined with this class name
page_navigation.querySelectorAll("#link1, #link2, #link3").length // returns 3
So selection is working, and I get a NodeList
that acts like an Array
(and can be converted into it). The function I am trying to execute for an .onclick
event is effective where I specify a single value using .getElementById
. but not for the multiple values returned with .querySelector()
.
That is, this will work:
attempt_using_id = page_navigation.querySelector("#link1").onclick = function(event) {
let random_image = image_list[Math.floor(Math.random()*Object.keys(image_list).length)]
image_view.querySelector("#image").src = random_image
}
But nearly the same thing with another element selection will not work.
Neither
page_navigation.getElementsByClassName("link").onclick = function(event) {
let random_image = image_list[Math.floor(Math.random()*Object.keys(image_list).length)]
document.getElementById('image').src = random_image
}
nor
page_navigation.querySelectorAll("#link1, #link2, #link3").onclick = function(event) {
let random_image = image_list[Math.floor(Math.random()*Object.keys(image_list).length)]
document.getElementById('image').src = random_image
}
These different outcomes for what appear to be similar constructs is hard to understand, and regrettably I’m not quite grasping it through trial-and-error + reading. Fortunately, there’s an easy workaroud (just repeating the working function for as many elements I wish), but this isn’t a satisfying solution. I suspect that, once I obtain the `NodeList`, there’s something more I must do. I am currently reading about forEach
and also trying to write for
loops, but haven’t quite gotten it.
Thanks again for your time, help and guidance! I definitely appreciate learning from this that I can specify a cell’s name to focus where I am looking for elements (and thereby creating an Observable dependency). I also appreciate your suggestions for how to accomplish the same effect in a different, more Observable way using views. I hope it’s OK that I am asking more basic JS-related questions. Very early on, Fabian indicated that I should embrace your invitation to discuss:
…common questions, examples of techniques, and general discussion about data science, visualization, programming, and more. [ref]