js function onclick needs to click one time to change the font - javascript

an event is working fine in js when clicked twice to change the font.I want same should work on single click as well.
js code is below.
function changered() {
iconsred.addEventListener('click', function(event) {
event.target.classList.toggle('fas');
event.style.color= "#ff0000";
}) }
HTML code is below.
<a onclick="changered()" href="#">
<div class="thumb-down">
<i id="iconsred" class="far fa-thumbs-down fa-5x right"></i>
</div>
</a>

The problem is that you are setting the eventlistener after the first click, that's why you need the first click.
I'm not sure if it fits your needs since its a little different but you can change the color on the changered callback instead of adding an event listener. Something like:
function changered() {
icon = document.getElementById('iconsred');
icon.classList.toggle('fas');
icon.style.color= "#ff0000";
}

Any reason why you add the click event on the <a>?
iconsred does not have a click event, before you run changered() that is why you need to click it twice.
You could do it like this:
var iconsred = document.getElementById("iconsred")
iconsred.addEventListener('click', function(event) {
event.target.classList.toggle('fas');
event.target.style.color = "#ff0000";
})
Demo
var iconsred = document.getElementById("iconsred")
iconsred.addEventListener('click', function(event) {
event.target.classList.toggle('fas');
event.target.style.color = "#ff0000";
})
<a href="#">
<div class="thumb-down">
<i id="iconsred" class="far fa-thumbs-down fa-5x right">test</i>
</div>
</a>

It's because you create a new eventListener the first time it is clicked, and therefore it works the second time you make the click.
You can add it to the document, and only react on the specific element if you give it an id:
document.addEventListener('click', function(event) {
if(e.target.id === "yourId") {
event.target.style.color= "#ff0000";
}
})

You can try this.
After DOM loaded we are adding listener.
document.addEventListener("DOMContentLoaded", function(event) {
iconsred.addEventListener('click', function(event) {
event.target.classList.toggle('fas');
event.style.color= "#ff0000";
})
});
<a onclick="changered()" href="#">
<div class="thumb-down">
<i id="iconsred" class="far fa-thumbs-down fa-5x right">test</i>
</div>
</a>

Related

JS - mouseover and mouseout events are inconstant

HTML
<a class="level-item like-icon">
<div class="icon is-medium">
<i class="far fa-heart" onmouseover="change(true)" onmouseout="change(false)"></i>
</div>
</a>
JS
change = (state) => {
state
? event.currentTarget.setAttribute('data-prefix', 'fas')
: event.currentTarget.setAttribute('data-prefix', 'far');
};
Goal:
To change icon (class, or in this case, attribute) when someone hovers over the icon and revert it back when the user hovers out of it. The above code seems to work but there are a couple issues. 1) It fires way to many times when I hover over it and 2) Many times, it doesn't change the attribute back to "far" (state = false). I tried attaching those events to <a> instead of <li> but the issues persist.
p.s. NOT using JQUERY
Something like this one ?
Here i adding and removing a class hover, but ti also may be any attribute or something else
window.addEventListener('mousemove', e => {
let hovered = document.querySelector('.hover');
if (e.target === hovered) return;
if (hovered) {
console.log('mouse out from', hovered);
hovered.classList.remove('hover');
}
if (!e.target.classList.contains('icon'))
return;
e.target.classList.add('hover');
console.log('mouse over on', e.target)
})
.icon {
display: inline-block;
width: 50px;
height: 50px;
transition: 100ms;
border: solid;
text-align: center;
line-height: 50px;
}
.hover {
color: red;
border-radius: 30%;
transform: rotate(10deg)
}
<div class="icon">1</div>
<div class="icon">2</div>
<div class="icon">3</div>
<div class="icon">4</div>
<div class="icon">5</div>
<div class="icon">6</div>
<div class="icon">7</div>
There are 7 'onmouse...' events...
onmousedown,
onmouseenter,
onmouseleave,
onmousemove,
onmouseout,
onmouseover,
onmouseup
... so it is important to use the right one for the job.
In the example clicking and mouse movement within the Element doesn't apply - all we want is a function to be called once when the mouse enters and the element and once agian when the mouse leaves. Therefore...
<!-- HTML -->
<a class="level-item like-icon">
<div class="icon is-medium">
<i class="far fa-heart"
onmouseenter="change(this)"
onmouseleave="change(this)"></i>
</div>
</a>
So here it seems sensible to use the onmouseenter and onmouseleave attributes to call the change() function, and in this case to passes the HTML Element under the mouse as an argument via the this keywords.
Now the function can scrutinize the element and check if it has the desired and required 'data-prefix' attribute, and if so what that attribute is set to. We can then use this condition to set/reset the 'data-prefix' attribute's value...
/* JavaScript */
change = (elem) => {
// does the Element have a 'data-prefix' attribute
// and what is it set to?
let isSet = elem.hasAttribute("data-prefix") && (
"far" === elem.getAttribute("data-prefix")
);
elem.setAttribute("data-prefix", (isSet ? "fas" : "far"));
}
However, as has already been mentioned using the Element.addEventListener() method is more robust and flexible than relying on HTML attributes like onmouse....
This sounds like a duplicate of How do I simulate a mouseover in pure JavaScript that activates the CSS ":hover"?
It's not ideal to deal with mouseover in pure JS, but here is a working example (insipired by an answer to the post I linked).
var element = document.getElementById('hoverIcon');
element.addEventListener('mouseover', function() {
console.log('Mouse over, set Font Awesome class here');
});
element.addEventListener('mouseout', function() {
console.log('Mouse out, remove Font Awesome class here');
});
var event = new MouseEvent('mouseover', {
'view': window,
'bubbles': true,
'cancelable': true
});
<a class="level-item like-icon">
<div class="icon is-medium">
<i id="hoverIcon" class="far fa-heart">ICON</i>
</div>
</a>
Here is a second version of my initial answer, this time with multiple elements.
var elements = document.getElementsByClassName("hover-icon");
var i;
for (i = 0; i < elements.length; i++) {
element = elements[i];
element.addEventListener('mouseover', function(data) {
console.log('Mouse over, set Font Awesome of ID ' + data.originalTarget.id + " here");
});
element.addEventListener('mouseout', function(data) {
console.log('Mouse out, remove Font Awesome of ID ' + data.originalTarget.id + " here");
});
}
var event = new MouseEvent('mouseover', {
'view': window,
'bubbles': true,
'cancelable': true
});
<a class="level-item like-icon">
<div class="icon is-medium">
<i id="hoverIcon1" class="hover-icon far fa-heart">ICON1</i>
<i id="hoverIcon2" class="hover-icon far fa-heart">ICON2</i>
</div>
</a>

How I can prevent the click event on a link which is nested on another element which also use onclick?

I have this simple code
<span class="doit"><a class="doit"href="ww.domain.com">text</a></span>
I want the click on the class "do it" fired a function, so I tried this
$(document).on('click', '.doit', function(e) {
// prevents to handle the click for nested objects again
e.stopPropagation();
alert("hello world");
});
Now I have the problem, that if I click on the <a href the link from href will open and not the on.click function will be fired.
How I can prevent, that the link will be fired instead of the on.click event?
UPDATE 1
I tried a suggested answer with this, failed because the href link is already opened. I must prepare to open the link, only the on.click event should work.
<span class="doit">
<a class="doit" href="http://www.example.com" target="_blank">webcms von
<span class="doit">ABC</span>
<span class="doit">123</span>
</a>
</span>
if ($(e.target).is("a")) {
e.preventDefault(); // stop the href
alert("I WILLL not go to " + e.target.href);
e.cancelBubble = true; // do not click through
e.stopPropagation(); // just stop the event or it will trigger again on the span
return false;
}
console.log('target:'+e.target);
In the console I read: [object HTMLSpanElement
I must find a way, which works in every way the html-tags are ordered or nested.
Update 2
if ($(e.target).is("a"))
{
e.preventDefault(); // stop the href
}
e.cancelBubble=true; // do not click through
e.stopPropagation(); // just stop the event or it will trigger again on the span
alert("hello world");
I see the alert 'hello world' but after that, the link will still be opened
Just test
However I do not recommend you give the same class to the two elements
Here you can click the link and the onclick of the span triggers but not the href
Nested spans are not correct HTML by the way
$(document).on('click', '.doit', function(e) {
if ($(e.target).is("a")) {
e.preventDefault(); // stop the href
alert("I WILLL not go to " + e.target.href);
}
e.cancelBubble=true; // do not click through
e.stopPropagation(); // just stop the event or it will trigger again on the span
alert("hello world");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span class="doit">
<a class="doit" href="http://www.example.com" target="_blank">webcms von
<span class="doit">4U</span>
<span class="doit">.tools</span>
</a>
</span>
Alternative
$(document)
.on('click', 'a.doit', function(e) {
e.preventDefault();
alert("I WILLL not go to " + e.target.href);
})
.on('click', 'span.doit', function(e) {
alert("hello world");
e.cancelBubble=true; e.stopPropagation()
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span class="doit">
<a class="doit" href="http://www.example.com" target="_blank">webcms von
<span class="doit">4U</span>
<span class="doit">.tools</span>
</a>
</span>

jQuery on click trouble

I am having trouble with my jQuery on click function. I can't figure out what I'm doing wrong since it isn't even registering the click in the console (I have set breakpoints and it refuses to visit my on click). I am using jQuery in other areas of my code, so I think I have linked it correctly, and I have checked the target several times to make sure that it is a class and I'm using the correct syntax, but I must have missed something. I feel like I have just been looking at it too long. Any help would be appreciated.
HTML:
<h3 class="collapseButton leftH3" data-toggle="collapse" data-target=".collapse_me">
Returns information about the current User
<span class="pull-right" id="arrow_me">
<i class="fa fa-arrow-down" aria-hidden="true"></i>
</span>
</h3>
JS:
function changeArrows() {
$('.collapseButton').on("click", function() {
$(this).next('.pull-right')
.html('<i class="fa fa-arrow-up" aria-hidden="true"></i>');
});
}
changeArrows();
You have to use children not next
function changeArrows() {
$('.collapseButton').on("click", function() {
$(this).children('.pull-right')
.html('<i class="fa fa-arrow-up" aria-hidden="true"></i>');
});
}
The on click is triggert but your selecotor is not correct.
$(this).children('.pull-right').html('<i class="fa fa-arrow-up" aria-hidden="true"></i>');
works fine for me (changed next for children)
Have you tried
$(document).ready(function(){
changeArrows();
});
Okay, rewrote it to do what you want it to do. Note that instead of next() (which gets the following sibling element with the given selector), you want children() (which gets the child elements of $(this)).
$(this) ends up resolving to be the h3 element in almost every case.
$(document).ready(function() {
$('.collapseButton').on('click', function(event) {
$(this).children('.pull-right')
.html('<i class="fa fa-arrow-up" aria-hidden="true"></i>');
});
});
Try putting the body of your function in $(document).ready( ... ). I don't think your event handler is available after this function is run. The .next() will also find the next sibling, but the element you're wanting to change is a child.
$(document).ready(function() {
$('.collapseButton').on("click", function() {
$(this).children('.fa.fa-arrow-up')
.html('<i class="fa fa-arrow-up" aria-hidden="true"></i>');
});
})
You can also just toggle the class for the i element without changing html:
$(".collapseButton").click(function(e) {
$(this).children('.pull-right').children('.fa-arrow-down').toggleClass('fa-arrow-up');
});
function setVisibility(id1,id2,id3) {
if(document.getElementById('bt1').value=='Show Box 3'){
document.getElementById('bt1').value = 'Show Box 4';
document.getElementById('bt1').value = 'Show Box 5';
document.getElementById(id1).style.display = 'inline';
document.getElementById(id2).style.display = 'none';
document.getElementById(id3).style.display = 'none';
}else{
document.getElementById('bt1').value = 'Show Box 3';
document.getElementById(id1).style.display = 'none';
document.getElementById(id2).style.display = 'inline';
document.getElementById(id3).style.display = 'inline';
}
}
<h4 class="pro_detail_title_name_new" >Product Description
<button type=button name=type id='bt1' onclick="setVisibility('sub3','sub4','sub5');";><span id="sub3" class="mobile-plus1"style="display:inline;" >+ </span><span id="sub5" class="fbutton"style="display:none;">-</span> </button></h4>
<div id="sub4"style="display:none;">-- inside --</div>

Protractor can't click on embedded <span> inside <a> element

I have two embedded <span> elements inside an <a> element. I need to trigger a click event on the second <span>. The by.id method on the id classes I created didn't trigger a click. I also tried by.binding and that didn't work. help please?
The code:
<div class="add-player">
<a href class="btn" data-ng-if="!currentUser.isAuthenticated && !vm.hasPendingInvitation">
<span>Add Player</span>
</a>
<a href class="btn" id="invite" data-ng-if="currentUser.isAuthenticated && !vm.hasPendingInvitation">
<span id="invite-player">Add Player</span>
</a>
</div>
We can play around with locators:
$("div.add-player a span").click();
$("#invite-player").click();
element(by.xpath("//span[. = 'Add Player']")).click();
We can also wait for the element to be visible:
var addPlayer = $("div.add-player a span"),
EC = protractor.ExpectedConditions;
browser.wait(EC.visibilityOf(addPlayer), 5000);
addPlayer.click();
We can also try clicking via JavaScript:
browser.executeScript("arguments[0].click();", addPlayer.getWebElement());
Or via browser.actions():
browser.actions().mouseMove(addPlayer).click().perform();
Or, scroll into view before clicking:
browser.executeScript("arguments[0].scrollIntoView();", addPlayer.getWebElement());
addPlayer.click();
You can also filter the visible element matching a locator:
var addPlayer = $$("#invite-player").filter(function (elm) {
return elm.isDisplayed();
}).first();
addPlayer.click();

Popover click event does not work

$('.pop').each(function () {
var $elem = $(this);
$elem.popover({
placement: 'auto',
trigger: 'hover',
html: true,
container: $elem,
animation: true,
content: function () {
var pop_dest = $(this).attr("data-pop");
//console.log(plant);
return $("#"+pop_dest).html();
}
});
});
$('#english').click(function() { // ---> THIS PART DOES NOT WORK
alert("english");
});
$('#turkce').click(function() { // ---> THIS PART DOES NOT WORK
console.log("turkce");
});
I have 2 button in popover. But their click event does not work. How can I fire click event from button click ? My html code is below.
<li>
<a href="javascript: void(0);" id="languages" class="pop" data-html="true" data-toggle="popover" data-pop="popper-content" class="popper">
<?=$language["languages"]?>
</a>
<div class="hide" id="popper-content">
<ul class="lang-list">
<li class="en">
<button id="english">English</button>
</li>
<li class="tr">
<button id="turkce">Türkçe</button>
</li>
</ul>
</div>
</li>
When you call the click function, the buttons are not added to to page yet (since they are in a dynamically added popover) so you have to use something that takes care of future added content:
$('body').on('click', '#english', function () {
alert("english");
});
You should delegate the event to make sure the event get's to the desired DOM element if it's not present at the time the js gets executed:
$("body").on('click', '#english', function() {
alert("english");
});
$("body").on('click', '#turkce', function() {
alert("turkce");
});
You can delegate events with jquery by using the on method, where the selector is the parent node that will delegate the event to the children, the firs parameter is the event name click, the second is the child you want the event to be delegated to #english and the third parameter is the handler.
The content of the popover is dynamically appended to the page. This means that when you attempt to attach the event handlers when the page loads neither of the buttons exist in the DOM. To fix the problem use a delegated event handler:
$(document).on('click', '#english', function() {
alert("english");
}).on('click', '#turkce', function() {
console.log("turkce");
});
The problem is that <button> has a default type of submit. You don't want that default behavior since you provided your own click handler. You need buttons of type="button".
<button id="english" type="button">English</button>

Categories

Resources