Event listener for when element becomes visible?
Javascript events deal with User Interaction, if your code is organised enough you should be able to call the initialising function in the same place where the visibility changes (i.e. you shouldn't change myElement.style.display
on many places, instead, call a function/method that does this and anything else you might want).
jQuery event to trigger action when a div is made visible
You could always add to the original .show() method so you don't have to trigger events every time you show something or if you need it to work with legacy code:
Jquery extension:
jQuery(function($) {
var _oldShow = $.fn.show;
$.fn.show = function(speed, oldCallback) {
return $(this).each(function() {
var obj = $(this),
newCallback = function() {
if ($.isFunction(oldCallback)) {
oldCallback.apply(obj);
}
obj.trigger('afterShow');
};
// you can trigger a before show if you want
obj.trigger('beforeShow');
// now use the old function to show the element passing the new callback
_oldShow.apply(obj, [speed, newCallback]);
});
}
});
Usage example:
jQuery(function($) {
$('#test')
.bind('beforeShow', function() {
alert('beforeShow');
})
.bind('afterShow', function() {
alert('afterShow');
})
.show(1000, function() {
alert('in show callback');
})
.show();
});
This effectively lets you do something beforeShow and afterShow while still executing the normal behavior of the original .show() method.
You could also create another method so you don't have to override the original .show() method.
Trigger event when element becomes visible with ngIf
Your div will be rendered and visible once the change detection is triggered. When a change is detected, the whole lifecycle is ran again.
If you want to run something, you should hook on one of the events of the lifecycle. I suggest AfterViewInit
.
Now that you know how, let's see what you should do.
In your case, you should create div with template references. This will allow you to have a reference to the element and make you able to check which div is shown or hidden.
Here is a stackblitz that shows you how it works, and here is the code :
import { Component, ViewChildren, QueryList, ElementRef } from '@angular/core';
@Component({
selector: 'my-app',
template: `
<div *ngFor="let item of [0, 1, 2, 3, 4, 5]; let i = index">
<span *ngIf="i === show" #shownDiv [id]="'div-' + i">{{ item }}</span>
</div>
`
})
export class AppComponent {
name = 'Angular 6';
show = 0;
@ViewChildren('shownDiv') divs: QueryList<ElementRef>;
ngOnInit() {
setInterval(() => {
this.show++;
if (this.show > 5) {
this.show = 0;
}
}, 1000);
}
ngAfterViewChecked() {
let shown = this.divs.find(div => !!div);
console.log('DIV shown is ' + (shown.nativeElement as HTMLSpanElement).id);
// Now that you know which div is shown, you can run whatever piece of code you want
}
}
Must an element be visible in order to load event listener to work?
Per our discussion, visibility:hidden
is solving the event issue.
Following is a example addressing your second problem, UI spacing.
function registerEvent() { document.getElementById("test").addEventListener("click", function() { console.log("Test"); });}
function addClass(str) { document.getElementById("test").className = str;}
div { height: 100px; width: 100px; border: 2px solid gray; float: left; margin: 10px; padding: 10px;}.display { display: none}.hidden { visibility: hidden}.invisible { visibility: hidden; height: 0px; width: 0px; margin: 0px; padding: 0px;}.show { visibility: visible; display: block;}
<div id="test">0</div><div id="test1">1</div>
<button onclick="addClass('display')">Display</button><button onclick="addClass('hidden')">Hidden</button><button onclick="addClass('invisible')">Invisible</button><button onclick="addClass('show')">Show</button>
jQuery when element becomes visible
There are no events in JQuery to detect css changes.
Refer here: onHide() type event in jQuery
It is possible:
DOM L2 Events module defines mutation events; one of them - DOMAttrModified is the one you need. Granted, these are not widely implemented, but are supported in at least Gecko and Opera browsers.
Source: Event detect when css property changed using Jquery
Without events, you can use setInterval
function, like this:
var maxTime = 5000, // 5 seconds
startTime = Date.now();
var interval = setInterval(function () {
if ($('#element').is(':visible')) {
// visible, do something
clearInterval(interval);
} else {
// still hidden
if (Date.now() - startTime > maxTime) {
// hidden even after 'maxTime'. stop checking.
clearInterval(interval);
}
}
},
100 // 0.1 second (wait time between checks)
);
Note that using setInterval
this way, for keeping a watch, may affect your page's performance.
7th July 2018:
Since this answer is getting some visibility and up-votes recently, here is additional update on detecting css changes:
Mutation Events have been now replaced by the more performance friendly Mutation Observer.
The MutationObserver interface provides the ability to watch for changes being made to the DOM tree. It is designed as a replacement for the older Mutation Events feature which was part of the DOM3 Events specification.
Refer: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
How to trigger a javascript event when a button becomes visible?
You can try MutationObserver
that will listen for changes in css of element and then you can run click event when change happens.
setTimeout(function() { $('button').css('display', 'block');}, 2000);
var observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { if ($('button').css('display') !== 'none') { $('button').click(); } });});
observer.observe(document.querySelector('button'), { attributes: true, attributeFilter: ['style']});
$('button').click(function() { alert('clicked');})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><button class="btn btn-primary" style="display: none;">Apply All</button>
how to get an event when a div gets visible
Since you did not explain if there is any specific lib/framework you are using, or is there any specific condition to render element visible I will give you this:
jQuery $(document).ready() can detects if whole page is loaded.
On the other hand if element was display:none or visibility:hidden, or both or whatever, you can use jQuery is like this : $('element').is(':visible') as a condition and trigger whatever inside if statement.
An event listener is only created for the last element in forEach loop
Because, you are capturing the button by ID. It will capture the last ID recorded.
Instead use querySelector.
Try below, which is not a proper code, you need to tweak based on error messages.
get(ref(db, "chats")).then((snapshot) => {
snapshot.forEach((child) => {
var html = "";
var childName = child.val().chatname;
var childPassword = child.val().chatpassword;
console.log(childName);
html += `
<li>
<div class="chat-login-container">
<h3>`+ childName + `</h3>
<input type="hidden" class="childname" value="`+ childname + `">
<input type="hidden" class="childPassword" value="`+ childPassword + `">
<input id="`+ childName + `-input" class="password" type="password" placeholder="Enter Chat Password">
<button id="`+ childName + `-button" class="login">Enter</button>
</div>
</li>
`;
messages.innerHTML += html;
});
const chatLoginContainers = document.querySelectorAll('.chat-login-container');
chatLoginContainers.forEach((element) => {
const loginBtn = element.querySelector('.login');
loginBtn.addEventListener('click', (event) => {
const childNameEle = event.target.closest('li').querySelector('.childname');
const childPasswordEle = event.target.closest('li').querySelector('.childPassword');
const passwordEle = event.target.closest('li').querySelector('.password');
const childNameVal = childNameEle.value;
const childPasswordVal = childPasswordEle.value;
const passwordVal = passwordEle.value;
get(ref(db, "chats/" + childNameVal)).then((snapshot) => {
if (passwordVal == childPasswordVal) {
chat = childNameVal;
console.log("Logging in to " + childNameVal);
messages.innerHTML = "";
start();
} else {
window.alert("Incorrect password, please try again");
}
}).catch((error) => {
console.log(error);
});
})
});
}).catch((error) => {
console.log(error);
});
Related Topics
Orderby Multiple Fields in Angular
Random Number Generator Without Dupes in JavaScript
Get Position/Offset of Element Relative to a Parent Container
How to Get a Specific Parameter from Location.Search
How to Serialize an Input File Object to JSON
Where Would I Use a Bitwise Operator in JavaScript
How to Get the Containing Form of an Input
Reactjs: Prevent Multiple Times Button Press
Replace a String in a File with Nodejs
Regex Pattern to Match the End of a String
Jquery's Live() Is Deprecated. What Do I Use Now
Node.Js Variable Declaration and Scope