0

I have simple dropdown button with image inside it:

By clicking on dropdown button, dropItems() is called, which displays list items:

    function dropItems() {
            document.getElementById("myDropdown").classList.toggle("show");
        }
        window.onclick = function(event) {
        if (!event.target.matches('.dropbtn') || !event.target.matches('#dropdownicon')) {

            var dropdowns = document.getElementsByClassName("dropdown-content");
            var i;
            for (i = 0; i < dropdowns.length; i++) {
                var openDropdown = dropdowns[i];
                if (openDropdown.classList.contains('show')) {
                    openDropdown.classList.remove('show');
                    }
                }
            }
        }
    <div class="dropdown">
                <button onclick="dropItems()" class="dropbtn"><img id="dropdownicon" src="img/dropdown.png" height="25" onclick="dropItems()"></button>
                <div id="myDropdown" class="dropdown-content">
                    <a href="#">Item 1</a>
                    <a href="#">Item 2</a>
                    <a href="#">Item 3</a>
                </div>
            </div>

As you can see, I have also applied onclick event on image inside button, because it blocks button's onclick when you click directly on image.

The problem is that when I click on image, nothing happens.

1
  • include CSS, i recommend using the Insert Code tool in StackOverflow. They making a working example so someone can help you. Commented Sep 22, 2017 at 12:46

2 Answers 2

3

First, you have an onclick in the button as well as the nested image element, which both call the same function and since that function has a toggle in it, the second call could wind up reversing the toggle of the first call.

Second, don't use inline HTML event attributes in the first place (here's a long list of reasons why).

But, the real issue is the layering of the nested image inside of the button, which can obstruct the button from being the event target. The solution is to not use a button at all and just style the image to look like a button and code it to act like a button.

Lastly, if you simply set a class on the drop down list that initially hides the list, the code becomes much simpler:

// Get references to the HTML elements we will need:
var dd = document.getElementById("myDropdown");
var img = document.querySelector("img");

// Set up the click event handler for the image:
img.addEventListener("click", dropItems);

// Set up the click event handler for the window
window.addEventListener("click", function(evt){
  // If anything except the image was clicked...,
  if(evt.target !== img){
    // Hide the list
    dd.classList.add("hide");
  }
});

function dropItems() {
  dd.classList.toggle("hide");
}
/* This will be applied to the list by default */
.hide { display:none; }

/* Style the image to make it look like a button: */
img { 
  display:inline-block;
  padding:5px;
  background-color:#e0e0e0;;
  border:1px solid #808080;
  box-shadow:1px 1px 1px #a0a0a0;
  height:25px;
}

/* Change the style when the image is clicked to make it 
   look like it's a button being clicked. */
img:active {
    box-shadow:-1px -1px 1px #606060;
}
<div class="dropdown">
  <!-- Don't use HTML to style elements. That's CSS's job. -->
  <img id="dropdownicon" class="dropbtn"
       src="https://i.pinimg.com/736x/1d/3b/8e/1d3b8e3c20793a25a32de080956cb41a--emoji-faces-smiley-faces.jpg">

  <!-- Note that the list has the "hide" class applied by default -->
  <div id="myDropdown" class="dropdown-content hide">
    <a href="#">Item 1</a>
    <a href="#">Item 2</a>
    <a href="#">Item 3</a>
  </div>
</div>

Sign up to request clarification or add additional context in comments.

Comments

-1

This doesn't work because images are not allowed in buttons. Here is a possible solution for your problem: https://stackoverflow.com/a/8683553/1751277

4 Comments

This isn't the deal, even if image is outside button, it still does nothing
Of course images are allowed as child elements to the button element.
From MDN "<button> elements are much easier to style than <input> elements. You can add inner HTML content (think <em>, <strong> or even <img>), and make use of :after and :before pseudo-element to achieve complex rendering while <input> only accepts a text value attribute."
Yes, you're right. I reasoned it because I had a problem with images in buttons in the past.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.