Calling a particular function when multiple events are bound - javascript

I have a site wide JS, which creates listeners for various events, but in certain conditions I need to call a particular function, like in code below, I need to call function call, but its not getting called.
<html>
<head>
<script>
window.onload = function ()
{
var inputs = document.getElementsByTagName("input");
var len = inputs.length;
for (var i=0; i < len; i++)
{
if (inputs[i].getAttribute("type") == "text")
{
var element = inputs[i];
element.onfocus = function()
{
var id = element.getAttribute("id");
alert(id);
}
}
}
}
function call(element)
{
element.value="";
}
</script>
</head>
<body>
<input type="text" name="myvar1" value="same content" id="noviceid" onfocus="call(this);">
<input type="text" name="myvar2" value="same content" id="noviceid" onfocus="call(this);">
</body>
</html>
Please suggest. I would like to call both onfocus. I am new to javascript.

So, once your page has loaded (with proper call onfocus handlers), you run window.onload that overwrites all these handlers. I guess it's not what you intended to do. Instead, you can use DOM2 events, if possible:
element.addEventListener("focus", function(event)
{
var id = event.target.getAttribute("id");
alert(id);
}, false);

Related

How to get value from button after it has been clicked

I'm struggling with this assignment: Pin an event listener to the buttons.
Create a function that gets called when one of the buttons is clicked. Check this with a console.log. Make sure the click event is passed to this function.
Make sure you have access to the value of the button clicked in this function. Check this with console.log. The outcome you want to see in the console when you click is: Leopard / Lion / Elephant / Rhino or Buffalo.
fiveButtons = document.getElementsByClassName("big-five-button");
for (var i = 0; i < fiveButtons.length; i++) {
fiveButtons[i].addEventListener("click", function () {
Array.from(fiveButtons).forEach(function (nameButton) {
console.log(nameButton.innerHTML);
})
});
}
This is what I wrote so far. When I'm clicking the button now, the outcome is the text from all the buttons. While I want the outcome to only be "Lion" after the button lion has been clicked.
<h1>The Big Five</h1>
<ul class="big-five-list">
<li class="big-five-list-item">
<button class="big-five-button">Lion</button>
</li> etc.
when creating an addEventListener you can use the event object to target the element clicked, like this:
fiveButtons[i].addEventListener("click", function (event) {
console.log(event.target.innerHTML);
});
You can change the button to include an onclick function like the below:
https://www.w3schools.com/jsref/event_onclick.asp
<!DOCTYPE html>
<html>
<body>
<button onclick="myFunction('Lion')">Lion</button>
<input type="text" value="" id="getValue">
<p id="demo"></p>
<script>
function myFunction(value) {
document.getElementById("getValue").value = value;
}
</script>
</body>
</html>
The onclick function will then have a value inside the () for the function name. This will pass the value you want across to the function and it can be called whatever you want. The above snippet shows an example of how it can be used
Try this solution!
fiveButtons = document.getElementsByClassName("big-five-button");
for (var i = 0; i < fiveButtons.length; i++) {
fiveButtons[i].addEventListener("click", function (item) {
console.log(item.target.innerHTML);
});
}
The function you pass to addEventListener gives an event argument:
fiveButtons = document.getElementsByClassName("big-five-button");
for (var i = 0; i < fiveButtons.length; i++) {
fiveButtons[i].addEventListener("click", function (event) { // use the first argument
console.log('element value:', event.target.value); // log the 'value' of the event target;
// I suspect you want the innerHTML or innerText
console.log('element innerText:', event.target.innerText);
});
}
You can then get the required information from the DOM node in event.target
You don't need the Array.from inside the for loop. You can just do that:
fiveButtons = document.getElementsByClassName("big-five-button");
for (let i = 0; i < fiveButtons.length; i++) {
fiveButtons[i].addEventListener("click", function () {
console.log(fiveButtons[i].innerText);
});
}
EDITED
// Get all the buttons
const fiveButtons = document.getElementsByClassName("big-five-button");
// Iterate through the collection of buttons
// Here is let i = 0 instead of var i = 0, since var has functional scope and let has block scope
// If we used var i = 0 it would not work implicitly because i would exist in the scope of a function,
// and all the event handlers (for each button) would share the same value of i
for (let i = 0; i < fiveButtons.length; i++) {
// For each button register event handler
fiveButtons[i].addEventListener("click", _ => {
// When button is clicked this part of a code is being called
// Because of javascript CLOSURE, it remembers the i value
console.log(fiveButtons[i].innerHTML)
});
}
If this is not understandable please read about closures in javascript.

Evenet Listener is not executing the functions

Althoug in inline onmauseover="verdadero()" works perfectly
Reviewing I realized that although the box acquires the event listener, simply when I hover over the element the function is not executed, nor is the console.log even written
Note: The Html is simplified for practical purposes
let onCuadro = false;
const cuadro = document.getElementsByClassName("overscroll__box");
for (let i = 0; i < cuadro.length; i++) {
cuadro[i].addEventListener("onmouseover", verdadero,true);
}
for (let i = 0; i < cuadro.length; i++) {
cuadro[i].addEventListener("onmouseleave", falso,true);
}
function verdadero() {
console.log("onCuadro = true");
onCuadro = true;
}
function falso() {
console.log("onCuadro = false");
onCuadro = false;
}
html :
<div class="overscroll__box"></div>
<div class="overscroll__box"></div>
<script src="./index.js"></script>
Event names should not be prefixed with on. Use on when using:
An inline handler, eg <button onclick=, or
When invoking the IDL getter or setter, eg `button.onclick = function() {
But when using addEventListener, only use the event name, without on. The event name here would be mouseover or mouseleave.
for (let i = 0; i < cuadro.length; i++) {
cuadro[i].addEventListener("mouseover", verdadero,true);
cuadro[i].addEventListener("mouseleave", falso,true);
}
Or, more concisely
for (const box of document.getElementsByClassName("overscroll__box")) {
box.addEventListener("mouseover", verdadero, true);
box.addEventListener("mouseleave", falso, true);
}
(You also may well not need to pass a third parameter to addEventListener unless the event delegation really is doing something useful for you)

addEventListener null, onclick works (onload did not work and js is in separate document)

I can use onClick in my HTML file to call upon functions created in my JavaScript file, however, attempting to use addEventListener does not work and I am not sure why. Error in console.log says that the addEventListner is null.
I am attempting to change the display of my web page via a click event.
I understand that addEventListener does not cancel out the previous event called, but even the first event called in my code does not trigger the change which is confusing.
After looking this up I tried the following:
Using window.onload = function(){} and placing the below code within the function.
document.getElementById('begin_game').addEventListener('click', beginGame);
document.getElementById('select_category').addEventListener('click', selectCategory);
Using this code independent of the window.onload function but the addEventListener still returned as null.
The beginGame and selectCategory functions reference the following code in the js file:
function Hide(x) {
const hidden = document.getElementsByClassName(x);
for (var i=0, length= hidden.length; i < length; i++) {
if ( hidden[i].style.display != 'none') {
hidden[i].style.display = 'none';
}
}
}
function Display(x) {
const show = document.getElementsByClassName(x);
for (var i = 0, length = show.length; i < length; i++) {
if (show[i].style.display != 'flex') {
show[i].style.display = 'flex';
}
}
}
//Below is how the functions are referenced
function beginGame() {
document.getElementById('welcome').style.display = 'flex';
Hide('start');
}
function selectCategory () {
Hide('welcome-content');
Display('category');
}
// Where I would place the event listeners I mentioned above
// document.getElementById('begin_game').addEventListener('click', beginGame);
// document.getElementById('select_category').addEventListener('click', selectCategory);
// When I used the window.onload function, I placed it at the bottom of the js page
Buttons from HTML file
<button type='submit' class='welcome-content' id='select_category'>
Categories
</button>
</div>
<h1 class= 'start'>
Math Maniacs
</h1>
<button type='submit' class='start' id='begin_button'>
START
</button>
Using window.onload was the correct solution, I realized that I was not enveloping all of the relevant js code with the onload function.
Before I did this
window.onload = function() {
document.getElementById('begin_game').addEventListener('click', beginGame);
document.getElementById('select_category').addEventListener('click', selectCategory);
}
However, I believe that didn't work because I did not place the functions the event listeners were referencing into the window.onload function.
Once I wrote the below
window.onload = function() {
function beginGame() {
document.getElementById('welcome').style.display = 'flex';
Hide('start');
}
document.getElementById('begin_button').addEventListener('click', beginGame);
function selectCategory() = {
Hide('welcome-content');
Display('category');
}
document.getElementById('select_category').addEventListener('click', selectCategory);
}
The code worked as intended

javascript function won't run onchange

window.onload = init;
function init(){
var allSelect = document.getElementsByTagName("option");
for (var i = 0; i < allSelect.length; i++){
allSelect[i].onchange = loadLink;
}
}
function loadLink(){
alert("TEST");
}
So I'm working on this problem for a class and the functions are incredibly simple. I replaced the code needed with a simple alert because even tracking break point by point it doesn't run the loadLink() function. AllSelect is populated and are all have the onchange value with the specified code in the {}.
I have also tried putting it into the html element by hand and it still doesn't work.
Any Ideas? I'm running locally on my computer with both IE and Chrome if anyone cares to know. Thanks ahead of time.
The onchange event belongs on the select element, not the option elements. So:
window.onload = init;
function init(){
var allSelect = document.getElementsByTagName("select");
for (var i = 0; i < allSelect.length; i++){
allSelect[i].onchange = loadLink;
}
}
function loadLink(){
alert("TEST");
}
I think you want
var allSelect = document.getElementsByTagName("select");
You are instead querying the option elements within selects in the DOM.

Do something on :target with javascript

I'm using the CSS3 :target pseudo selector to create in-page navigation without reloading the page. This works really well!
But I have a problem, I need to reset the forms in a page when the page targetted, how can I know if an element is targetted with javascript? Like element.ontarget = function();
Or maybe something like element.ondisplaychange -> element.oncsschange?
BETTER UPDATE:
var hashcache = document.location.hash;
window.onhashchange = function() {
if(hashcache != document.location.hash) {
$(hashcache + ' form input').each(function() {
$(this).val('');
});
hashcache = document.location.hash;
}
}
UPDATE:
$('a[href^="#"]').each(function() {
this.onclick = function() {
href = $(this).attr('href');
if(href != document.location.hash) {
$(href + ' form input').each(function() {
$(this).val('');
});
}
}
});
If you're using JavaScript for the navigation, I'd suggest just adding the check to that. But I'm guessing from your question you're not, that you're instead using plain links with just anchors (e.g., <a href='#target1'>, <a href='#target2'>, ...).
A couple of options:
Use a Timer
In that case, basically what you want to do boils down to receiving an event when the anchor changes. As far as I know, and as far as the people answering this other question on StackOverflow in January knew, you can only do that with a timer. (Edit: But see ide's comment below, there's a new hashchange event we'll be able to use soon!) E.g.:
(function() {
var lastHash = window.location.hash;
setTimeout(function() {
var newHash = window.location.hash;
if (newHash !== lastHash) {
lastHash = newHash;
// Trigger your target change stuff
}
}, 250);
})();
That checks for changes every quarter second. That may not be enough for you, you could lower the 250, but beware running too much and slowing everything else down.
But as you say below, this is inefficient.
Hook the Link's click event
Since you're already using JavaScript on the page, I'd recommend using handlers on your links instead. If you add a class name or something to them (I bet they already have one; I'll us "navlink" below), this is easily set up:
var links, index, link;
links = document.getElementsByTagName('a');
for (index = 0; index < links.length; ++index) {
link = links.item(index);
if ((" " + link.className + " ").indexOf(" navlink ") >= 0) {
hookEvent(link, 'click', clickHandler);
}
}
function clickHandler() {
// `this` will reference the element that was clicked
}
// The 'hook' function:
var hookEvent = (function() {
var elm = document.createElement('a');
function hookEventViaAttach(element, event, handler) {
element.attachEvent("on" + event, handler);
}
function hookEventViaAddListener(element, event, handler) {
element.addEventListener(event, handler, false);
}
function hookEventDOM0(element, event, handler) {
element["on" + event.toLowerCase()] = handler;
}
if (elm.attachEvent) {
return hookEventViaAttach;
}
if (elm.addEventListener) {
return hookEventViaAddListener;
}
// I usually throw a failure here saying not supported, but if you want,
// you can use the DOM0-style stuff.
return hookEventDOM0;
})();
A lot of the complication of the above goes away if you use a library like jQuery, Prototype, YUI, Closure, or any of several others.
For instance, the jQuery version:
$("a.navlink").click(clickHandler);
function clickHandler() {
// `this` will reference the element that was clicked
}
The Prototype version:
$$("a.navlink").invoke('observe', 'click', clickHandler);
function clickHandler() {
// `this` will reference the element that was clicked
}
The onfocus property returns the onFocus event handler code on the current element.
event handling code = element.onfocus
The onblur property returns the onBlur event handler code, if any, that exists on the current element.
element.onblur = function;
Example: http://jsfiddle.net/g105b/cGHF7/
<html>
<head>
<title>onblur event example</title>
<script type="text/javascript">
var elem = null;
function initElement()
{
elem = document.getElementById("foo");
// NOTE: doEvent(); or doEvent(param); will NOT work here.
// Must be a reference to a function name, not a function call.
elem.onblur = doEvent;
};
function doEvent()
{
elem.value = 'Bye-Bye';
alert("onblur Event detected!")
}
</script>
<style type="text/css">
<!--
#foo {
border: solid blue 2px;
}
-->
</style>
</head>
<body onload="initElement()";>
<form>
<input type="text" id="foo" value="Hello!" />
</form>
<p>Click on the above element to give it focus, then click outside the
element.<br /> Reload the page from the NavBar.</p>
</body>
</html>
Maybe youcan just code like this
function hashChangeEvent(){
$(window.location.hash)//do something
}
window.onhashchange = hashChangeEvent;//when hash change
hashChangeEvent();//first load

Categories

Resources