1

I'm stuck as to why I can't get an AddEventListener click event to work on a set of images that appear in a modal. I had them working before before the modal aspect was involve, but I'm not sure that the modal broke the image click event either.

Here is the function in question, which is called within a massive document.addEventListener("DOMContentLoaded", function (event) function:

 var attachClick = function () {
        Array.prototype.forEach.call(containers, function (n, i) {
            n.addEventListener('click', function (e) {

                // populate
                cleanDrawer();
                var mediaFilterSelected = document.querySelector('.media-tags .tag-container .selected');
                var selectedFilters = "";
                if (mediaFilterSelected != "" && mediaFilterSelected != null) {
                    selectedFilters = mediaFilterSelected.innerHTML;
                }
                var portfolioItemName = '';
                var selectedID = this.getAttribute('data-portfolio-item-id');
                var data = portfolioItems.filter(function (item) {
                    portfolioItemName = item.name;
                    return item.id === selectedID;
                })[0];

                clientNameContainer.innerHTML = data.name;
                descriptionContainer.innerHTML = data.description;
                var childItems = data.child_items;

                //We will group the child items by media tag and target the unique instance from each group to get the right main banner
                Array.prototype.groupBy = function (prop) {
                    return this.reduce(function (groups, item) {
                        var val = item[prop];
                        groups[val] = groups[val] || [];
                        groups[val].push(item);
                        return groups;
                    }, {});
                }
                var byTag = childItems.groupBy('media_tags');
                if (childItems.length > 0) {
                    handleBannerItem(childItems[0]);
                    var byTagValues = Object.values(byTag);
                    byTagValues.forEach(function (tagValue) {
                        for (var t = 0; t < tagValue.length; t++) {
                            if (tagValue[t].media_tags == selectedFilters) {
                                handleBannerItem(tagValue[0]);
                            }
                        }
                    });
                    childItems.forEach(function (item, i) {
                        // console.log("childItems.forEach"); we get into here
                        var img = document.createElement('img'),
                            container = document.createElement('div'),
                            label = document.createElement('p');
                        container.appendChild(img);
                        var mediaTags = item.media_tags;

                        container.className = "thumb";
                        label.className = "childLabelInactive thumbLbl";
                        thumbsContainer.appendChild(container);
                        if (selectedFilters.length > 0 && mediaTags.length > 0) {
                            for (var x = 0; x < mediaTags.length; x++) {
                                if (mediaTags[x] == selectedFilters) {
                                    container.className = "thumb active";
                                    label.className = "childLabel thumbLbl";
                                }
                            }
                        }
                        else {
                            container.className = i == 0 ? "thumb active" : "thumb";
                            // console.log("no tags selected"); we get to here
                        }

                        img.src = item.thumb;
                        if (item.media_tags != 0 && item.media_tags != null) {
                            childMediaTags = item.media_tags;
                            childMediaTags.forEach(function (cMTag) {
                                varLabelTxt = document.createTextNode(cMTag);
                                container.appendChild(label);
                                label.appendChild(varLabelTxt);
                            });
                        }
                        //console.log("before adding click to images"); we get here
                        console.log(img.src);
                        img.addEventListener("click", function () {
                            console.log("thumbnail clicked"); //this is never reached
                            resetThumbs();
                            handleBannerItem(item);
                            container.className = "thumb active";
                        });

                    });
                }

                attachClick();

                //open a modal to show off the portfolio pieces for the selected client
                var tingleModal = document.querySelector('.tingle-modal');
                drawer.className = 'drawer';
                var portfolioModal = new tingle.modal({
                    onOpen: function() {
                        if(tingleModal){
                            tingleModal.remove();
                        }
                        console.log('modal open');
                    },
                    onClose: function() {
                        console.log('modal closed');
                        //tingleModal.remove();
                    }
                });

                e.preventDefault();
                portfolioModal.open();
                portfolioModal.setContent(document.querySelector('.drawer-content').innerHTML);

            });

        });
    };

And the specific bit that I'm having trouble with:

console.log(img.src);
img.addEventListener("click", function () {
    console.log("thumbnail clicked"); //this is never reached
    resetThumbs();
    handleBannerItem(item);
    container.className = "thumb active";
});

I tried removing the e.PreventDefault() bit but that didn't solve the issue. I know the images are being created, so the img variable isn't empty. I feel like the addEventListener is setup correctly. I also tried moving that bit up just under the img.src = item.thumb line, but no luck. For Some reason, the click event just will not trigger for the images.

Rob
  • 13,342
  • 26
  • 40
  • 60
Dejsa Cocan
  • 1,418
  • 2
  • 16
  • 45
  • 1
    as shirajg alluded to, you may want to leverage the jQuery `.delegate()` method. It will give you exacting event control even on items not yet on the page because events are bubbled up to the parent, presumably. Please tell us what is the parent for these images, or rather, what is the proper selector for the parent most element that the image will be contained. – Alexander Dixon Oct 06 '17 at 20:02
  • I'd try that but this is a vanilla JavaScript project -- no jQuery – Dejsa Cocan Oct 06 '17 at 20:10
  • img is stored with a div with class 'thumb' and 'thumb' is located within a div called 'thumbs-container' if that helps – Dejsa Cocan Oct 06 '17 at 20:12
  • Here is a link to a stack overflow answers that shows how to leverage class selectors to achieve the same functionality that jQuery `.delegation()` provides. https://stackoverflow.com/a/33015903/5076162 – Alexander Dixon Oct 06 '17 at 20:35

2 Answers2

0

Are the images present in the modal on DOMContentLoaded? You may be able to try delegating the handling of clicks to a parent element if that's the case.

You can try the delegation approach shown here: Vanilla JavaScript Event Delegation

shirajg
  • 103
  • 3
  • 9
  • 1
    They get added in one you select a portfolio category. Selecting a category populates the appropriate divs with the thumbnails associated with that category, if that makes sense. Initially, those divs are empty. – Dejsa Cocan Oct 06 '17 at 19:48
  • 1
    If the images are not there, and you are running code to set up the listeners on elements that are not present. Instead try setting a listener on the DOM element that will contain those thumbnails. – shirajg Oct 06 '17 at 20:38
  • 1
    I ended up just scrapping use of the modal plugin and made my own custom modal. I was able to do that without much trouble and must faster than wasting time on the plugin. – Dejsa Cocan Oct 12 '17 at 17:25
0

So if I understand correctly, you have a modal that lies above the images (it has a higher z-index)? Well in this case the clicks are not reaching the images as they will hit the modal. You can pass clicks through elements that lie above by applying the css property pointer-events: none; to the modal, but thats somehow controversial to what a modal is intended to do.