How to determin that javascript has finished doing something - javascript

JS on ios is rather slow. For example in this piece of code, the Js adds the class before being able to add the block style. This breaks an animation i have on the page.
comments.style.display="block";comments.className = "show";
I have a workaround that fixes the issue on ios but just feels wrong:
comments.style.display="block";setTimeout(function(){comments.className = "show";},1)
Is there any way to determine if the block style has been set and only then trigger the second part?
Thanks for your suggestions!

Can't you just use an if?
<div id="foo" style="display: none;">foo</div>
var div = document.getElementById( "foo" );
if ( div.style.display == "none" ) {
div.style.display = "block";
}
If you want to listen to a class change (or a style change) "event", you can try these links:
Event detect when css property changed using Jquery <= this solves the problem without jQuery
jQuery - Fire event if CSS class changed
Trigger event using Jquery on CSS change?
Is it possible to listen to a "style change" event?
I think the first one will solve your problem. Here is the code:
document.documentElement.addEventListener( "DOMAttrModified", function( evt ){
if ( evt.attrName === "style" ) {
if ( evt.newValue.indexOf( "block" ) != -1 ) {
alert( "do something!" );
}
}
}, false );
document.getElementById( "foo" ).style.display = "block";

This is a glorious mess of a hack that may work:
comments.blockStyleEvent = function() {
if ( this.style.display === "block" ) {
this.onBlockStyleEvent.apply(this);
}
};
comments.onBlockStyleEvent = function() {
this.className = "show";
};
setInterval(function(){
comments.blockStyleEvent();
}, 1);
You could also create two css classes one show and another showAsBlock for example then you could do this:
// somewhere else
comments.className = "hide";
// ...then
comments.className = "showAsBlock";

Related

Javascript pop up

Im kinda new to the world of web development , right now I have knowledge in CSS & HTML and trying and learn TypeScript. Im trying to make this message icon to open up and close up this notifications bar.
right now this is i got so far:
document.getElementById("bar").addEventListener("click", function(){
document.querySelector(".messagebar").style.display = "flex";
})
I tried to make:
document.getElementById("bar").addEventListener("click", function(){
document.querySelector(".messagebar").style.display = "none";
it`s not working. ty for help!
I tried to make:
document.getElementById("bar").addEventListener("click", function(){
document.querySelector(".messagebar").style.display = "none";
it`s not working. ty for help!
You are adding 2 of the same event listeners to the same element. This means that the event listener you are creating here:
document.getElementById("bar").addEventListener("click", function(){
document.querySelector(".messagebar").style.display = "flex";
})
and the event listener created here:
document.getElementById("bar").addEventListener("click", function(){
document.querySelector(".messagebar").style.display = "none"
)}
are both being executed at the same time upon click. This means that the display is first being set to flex and secondly to none hence why you are unable to make it work.
In order to fix this we want to condense this into one event listener.
The following works:
document.getElementById("bar").addEventListener("click", () => {
const messageBar = document.querySelector('.messagebar')
const display = messageBar.style.display
// if display is flex sets it to none else sets it to flex
messageBar.style.display = display === 'flex' ? 'none' : 'flex'
});
If you want to toggle with the same button, or html element, you will have to track the currect state of the .messagebar.style.display.
document.getElementById("bar").addEventListener("click", function(){
const current = document.querySelector(".messagebar").style.display;
if (current === "none") {
document.querySelector(".messagebar").style.display = "flex";
} else {
document.querySelector(".messagebar").style.display = "none";
}
})

Why does this js not working? Change onclick attribute

Fast and probably easy for you problem to solve.
function openNav() {
document.getElementById("myNav").style.visibility = "visible";
document.getElementById("myNav").style.opacity = "1";
document.getElementById("nav-icon3").attribute("onclick","closeNav()");
}
This function work fine with visibility and opacity but changing onclick function is not working. Any ideas?
Page: http://test.advermedia.pl/
Firstly, it's setAttribute(), not attribute(). Secondly, that's pretty moot anyway as using event attributes, let alone dynamically changing them at runtime, is a really bad idea. Use a single unobtrusive event handler instead:
<div id="nav-icon3">Toggle nav</div>
document.getElementById("nav-icon3").addEventListener('click', function() {
var nav = document.getElementById("myNav");
nav.style.visibility = nav.style.visibility == 'visible' ? 'hidden' : 'visible';
nav.style.opacity = nav.style.opacity == '1' ? '0' : '1';
});
Or alternatively, as you've tagged jQuery:
$('#nav-icon3').click(function() {
$('#myNav').toggle();
});
You have to set that attribute. Please try with the following:
document.getElementById("nav-icon3").setAttribute("onclick", "closeNav()");

Javascript click event requires double clicks

I have a simple HTML-CSS-JavaScript page with an event listener on a button to toggle a div.
However, all is working but the animation function takes two clicks first time to work, although i consoled the click event to prove that the button listens to the first click too.
i tried to wrap into window.onload but same thing.
note: i want to use pure javascript only.
thank you
this pic shows the first click (it says "clicked" in the console):
this pic shows the second click (animation took place):
Here is my code:
var showDivButton = document.getElementById('showDivButton');
var info = document.getElementById('info');
showDivButton.addEventListener('click', animation) ;
// animation func
function animation () {
console.log('Clicked!');
if (info.style.display === 'none'){
info.style.display = 'inline-block';
showDivButton.style.background = 'green';
} else {
info.style.display = 'none';
showDivButton.style.background = 'gray';
}
}
Look at My Plunker Here please. Thank you in advance.
Try to revise your function block as follow:
function animation () {
console.log('Clicked!');
if (info.style.display == '' || info.style.display == 'none'){
info.style.display = 'inline-block';
showDivButton.style.background = 'green';
} else {
info.style.display = 'none';
showDivButton.style.background = 'gray';
}
}
info.style.display is '' on initial
Because info.style.display refers to the style attribute of your div, not the computed Style, so on the first click, this is not set.
You may want to look at getComputedStyle, but i would advise switching class instead of directly modifying style.

function toggle - open all items

guys
I have a following HTML code with wrap (notice-wrap):
<div class="notice-title">
Title
</div>
<div class="notice-content">
Content text
</div>
<div class="notice-toggle" value="Hide" onclick="toggle()">
<img src="../img/icon_rollout.png">
</div>
And Toggle Script
function toggle() {
var newStatus = $('.notice-toggle').val() === "Hide" ? "Show" : "Hide";
$('.notice-toggle').val(newStatus);
if (newStatus == "Show") {
$("div.notice-content").css('overflow','hidden');
$("div.notice-content").css('height','80px');
$("div.notice-wrap").css('height','187px');
}
else {
$("div.notice-content").css('overflow','visible');
$("div.notice-content").css('height','100%');
$("div.notice-wrap").css('height','100%');
}
}
When i'm clicking on the toggle, open once all the items. How to make the opening only that element which i choose?
P.S. I also use Angular
Thanks in advance!
Maybe you can just change this:
function toggle() {
var newStatus = $('.notice-toggle').val() === "Hide" ? "Show" : "Hide";
$('.notice-toggle').val(newStatus);
if (newStatus == "Show") {
$("div.notice-content").css('overflow','hidden');
$("div.notice-content").css('height','80px');
$("div.notice-wrap").css('height','187px');
}
else {
$("div.notice-content").css('overflow','visible');
$("div.notice-content").css('height','100%');
$("div.notice-wrap").css('height','100%');
}
}
to:
function toggle() {
var noticeToggleElement = $(this);
var newStatus = noticeToggleElement.val() === "Hide" ? "Show" : "Hide";
noticeToggleElement.val(newStatus);
if (newStatus == "Show") {
noticeToggleElement.css('overflow','hidden');
noticeToggleElement.css('height','80px');
$("div.notice-wrap").css('height','187px');
}
else {
noticeToggleElement.css('overflow','visible');
noticeToggleElement.css('height','100%');
$("div.notice-wrap").css('height','100%');
}
}
As you should have the context of the element you toggle on with the mouse click.
As you're using jQuery, should be better if you remove the onclick from the HTML tag and make the bind in your javascript code, on a function that is executed on document ready:
$(function(){
$('div.notice-content').click(toggle);
})
But this is just a plus.
What you should do first is move that styling from js to css,
and have additional variations of your classes, for example:
.notice-title--toggled {
...
}
.notice-content--toggled {
...
}
.notice-toggle--toggled {
...
}
Now you have good separation of concerns, and your toggle function could just toggle classes for those elements.
Also you should put this toggle click handler on document ready, so final result would be:
$(function) {
$('.notice-toggle').click(function() {
$('.notice-title').toggleClass('notice-title--toggled');
$('.notice-content').toggleClass('notice-content--toggled');
$('.notice-toggle').toggleClass('notice-toggle--toggled');
});
}

IE click event span not triggered

I'm having this webpage
http://pocolocoadventures.be/reizen/
And it should filter (with isotope.js) the travelboxes on the page.It does in safari, chrome, firefox, opera, .. but in IE, the filter doesn't work. Even worse, JS doesn't react at all at a click event on te span.
This is the piece of js
// Travel Isotope
var container = $('#travel-wrap');
container.isotope({
animationEngine : 'best-available',
itemSelector: '.travel-box ',
animationOptions : {
duration : 200,
queue : false
},
});
$(".filters span").click(function(){
var elfilters = $(this).parents().eq(1);
if( (elfilters.attr("id") == "alleReizen") && elfilters.hasClass("non-active") )
{
$(".label").each(function(){
inActive( $(this) );
});
setActive(elfilters);
}
else{
//set label alleReizen inactive
inActive( $("#alleReizen") );
if( elfilters.hasClass("non-active") ){
setActive(elfilters);
}
else{
inActive(elfilters);
}
}
checkFilter();
var filters=[];
$(".search.filters").children().each(function(){
var filter = $(this).children().children().attr("data-filter");
if( $(this).hasClass("non-active") ){
filters = jQuery.grep(filters, function(value){
return value != filter;
});
}
else{
if(jQuery.inArray(filter,filters) == -1){
filters.push(filter);
}
}
});
filters = filters.join("");
filterItems(filters);
});
function filterItems(filters){
console.log("filter items with filters:" + filters);
container.isotope({
filter : filters,
}, function noResultsCheck(){
var numItems = $('.travel-box:not(.isotope-hidden)').length;
if (numItems == 0) {
$("#no-results").fadeIn();
$("#no-results").css("display", "block");
}
else{
$("#no-results").fadeOut();
$("#no-results").css("display", "none");
}
});
}
function setActive(el){
el.removeClass("non-active");
var span = el.find('i');
span.removeClass("fa-check-circle-o").addClass("fa-ban");
}
function inActive(el){
el.addClass("non-active");
var span = el.find('i');
span.removeClass("fa-ban").addClass("fa-check-circle-o")
}
function checkFilter(){
var filterdivs = $('.filters span').parent().parent();
if( filterdivs.not('.non-active').length == 0 ){
setActive( $("#alleReizen") );
}
var filterLabels = $(".filters .label");
if( filterLabels.not('.non-active').length == 0){
setActive( $("#alleReizen") );
}
}
function noResultsCheck() {
var numItems = $('.item:not(.isotope-hidden)').length;
if (numItems == 0) {
//do something here, like turn on a div, or insert a msg with jQuery's .html() function
alert("There are no results");
}
}
Probably something small and stupid; but I can't find it..
Thanks in advance!
On your website you've build the buttons like this:
<button>
<span>
</span>
</button>
Now the button element is designed to be a button. It differs from the input button. In the latter you'd set the caption using value. In the button element you set it as a text node. The button element can contain elements like a span. The spec isn't very clear about whether or not you should have event handlers on the children of the button element. It's a browser developers interpretation of allowing it or not.
This problem has been posted here before (a few times)
span inside button, is not clickable in ff
Missing click event for <span> inside <button> element on firefox
It seems that Firefox is allowing it, based upon your findings. IE isn't. So to be on the safe side: use the button the way it was intended.
Wrap the button inside a span (not really logical)
Put the click handler on the button.
$(".filters button").click(...);
played around in the console a bit, and this seemed to work well.
$(".filters").on('click', 'span', function(){
// foo here
console.log('foo');
});
Maybe the filters are manipulated by one of your js files after page load?
.on will allow you to select a container which listens on changes that happen inside it, passing the element you want the actual action to work on.
If it's ok for you, I'd suggest to use the <button> element, instead of the <span>.
Let me know if that works for you.

Categories