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:
- instead of calling
click
event onol
tag you can callmousedown
which happens beforeclick
event. - Calling a click event on the
li
elements on creation, which needs a new function. - Depending on Vektor's answer, you can remove the unnecessary
click
event inside the firstclick
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
How to Jump to Top of Browser Page
Jquery.Lazy(): Plugin Is Not Loading My 'Li' Contents
Z-Index Inherits Parents Z-Index , or Not
How to Get New Image Size Dimension After Giving Object-Fit:Contain Property to the Image Tag
How to Change the Design of the Textarea Resize Handle in CSS
How to Make the Whole Card Component Clickable in Material UI Using React Js
How to Pause CSS Transition Mid-Way
Add Custom Buttons on Slick Carousel
How to Make Content Load When the User Scrolls Down to It
How to Check If Character Isn't Supported by the User's Browser in JavaScript
Bootstrap Switch Checked Event
How to Save an Image with CSS Filter Applied
Webview Methods on Same Thread Error
Bootstrap 4 Input Field in Popover
Change Header CSS Upon Scrolling Down
Ios: Disable Bounce Scroll But Allow Normal Scrolling