1

I have the following event-listeners

element2.addEventListener("focusout", hideDropdown);
element3.addEventListener("click", addSelectedOption);

when I click on element3, only function1 is called, but I want both to be called since clicking element3 also means that element2 lost focus.

When I remove the the first event listener, then the second one works. Why is this the case? and how can I get around it?

Here is the code:

<!DOCTYPE html>
<html>
<header>

<style>
    #element3 {
        display: none;
    }
</style>
</header>

<body>
<label>Multi Select</label>
<div id="element1">
    <p id="element2" contenteditable="true">Select required competencies</p>
</div>
<div id="element3" class="auto-complete-select-dropdown">
    <p>One</p>
    <p>Two</p>
    <p>Three</p>
    <p>Four</p>
</div>

<script>

    var element1 = document.getElementById("element1");
    var element2 = document.getElementById("element2");
    var element3 = document.getElementById("element3");

    element2.addEventListener("keyup", showDropdown);
    element2.addEventListener("focusout", hideDropdown);
    element3.addEventListener("click", addSelectedOption);

    function showDropdown() {
        var element = document.getElementById("element3");
        if (element.style.display != "block")
            element.style.display = "block";
    }

    function hideDropdown() {
        var element = document.getElementById("element3");
        if (element.style.display != "none")
            element.style.display = "none";
    }


    function addSelectedOption(event) {
        alert("here");
        element = event.target;
        var element1 = document.getElementById("element1");
        var p = document.createElement('p');
        p.textContent = element.textContent.trim();
    }
</script>
</body>
</html>
1
  • 1
    You'll need to show the relationship between element1 and element2... like in HTML. Events travel up and down the DOM tree. Commented Oct 26, 2018 at 16:50

1 Answer 1

4

The focusout event fires when the user presses down the mouse button on some other element. The click event fires when the user releases the mouse button over some element. So, the problem is that the focusout event on element2 fires before the click event fires on element3. In the focusout listener, element3's display is set to none - it gets hidden, which means it's unclickable a few milliseconds later when the user releases the mouse button.

Even if the user tried to click on it, the element was hidden from the focusout event before the click event could fire, so the click handler never runs.

One option would be to add a mousedown listener to element3, which will fire at the same time as the focusout event (synchronously, so the browser doesn't have time to repaint the page before the mousedown event gets processed):

element3.addEventListener("mousedown", addSelectedOption);

var element1 = document.getElementById("element1");
var element2 = document.getElementById("element2");
var element3 = document.getElementById("element3");

element2.addEventListener("keyup", showDropdown);
element2.addEventListener("focusout", hideDropdown);
element3.addEventListener("mousedown", addSelectedOption);

function showDropdown() {
  var element = document.getElementById("element3");
  if (element.style.display != "block")
    element.style.display = "block";
}

function hideDropdown() {
  var element = document.getElementById("element3");
  if (element.style.display != "none")
    element.style.display = "none";
}


function addSelectedOption(event) {
  console.log('adding selected option');
  element = event.target;
  var element1 = document.getElementById("element1");
  var p = document.createElement('p');
  p.textContent = element.textContent.trim();
}
#element3 {
  display: none;
}
<label for="requiredCompetencies">Required Competencies</label>
<div id="element1">
  <p id="element2" contenteditable="true">Select required competencies</p>
</div>
<div id="element3" class="auto-complete-select-dropdown">
  <p>One</p>
  <p>Two</p>
  <p>Three</p>
  <p>Four</p>
</div>

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

Comments

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.