How to stop click event from creating more than one element?

jquery prevent multiple click events
trigger parent click event when child is clicked
stopimmediatepropagation
stoppropagation not working
javascript capture all events
stop click event jquery
preventdefault
when to use event capturing

I've made a project that creates tabs dynamically. For example, each time the user clicks on the "Email" button, it creates a new "Email" tab (which also includes an 'x' symbol to remove it). I want to prevent click events from creating multiple tabs. However, after the user clicks on a tab's 'x' symbol, I want the user to be able to create it again.

http://jsfiddle.net/v6awanwn/1/

$("#mainTab").on("click", "a", function(e) {
    $(this).tab('show');
  })
  .on("click", "span", function() {
    var anchor = $(this).siblings('a');
    $(anchor.attr('href')).remove();
    $(this).parent().remove();
    $(".nav-tabs li").children('a').first().click();
  });
$('.gtab').click(function(e) {
  var id = $("#mainTab").children().length + 1;
  var tabId = 'contact_' + id;
  var tabtitle = $(this).find('span').html();
  $('#mainTab').closest('li').before('<li><a href="#contact_' + id + '">New Tab</a> <span> x </span></li>');
  $('<li><a href="#contact_' + id + '">' + tabtitle + '</a> <span> x </span></li>').appendTo('#mainTab');
  $('#tabpanel .tab-content').append('<div style="height:400px;" class="tab-pane" id="' + tabId + '">' + tabtitle + '</div>');
  $('#mainTab li:nth-child(' + id + ') a').click();
});
#mainTab li span {
  position: relative;
  top: -31px;
  left: 5px;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>

  <div>
    <ul>
      <li class="gtab">
        <a><span title="Email">Email</span></a>
      </li>
      <li class="gtab">
        <a><span title="system">system</span></a>
      </li>
    </ul>
  </div>
  <div class="tabbable" id="tabpanel">
    <ul id="mainTab" class="nav nav-tabs"></ul>
    <div class="tab-content">
    </div>
  </div>

If you have two elements with same text, you don't do any things. For implementing it you can use code below in click event:

// Get title by text
var tabtitle = $(this).find('span').text();

// Checking for similar element by text
if($("#mainTab li").find('a').text().indexOf(tabtitle) >= 0)
    return;

Online demo (jsFiddle)

The Dangers of Stopping Event Propagation, If the click event originated from inside #menucontainer , stop that event so it will The browser has to go through every single ancestor element of the event in two different and unrelated places, making it far more fragile than necessary. Create a single event listener on the parent theDude element. When any of the one, two, three, four, or five elements are clicked, rely on the propagation behavior that events possess and intercept them when they hit the parent theDude element. Stop the event propagation at the parent element just to avoid having to deal with the event obnoxiously running up and down the DOM tree.

If you give each tab an id based on its type, you can first check whether any such tabs exist (using length). If they don't, then you can create your new tab.

$("#mainTab").on("click", "a", function(e) {
  $(this).tab('show');
})
.on("click", "span", function() {
  var anchor = $(this).siblings('a');
  $(anchor.attr('href')).remove();
  $(this).parent().remove();
  $(".nav-tabs li").children('a').first().click();
});

$('.gtab').on("click", function(e) {
  var tabTitle = $(this).find('span').html();
  var id = 'contact_' + tabTitle;
  var count = $("#" + id).length;

  if (count === 0) {
    var $newTab = $('<li><a href="#' + id + '">' + tabTitle + '</a> <span> x </span></li>');
    var $newContent = $('<div style="height:400px;" class="tab-pane" id="' + id + '">' + tabTitle + '</div>');

    $('#mainTab').append($newTab);
    $('#tabpanel .tab-content').append($newContent);
    $newTab.find("a").click();
  }
});
#mainTab li span {
  position: relative;
  top: -31px;
  left: 5px;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>

<div>
  <ul>
    <li class="gtab">
      <a><span title="Email">Email</span></a>
    </li>
    <li class="gtab">
      <a><span title="system">System</span></a>
    </li>
  </ul>
</div>
<div class="tabbable" id="tabpanel">
  <ul id="mainTab" class="nav nav-tabs"></ul>
  <div class="tab-content">
  </div>
</div>

How to avoid multiple click events in jQuery, One way to avoid multiple click events on any object is by disabling that object If you need to apply the same to multiple handlers, then you can create a good way to dynamically pass in values into the HTML button elements using jQuery? In case it’s not clear what this code is doing, here’s a quick rundown: If a click event propagates to the <html> element, hide the menus. If the click event originated from inside #menucontainer, stop that event so it will never reach the <html> element, thus only clicks outside of #menucontainer will hide the menus.

$("#mainTab").on("click", "a", function (e) {
    e.preventDefault();
    //if (!$(this).hasClass('add-contact')) {
    $(this).tab('show');
    //}
})
    .on("click", "span", function () {
        var anchor = $(this).siblings('a');
        $(anchor.attr('href')).remove();
        $(this).parent().remove();
        $(".nav-tabs li").children('a').first().click();
    });

$('.gtab').click(function (e) {
    console.log('tset');
    //e.preventDefault();
    e.stopPropagation();
    var tabExist = 0;
    var id = $("#mainTab").children().length + 1; //think about it ;);
  var tabId = 'contact_' + id;
    var tabtitle = $(this).find('span').html();
    $("#mainTab li a").each(function(){
    		if($(this).html() == tabtitle){
        	tabExist =1;
        }
    });
    

if(tabExist == 1){
	e.preventDefault();
}else{
	    //$('#mainTab').closest('li').before('<li><a href="#contact_' + id + '">New Tab</a> <span> x </span></li>');
    $('#mainTab').closest('li').before('<li><a href="#contact_' + id + '">New Tab</a> <span> x </span></li>');
    $('<li><a href="#contact_' + id + '">' + tabtitle + '</a> <span> x </span></li>').appendTo('#mainTab');
    $('#tabpanel .tab-content').append('<div style="height:400px;" class="tab-pane" id="' + tabId + '">' + tabtitle + '</div>');
    //$('#tabpanel .tab-content').append('<div class="tab-pane" id="' + tabId + '">Contact Form: New Contact ' + id + '</div>');
    $('#mainTab li:nth-child(' + id + ') a').click();

}
});
#mainTab li span {
    position: relative;
    top: -31px;
    left: 5px;
}
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
   <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<link href="common.css" rel="stylesheet" />
</head>
<body>
    <div>
        <ul>
            <li class="gtab">
                <a><span title="Email">Email</span></a>
            </li>
            <li class="gtab">
                <a><span title="system">system</span></a>
            </li>
        </ul>
    </div>
    <div class="tabbable" id="tabpanel">
        <ul id="mainTab" class="nav nav-tabs"></ul>
        <div class="tab-content">
        </div>
    </div>
   <script
  src="https://code.jquery.com/jquery-3.3.1.min.js"
  integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
  crossorigin="anonymous"></script>
   <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
    <script src="common.js"></script>
</body>
</html>

event.stopImmediatePropagation(), In addition to keeping any additional handlers on an element from being to the top of the document, it is not possible to stop propagation of live events. But, your example looks a bit different. It looks like you also have one event bound to the input object and others to the parent li object. In that case, the one where the event actually originated (presumably the input element in this case) will occur first and then the event will bubble up to the parent objects and they will occur later.

I think the best way to achieve this is to check whether tab with the tabtitle already exists. For this example I would like to change your code a bit. First, I would like to add a new attribute to the tab which your code is creating, data-tab-title, with that it will be much easier to fine the tab. Next you need a condition which will check whether the tab exists, if ($('#tabpanel .tab-content div[data-tab-title="' + tabtitle + '"]').length > 0) return;. Here is a complete click handler for .gtab:

$('.gtab').click(function (e) {
    console.log('tset');
    //e.preventDefault();
    e.stopPropagation();
    var id = $("#mainTab").children().length + 1; //think about it ;)
    var tabId = 'contact_' + id;
    var tabtitle = $(this).find('span').html();

    if ($('#tabpanel .tab-content div[data-tab-title="' + tabtitle + '"]').length > 0) return;

    //$('#mainTab').closest('li').before('<li><a href="#contact_' + id + '">New Tab</a> <span> x </span></li>');
    $('#mainTab').closest('li').before('<li><a href="#contact_' + id + '">New Tab</a> <span> x </span></li>');
    $('<li><a href="#contact_' + id + '">' + tabtitle + '</a> <span> x </span></li>').appendTo('#mainTab');
    $('#tabpanel .tab-content').append('<div style="height:400px;" class="tab-pane" id="' + tabId + '" data-tab-title="' + tabtitle + '">' + tabtitle + '</div>');
    //$('#tabpanel .tab-content').append('<div class="tab-pane" id="' + tabId + '">Contact Form: New Contact ' + id + '</div>');
    $('#mainTab li:nth-child(' + id + ') a').click();
});

Bubbling and capturing, This handler is assigned to <div> , but also runs if you click any nested tag If an element has multiple event handlers on a single event, then even if one of To stop the bubbling and prevent handlers on the current element from stopPropagation() creates hidden pitfalls that later may become problems. Is there any way to execute same code for different elements on the page? What if had class2 cached like this var class2=$ (".class2")? – Vivek S Jun 6 '14 at 5:50. Note that this will still attach events to jquery objects that exist, even if one of the selectors returns undefined. – Ben Sewards Aug 7 '14 at 14:39.

Not really sure what you're trying to do here but I'm guessing that you want to make it so you can only have one of each tab in which case you can just add a bool datatype that just stores whether the tab of a certain type is already opened. and just run a simple if statement before adding a new tab.

Call multiple JavaScript functions in onclick event, Create a Reflex Game using JavaScript · How to generate a n-digit number using JavaScript ? Given multiple functions, the task is to call them by just one onclick event names with element where onclick event occurs or first call a single function How to stop event propagation with inline onclick attribute in JavaScript ? The addEventListener () method attaches an event handler to an element without overwriting existing event handlers. You can add many event handlers to one element. You can add many event handlers of the same type to one element, i.e two "click" events. You can add event listeners to any DOM object not only HTML elements. i.e the window object.

jQuery Event Methods, Event methods trigger or attach a function to an event handler for the selected elements. The following table lists all the jQuery methods used to handle events. You could add a separate event listener for every single accordion link on the page, but that would be madness. There's an easier way: Event Bubbling. An alternate approach is to listen for all clicks on the page by attaching your event listener to the document element. You can then check if the clicked element has the selector you care about.

jQuery event.stopPropagation() Method, Stop the click event from bubbling to parent elements: stopPropagation() method stops the bubbling of an event to parent elements, preventing any parent​  jQuery Events Exercises with Solution: Attach a click and double-click event to a element. w3resource. Attach a click and double-click event to a element

Events and Event Delegation, For example, this code listens for a user to click on any li element in the page: 1 Another benefit of using .on() is the ability to bind to multiple events at once. However, you can create a function ahead of time and store it in a variable, then pass Often, you'll want to prevent the default action of an event; for example, you  Example of getting the element in a click event in Typescript and jQuery - jquery-click-element.ts

Comments
  • So do you want to prevent multiple 'email' or 'system' tabs from being added?
  • yours working fine if you want to limit creating tabs by number