gyanendra
gyanendra

Reputation: 83

How to close the parent div on clicking the child element using JavaScript?

I have four div elements having same class but different Id. Inside each div i have one paragraph element and a span element. The span have same class but different id. Inside the span i use fa-times(close) icon to close the outer div. How to do it with JavaScript?

I tried declaring the variables using the class name but it returns an Array of HTML Collection. However, i am able to hide the parent div by targeting each element from inside the array. But I know this is the wrong method.

CODE

function close() {
  var clost = document.getElementsByClassName('span');
  clost[0].parentElement.style.display = 'none';
}
<div class="div" id="div_1">
  <p>Please Enter a Keyword</p>
  <span class="span" onclick="close()" id="span_1">
<i class="fa fa-times" aria-hidden="true"></i></span>
</div>

<div class="div" id="div_2">
  <p>Enter your name</p>
  <span class="span" onclick="close()" id="span_2">
<i class="fa fa-times" aria-hidden="true"></i></span>
</div>

<div class="div" id="div_3">
  <p>Enter your city</p>
  <span class="span" onclick="close()" id="span_3">
<i class="fa fa-times" aria-hidden="true"></i></span>
</div>

<div class="div" id="div_4">
  <p>Enter your country</p>
  <span class="span" onclick="close()" id="span_4">
<i class="fa fa-times" aria-hidden="true"></i></span>
</div>

Error: Cannot find parent of Undefined

Expected results: All div should close separately on click on the fa-icon."

Upvotes: 0

Views: 1344

Answers (5)

Keith
Keith

Reputation: 24181

May I offer a simpler solution.

All your div's for close are the same, so you could use a delegated event. Another advantage is if dynamic content is also added later, these events will work for new elements.

Some notes, you can attach delegated events at any point your DOM tree. Here for a simple example I have just used body. But if say you had another container that all your controls are in, you could attach there so that your delegated event doesn't fire when not required.

Also if your events need to stop bubbling down the DOM, you can use evt.stopPropagation, and you can even prevent the DOM default behaviour with evt.preventDefault.

Below is a simple example.

document.querySelector("body").addEventListener("click", 
 function (evt) {
  if (evt.target.classList.contains("fa-times")) {
    evt.target.closest("div").style.display = "none";
  }
 }
);
.fa {
  background-color: #e5e5e5;
  cursor: pointer;
  padding: 4px 6px;
  border: 1px solid silver;
  border-radius: 3px;
}
<div>
  <p>Please Enter a Keyword</p>
  <span>
<i class="fa fa-times" aria-hidden="true">❌</i></span>
</div>

<div>
  <p>Enter your name</p>
  <span>
<i class="fa fa-times" aria-hidden="true">❌</i></span>
</div>

<div>
  <p>Enter your city</p>
  <span>
<i class="fa fa-times" aria-hidden="true">❌</i></span>
</div>

<div>
  <p>Enter your country</p>
  <span>
<i class="fa fa-times" aria-hidden="true">❌</i></span>
</div>

Upvotes: 1

Bahador Raghibizadeh
Bahador Raghibizadeh

Reputation: 1265

function closeDiv(event) {
  event.target.parentElement.style.display = 'none';
}
span{
  background: red
}
<div class="div" id="div_1">
  <p>Please Enter a Keyword</p>
  <span class="span" onclick="closeDiv(event)" id="span_1">***
<i class="fa fa-times" aria-hidden="true"></i></span>
</div>

<div class="div" id="div_2">
  <p>Enter your name</p>
  <span class="span" onclick="closeDiv(event)" id="span_2">***
<i class="fa fa-times" aria-hidden="true"></i></span>
</div>

<div class="div" id="div_3">
  <p>Enter your city</p>
  <span class="span" onclick="closeDiv(event)" id="span_3">***
<i class="fa fa-times" aria-hidden="true"></i></span>
</div>

<div class="div" id="div_4">
  <p>Enter your country</p>
  <span class="span" onclick="closeDiv(event)" id="span_4">***
<i class="fa fa-times" aria-hidden="true"></i></span>
</div>

Upvotes: 1

Gh05d
Gh05d

Reputation: 8962

You should tell your close function which div to be closed by giving a parameter to the function. Then you can target this element:

Javascript

function close(divId) {
  var outerDiv = document.querySelector(`#{divId}`);
  outerDiv.style.display = 'none';
}

HTML

<div class="div" id="div_1">
  <p>Please Enter a Keyword</p>
  <span class="span" onclick="close(div_1)" id="span_1">
<i class="fa fa-times" aria-hidden="true"></i></span>
</div>

<div class="div" id="div_2">
  <p>Enter your name</p>
  <span class="span" onclick="close(div_2)" id="span_2">
<i class="fa fa-times" aria-hidden="true"></i></span>
</div>

<div class="div" id="div_3">
  <p>Enter your city</p>
  <span class="span" onclick="close(div_3)" id="span_3">
<i class="fa fa-times" aria-hidden="true"></i></span>
</div>

<div class="div" id="div_4">
  <p>Enter your country</p>
  <span class="span" onclick="close(div_4)" id="span_4">
<i class="fa fa-times" aria-hidden="true"></i></span>
</div>

Upvotes: 0

freefaller
freefaller

Reputation: 19953

Firstly close will not work as a function name, as you will get a conflict... so change it to something else like closeDiv.

The easiest way to do it with your current code and vanilla JS is to include this as a parameter in the closeDiv(), and then use that directly...

(Note, I have added the word Text to each span so you actually have something to click on)

function closeDiv(spn) {
  spn.parentNode.style.display = "none";
}
<div class="div" id="div_1">
  <p>Please Enter a Keyword</p>
  <span class="span" onclick="closeDiv(this)" id="span_1">
  <i class="fa fa-times" aria-hidden="true">Text</i></span>
</div>

<div class="div" id="div_2">
  <p>Enter your name</p>
  <span class="span" onclick="closeDiv(this)" id="span_2">
  <i class="fa fa-times" aria-hidden="true">Text</i></span>
</div>

<div class="div" id="div_3">
  <p>Enter your city</p>
  <span class="span" onclick="closeDiv(this)" id="span_3">
  <i class="fa fa-times" aria-hidden="true">Text</i></span>
</div>

<div class="div" id="div_4">
  <p>Enter your country</p>
  <span class="span" onclick="closeDiv(this)" id="span_4">
  <i class="fa fa-times" aria-hidden="true">Text</i></span>
</div>


If you have the option to use jQuery, it becomes a bit more simple...

$(function(){
  $(".span").on("click", function(e) {
    $(this).parent().hide();
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="div" id="div_1">
  <p>Please Enter a Keyword</p>
  <span class="span" id="span_1">
  <i class="fa fa-times" aria-hidden="true">Text</i></span>
</div>

<div class="div" id="div_2">
  <p>Enter your name</p>
  <span class="span" id="span_2">
  <i class="fa fa-times" aria-hidden="true">Text</i></span>
</div>

<div class="div" id="div_3">
  <p>Enter your city</p>
  <span class="span" id="span_3">
  <i class="fa fa-times" aria-hidden="true">Text</i></span>
</div>

<div class="div" id="div_4">
  <p>Enter your country</p>
  <span class="span"  id="span_4">
  <i class="fa fa-times" aria-hidden="true">Text</i></span>
</div>

Upvotes: 2

volcanic
volcanic

Reputation: 322

Why don't you pass the id of the parent as argument to the close function?

<span class="span" onclick="close('div_1')" id="span_1">
<i class="fa fa-times" aria-hidden="true"></i></span>

And javascript:

function close (parentId) {
    var parent = document.getElementById(parentId);
    parent.style.display = 'none';
}

Upvotes: 1

Related Questions