Onclick JavaScript Function Working Only on Second Click

Onclick works only after second click

What you're currently doing is adding an onclick event to a link that calls a function that adds another onclick event via jQuery.

Remove the onclick property and the open_file() function wrapper so that jQuery adds the event as you intended.

onClick method works on 2nd click. But it should work on the 1st click

Your todoDelete() function is only called after a to do item is created and it is within that function that all the items are found and given their delete event handler. So the first click gives the element you just clicked on its handler and the second click allows that handler to run, deleting the element.

Instead, the handler should be set prior to the element being created. This can be done through "event delegation", whereby you set the handler up on an ancestor of all the elements and allow the event to bubble up to that element to be handled there. Since that element will exist from the start, it's no problem to set it up on it. Then, when the event is triggered by a dynamically added element later, the event bubbles up to the ancestor, is handled there and in the handler, the actual source of the event is determined. If it is the right source, then you act appropriately. If not, do nothing. This approach not only allows for dynamically added or removed elements to immediately participate in the event handling, but it results in just a single event handler registration, rather than one for each dynamically added element, which is more efficient and easier to keep track of.

Additionally:

  • Don't use inline HTML event attributes like onXyz in the first
    place (here's even more on that).
  • Don't use .getElementsByClassName(), instead use
    .querySelectorAll() when a node list/collection is desired.

So here's your code again, using this approach (see additional comments inline):

const todoAdd = document.getElementById("buttonAdd");
const output = document.getElementById("todoMissions");

// When you are going to need to use the same element
// over and over, just get the reference just once and
// keep using it.
const input = document.getElementById("input");

// Set up the delete handler on an ancestor of all the potential items
document.querySelector(".todo").addEventListener("click", todoDelete);

//ADD
todoAdd.addEventListener("click", () => {
// Best to test this first and then only do the work if there is a value.
if(input.value == ""){
alert("You must write something!");
}else{

var p = document.createElement("p");
// Use the .classList API when setting/removing/toggling
// classes instead of .setAttribute as the API is more straight-forward
p.classList.add("mission");

// No need to create a text node and then inject that into your string
// just inject the string value right into the string.
p.innerHTML = `${input.value} <button class="buttonDelete"><i class="fas fa-trash trash">X</i>`;
output.appendChild(p);
}

input.value = "";
});


//DELETE
function todoDelete(event){
// Look at the event argument and see if the event
// was triggered by a todo item delete button or the
// <i> element within one.
if(event.target.classList.contains("buttonDelete")
|| event.target.classList.contains("trash")){
event.target.closest("p").remove(); // Remove the nearest ancestor p
}
}
<div class="todo">
<input id="input" type="text" maxlength="30" placeholder="text...">
<button id="buttonAdd"><i class="fas fa-pen pencil">Add</i></button>
<div id="todoMissions"></div>
</div>

OnClick Functions Only Work On Second Click

In the handler, you access Par1.style. The style property of an element refers to the style properties in an inline style="..." HTML attribute. You specified that elsewhere, you had something like the following in CSS:

#para1 {
display: none;
}

This doesn't get picked up in Par1.style.display. Look into getComputedStyle if you want to see what's currently applied. fiddle

Or just do your conditional the other way around:

Par1.style.display = ((Par1.style.display!='block') ? 'block' : 'none')

Click event only works on the second click

The problem is you call the function umClick and call the function to add .selected within a click event in the same function umClick.

What happens is the click event completedLine.addEventListener('click', umClick); happens before the i.addEventListener('click', function semNomeDois() event. This is why you need a first click on the ol tag for only the first time.

To fixes this you have multiple options:

  1. instead of calling click event on ol tag you can call mousedown which happens before click event.
  2. Calling a click event on the li elements on creation, which needs a new function.
  3. Depending on Vektor's answer, you can remove the unnecessary click event inside the first click event.

Also, I've made the red highlight on the .selected class instead of :focus, just to make it clear when the item is selected.

.selected {
background: red;
}

First Solution

const textoTarefa = document.getElementById('texto-tarefa');
const criarTarefa = document.getElementById('criar-tarefa');
const listaTarefas = document.getElementById('lista-tarefas');
criarTarefa.onclick = function click() {
const lista = document.createElement('li');
lista.className = 'lista';
lista.id = 'lista';
lista.tabIndex = '0';
lista.innerHTML = textoTarefa.value;
listaTarefas.appendChild(lista);
document.body.appendChild(listaTarefas);
textoTarefa.value = '';
};
const completedLine = document.querySelector('ol');

function umClick(event) {
if (event.target.tagName === 'LI') {
const listas = document.querySelectorAll('.lista');
listas.forEach((i) => {
i.addEventListener('click', function semNomeDois() {
listas.forEach((j) =>{
if(j != event.target)
j.classList.remove('selected');
});
this.classList.add('selected');
});
});
}
}
completedLine.addEventListener('mousedown', umClick);

function removeSelected() {
// teste
const listaSelected = document.querySelectorAll('.selected');
for (let i = 0; i < listaSelected.length; i += 1) {
listaSelected[i].remove();
}
}
.selected {
background: red;
}
<!DOCTYPE html>
<html>

<head>
<link rel='stylesheet' href='style.css'>
</head>

<body>
<header>
<h1>My List</h1>
</header>
<input id='texto-tarefa' type="text" />
<button id='criar-tarefa' type="submit" onClick='click()'>Add</button>
<ol id='lista-tarefas'>
</ol>
<button id='remover-selecionado' type="submit" onClick='removeSelected()'>Remove Selected (Only One)</button>
<script src="script.js"></script>
</body>

</html>

Javascript Code Words Only After Second Click

Remove the onclick event, call the function on load itself.

You are calling openaccordion function on click of each button. The openaccordion is registering the onclick event of each button. When the button is clicked for the first time you are looping through the uttons and registering the onclick event for all the three buttons. Now the required action is registered but only after clicking the button for the first time. From next time onwards the button will behave as expected, that is because of the onclick listner written inside openaccordion function. But again when you click ay one of the button, the click event for each button will be regitered again. This is not needed.

Actually your openaccordion function is registring the click event for the three button. This need not to be called ach time when the button is clicked, insted only once when the document is loaded.

Working fiddle: I have updated the function name openaccordion to registeraccordionEvents since that is a more generic name for the functionality.

function registeraccordionEvents() {
//this is the button
var acc = document.getElementsByClassName("course-accordion");
var i;
for (i = 0; i < acc.length; i++) {
//when one of the buttons are clicked run this function
acc[i].onclick = function () {
//variables
var panel = this.nextElementSibling;
var coursePanel = document.getElementsByClassName("course-panel");
var courseAccordion = document.getElementsByClassName("course-accordion");
var courseAccordionActive = document.getElementsByClassName("course-accordion active");

/*if pannel is already open - minimize*/
if (panel.style.maxHeight) {
//minifies current pannel if already open
panel.style.maxHeight = null;
//removes the 'active' class as toggle didnt work on browsers minus chrome
this.classList.remove("active");
} else { //pannel isnt open...
//goes through the buttons and removes the 'active' css (+ and -)
for (var ii = 0; ii < courseAccordionActive.length; ii++) {
courseAccordionActive[ii].classList.remove("active");
}
//Goes through and removes 'activ' from the css, also minifies any 'panels' that might be open
for (var iii = 0; iii < coursePanel.length; iii++) {
this.classList.remove("active");
coursePanel[iii].style.maxHeight = null;
}
//opens the specified pannel
panel.style.maxHeight = panel.scrollHeight + "px";
//adds the 'active' addition to the css.
this.classList.add("active");
}
}//closing to the acc onclick function
}//closing to the for loop.
}
registeraccordionEvents();
button.course-accordion {
background-color: transparent;
color: white;
cursor: pointer;
padding: 8px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 22px;
font-weight: 600;
transition: 0.4s;
font-family: "Raleway";
line-height: 1.5em;
text-transform: none;
letter-spacing: 0px;
font-weight: 600;
font-style: normal;
}

/*When the button is active or mouse hovers*/
button.course-accordion.active,
button.course-accordion:hover {
background-color: rgba(166, 166, 166, 0.6);
}

/*button not active*/
button.course-accordion:after {
content: '\002B';
color: white;
font-weight: bold;
float: right;
margin-left: 5px;
}

/* minus button */
button.course-accordion.active:after {
content: "\2212";
}

div.course-panel {
padding: 0 18px;
background-color: transparent;
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
width: 96%;
font-family: "Raleway";
font-size: 15px;
line-height: 1.6em;
letter-spacing: .4px;
font-weight: 400;
font-style: normal;
color: rgba(0, 0, 0, .88);
}
<button class="course-accordion">Title 1</button>
<div class="course-panel">Text 1</div>
<button class="course-accordion">Title 2</button>
<div class="course-panel">Text 2</div>
<button class="course-accordion">Title 3</button>
<div class="course-panel">Text 3</div>

onclick function it's working only after second click

First u r binding the "showimage" method to be called when u click on the image then u r binding

function ()
{
modal.style.display = "block";
modalImg.src = this.src;
captionText.innerHTML = this.alt;
}

on click of the image. So u should not bind the event again on the image tag.

remove either onclick="showimage()" from ur html tag or remove img.onclick from the JS code.

write it like :

function showimage(z)
{
var modal = document.getElementById('myModal'+z);
var img = document.getElementById('myImg'+z);
var modalImg = document.getElementById('img01'+z);
var captionText = document.getElementById('caption'+z);

modal.style.display = "block";
modalImg.src = img.src;
captionText.innerHTML = this.alt;
}

and it will work perfectly.

Onclick javascript function working only on second click

You do not need to bind a click event handler inside another click event handler. You have to use a single click event handler.

The show/hide functionality belongs to second click event handler and this is binded to your span DOM element after first click.

function toggleDivFunction () {   var arrowElement = document.getElementById ("arrowRight");   var showElement = document.getElementById ("dropdownText");   if(showElement.style.display == 'none')   {      showElement.style.display = 'block';       document.getElementById("arrowRight").style = "transform: rotate(+90deg)";   }   else   {      showElement.style.display = 'none';      document.getElementById("arrowRight").style = "transform: rotate(0deg)";   }}
<p class="dropdownHeader">TOP <span id="arrowRight" class="arrowRight" onclick="toggleDivFunction();"> > </span></p><div class="dropdownText" id="dropdownText"><p>TEXT TO BE SHOWN</p></div>


Related Topics



Leave a reply



Submit