Joseph Sliker;11042921 wrote:
Hi; I am working towards a script that will show a set small thumbnail images on one side of the page, that when clicked will show a larger version of the same image, plus related text content on the other side of the page. I am not very good with javascript yet and wonder if the <script> section here is fussier than necessary to accomplish this. It does seem to work. But can the script/code be simpler to accomplish this?
Yes it can. If you don't mind changing your approach completely, the event handler can be changed to a single statement! But you would have to check browser support. It's entirely possible that this has been possible for many years, but I really don't know. This solution comes in the next post.
But without fundamentally changing your original approach, I'd at least go with a "grouped structure", one group for controls and one for display items. I'd also use the same class names for both input and its corresponding display item.
<div id="singular-display-input-group">
<div class="one">Show 1</div>
<div class="two">Show 2</div>
<div class="three">Show 3</div>
</div>
<div id="singular-display-group">
<p class="default">This is default content.</p>
<p class="one">This is content 1.</p>
<p class="two">This is content 2.</p>
<p class="three">This is content 3.</p>
</div>
Using this approach, you can create an event listener on the control group, with a filter of 'div'
$('#singular-display-input-group').on('click', 'div', function (e) { … });
This way you may use e.target.className inside the event handler to relate to the display group, while at the same time retrieving specific elements by first targeting an element by its id.
$('#singular-display-group.' + e.target.className)
This means that only the part of the DOM tree rooted at #singular-display-group has to be traversed in order to find elements with matching class. If you cannot keep .singular-display-group small in the long run, you could also resort to either prefixing id attributes (or suffixing them).
<div id="click-one">Show 1</div>
<div id="click-two">Show 2</div>
<p id="display-one">This is content 1.</p>
<p id="display-two">This is content 2.</p>
And then you could find your display items using (once again inside the event handler above)
// "click-" is 6 characters long, which means "click-one".substring(6) yields "one"
$('#display-' + e.target.id.substring(6));
If you also store a reference to the previously displayed element, you can also target that right away. For example using window.previouslyVisible.
Full example
$(document).ready(function () {
window.$previouslyVisible = $('#singular-display-group .default');
$('#singular-display-input-group').on('click', 'div', function (e) {
var $el = $('#singular-display-group .' + e.target.className);
// .children looks for direct descendants only
$el.removeClass('no-display');
window.$previouslyVisible.addClass('no-display');
window.$previouslyVisible = $el;
});
});
<style>
#singular-display-group .no-display {
display: none;
}
</style>
</head>
<body>
<div id="singular-display-input-group">
<div class="one">Show 1</div>
<div class="two">Show 2</div>
<div class="three">Show 3</div>
</div>
<div id="singular-display-group">
<p class="default">This is default content.</p>
<p class="one no-display">This is content 1.</p>
<p class="two no-display">This is content 2.</p>
<p class="three no-display">This is content 3.</p>
</div>