Analysing button in html to check if can register for events - javascript

I want to register for events on a button in a web page using javascript addEventListener or something equivalent. But the web page doesn't appear to have standard form buttons. The html snippet below is the html markup for what appears as a button on the page.
I want to detect mousedown (or mouseclick or equiv). Is there any way I could detect the user clicking on this button?
<a href="javascript:" id="WIN_0_536870914" arid=536870914 artype="Control" ardbn="Dial" artcolor="null" class="btn btn3d arfid536870914 ardbnDial" style="top:247; left:115; width:46; height:21;z-index:1001;">
<div class="btntextdiv" style="top:0; left:0; width:46; height:21;">
<div class="f1" style=";width:46">Dial</div>
</div>
</a>

The only tricky bit will be getting the elements from the DOM in the first place. If you know the id then it's trivial to get this specific button:
var elem = document.getElementById('WIN_0_536870914');
elem.addEventListener('click', function () {
alert('click!');
});
http://jsfiddle.net/ugsYB/
Although you probably want to target all the buttons by their class:
var elems = document.getElementsByClassName('btn');
var i;
for(i = 0; i < elems.length; i++) {
var elem = elems[i];
elem.addEventListener('click', function () {
alert('click!');
});
}
http://jsfiddle.net/ugsYB/1/ (Note: there are cross browser issues with getElementByClassName)
Of course, jQuery makes this sort of thing trivial:
$('.btn').click(function () { alert('click!'); });
http://jsfiddle.net/ugsYB/2/
But it might be overkill for your needs.

Related

EventListener doesn't trigger by clicking to div's

I create multiple div's dynamically with Javascript
var cart = document.createElement("div");
cart.classList.add("buy-item");
cart.setAttribute("name", "buy-food");
div.appendChild(cart);
and when i collect all the elements with the "buy-item" class i get the elements as an HTMLCollection but when i want to know when it was clicked nothing happens
var elements = document.getElementsByClassName("buy-item");
console.log(elements)
function addFoodToCart() {
console.log("One of buy-item class itemes was clicked")
};
for (var i = 0; i < elements.length; i++) {
elements[i].addEventListener('click', addFoodToCart);
}
The HTML element looks like this
<div class="food-wrap dynamic-food">
<img class="food-item-img" src="/img/foodItem.png">
<p class="food-title">Csípős</p><p class="food-price">190</p>
<div class="buy-item" name="buy-food"></div>
<div class="tooltip">
<span class="tooltiptext">Csípős szósz</span>
</div>
</div>
tl;dr: Add the event listener to the parent div (the one holding all the other elements that you have/will be creating) and use event.target to know which one was clicked.
Not sure if this helps and if this is your case, but you could be benefited by the understanding of Event Bubbling and Event Delegation in Javascript.
In my example below, run the code and click in each paragraph. The console log will show which element you cliked.
function findTheOneClicked(event) {
console.log(event.target)
}
const mainDiv = document.getElementById("parent");
mainDiv.addEventListener('click', findTheOneClicked);
<div id="parent">
<p>"Test 1"</p>
<p>"Test 2"</p>
<p>"Test 3"</p>
</div>
This is really good when you have an element with many other elements on it and you want to do something with them, or when you want to add an event handler to an element that is not available (not created yet) on your page.
Good reading on this topic:
https://javascript.info/bubbling-and-capturing

Two divs clicked at the same time (css)

Let's say I have two divs:
<div id="div1">Click here</div>
<div id="div2">Click here</div>
Is there a way to stack them one upon the other so that when I click one I click both. Preferably with css.
Any solution is welcome.
You cannot trigger events with css.
You can with js:
document.getElementById('div1').addEventListener('click', () => { // on click in div1
document.getElementById('div2').click(); // make div2 clicked
});
You can add this to your script file. Clicking is handled by JavaScript, not by CSS. Even if you place one element over the other, you will be unable to click both at once.
var x = document. getElementsByTagName("div");
for (var i = 0; i < x.length; i++) {
x[i].addEventListener("click", function() {
// Whatever you want to do
});
}
You could have them both call the same function when clicked.
document.getElementById('div1').addEventListener('click', onClick, false);
document.getElementById('div2').addEventListener('click', onClick, false);
function onClick() {
// Do something.
}

how does stoppropagation works with Loops?

i create some Tiles in a foreach loop:
#foreach (var a in Model.AA)
{
<partial name="Partial/A/Tile" model="a" />
}
each of this Tiles have a Button to Start something. (Yes if the JS works i dont need the asp calls at the button)
my Problem is now: The js call works only at the first Tile but not at all others. But Why?
Button
<div class="Infos" Id=#Model.Id>
<a class="button" id="startsomething" url="#Url.Action(nameof(AController.Start), "A")" asp-action="Start" asp-route-Id="#Model.Id">Start me</a>
</div>
JS
$('#startsomething').click(function (event) {
var Id = $(this).parents('.Infos').attr('Id');
var url = $(this).attr('url');
event.preventDefault();
event.stopPropagation();
Start(url, Id)
});
ids are meant to be unique, so the event only registers to one id when you use #startsomething. Use a class name, and the selector .somethingClass.

Avoid popup block with attached event listener

I've got about 10 buttons of class "serviceButton" that also contain a custom attribute called "about". They look like this:
<li>
<button type="button" class="serviceButton serviceButton-red" about="http://blabla">Identity Service</button>
</li>
<li>
<button type="button" class="serviceButton serviceButton-red" about="http://secondLink,etc">VPN</button>
</li>
I've also got some javascript on the page which loops through all buttons of that class and attaches a listener to them that is going to get the value of the about attribute and open up a new window by that. (I am trying to make the site work both on mobile/touch events and desktop/click events).
var classname = document.getElementsByClassName("serviceButton");
var open = function() {
var attribute = this.getAttribute("about");
alert("start");
var win = window.open(attribute, '_blank');
win.focus();
alert("stop");
};
for (var i = 0; i < classname.length; i++) {
classname[i].addEventListener('touchstart', open, false);
}
The first alert gets called successfully, whereas the second one does not; neither does a new tab open. How can I solve this issue by using just js?(No jQuery etc...)
Avoid attaching multiple eventListeners like this, and add it the parent instead.
Here's an exemple, with onclick event, you can adapt it to your problem and it should do the trick.
http://jsfiddle.net/3r7rq8vc/
<ul>
<li about="http://www.google.com">Google</li>
<li about="http://www.devrant.io">Devrant</li>
</ul>
<script>
var listParent,
listenerId,
openLink;
openLink = function(e) {
var targetLink = e.target.getAttribute('about');
// Trying to open
window.open(targetLink, '_blank')
}
// Prefer adding event listener to the parent
listParent = document.querySelector('ul');
listenerId = listParent.addEventListener('click', openLink);
</script>

Javascript click button function under certain div

This is the code of a button in one html page
<a class="btn" role="button" href="#">Click me</a>
I have this javascript code to click a button with a certain class
var clickBtn = document.getElementsByClassName('btn');
for(var i=0;i<clickBtn.length;i++)
{
clickBtn[i].click();
}
This code clicks every button with the class "btn" in ALL the page.
But there are some other buttons in the same page with the same class.
So i want my javascript code to be modifided to click
only a certain button in a certain div.
The code with the div is
<div class="inside">
<span>
<a class="btn" role="button" href="#">Click me</a>
</span>
</div>
Any idea of how can i modify my javascript code to click only the button inside that div??
Thanks for your time.
You can use querySelectorAll()
Array.from(document.querySelectorAll('.inside .btn')).forEach(btn => {
alert(btn.innerHTML)
btn.click();
});
Or without es6:
[].slice.call(document.querySelectorAll('.inside .btn')).forEach(function(btn) {
alert(btn.innerHTML)
btn.click();
});
DEMO
Updated for your comment (Can you update your code that if there is an id in the span like not to click the button?):
[].slice.call(document.querySelectorAll('.inside .btn')).forEach(function(btn) {
if (btn.parentNode.id != 'clicked') {
alert(btn.innerHTML);
btn.click();
}
});
or you can use querySelectorAll() with a :not condition to avoid the if check:
Array.from(document.querySelectorAll('.inside span:not([id="clicked"]) .btn'))
.forEach(btn => {
alert(btn.innerHTML)
btn.click();
});
If you want a non-jQuery solution, you can use getElementById to get the div, and then getElementsByClassName to get all the buttons within that div.
var insideDiv = document.getElementById("inside");
var buttonsInsideDiv = insideDiv.getElementsByClassName();
var parentDiv = clickBtn[i].parentNode;
var clickBtn = document.getElementsByClassName('btn');
for(var i=0;i<clickBtn.length;i++)
{
var parentDiv = clickBtn[i].parentNode;
if(parentDiv == yourDiv)
{
clickBtn[i].click();
}
}
I am not sure, var parentDiv = clickBtn[i].parentNode will work. But the idea is the same.

Categories