Event Listener for When Element Becomes Visible

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



Leave a reply



Submit