Removing CSS class not yielding expected results with javascript - javascript

I have a web site that exists on one page: index.html. There is a lot of content on the site (that appears to be on many "pages") but via javascript and CSS, all the info is contained on index.html.
So there exists a "home" position and an "inside" position (like a home page and inside page), and I need some links to behave differently when the user is on an inside page vs the home page. So the way I have it set up, once an "inside" link is clicked, I remove a class from a div that I think should cause the links within that div to behave differently. But they are not behaving as I expect.
The page, very dumbed down for this example, is here:
http://littleduck.com/ns_sample/index.html
On this example, there is just the home page and the "Services" page. You can link back and forth between them.
If you mouseover those grey links on the left (which are called "balloons" in the code), you will see that they have a hover color, and a popup graphic appears. I ONLY want this to happen when the page is in the "home" position. I have a class called "popup_yes" that allows this hover/popup action to happen. It appears when index.html is loaded, and if I remove it or change its name in the code, the hover/popup does not work. So I know that class is doing something. Now, I REMOVE that class when "Services" is clicked. I can see by inspecting the element in Chrome that "popup_yes" DOES in fact get removed. HOWEVER ... the hover/popup action still happens when you mouseover the balloons.
And when I inspect the element, even though you can see in the code that "popup_yes" is gone, it is still being utilized by Chrome. Here is a screenshot of what Inspect Element looks like on the "home" and "inside" pages:
http://i.stack.imgur.com/p1ZP7.jpg
So, please tell me where my brain is derailing. How can I get the hover/popup action to NOT WORK when I'm on the "Services" page? Thank you incredibly much for any help you can provide.

The issue is in your mouseover/out code
$(".popup_yes .balloon_1").mouseover(function() {
$("#popup_1").show(400);
$(".balloon_1").addClass("hover");
});
When the page loads, the mouseover event is binding to that span, so that action is already established, if you add the check in the function
$(".popup_yes .balloon_1").mouseover(function() {
if ($('#balloons').hasClass('popup_yes') ){ //<--here
$("#popup_1").show(400);
$(".balloon_1").addClass("hover");
}
});
it should work as expected

I have modified the javascript that you are using and could make it work. Here are the changes that i made.
First of all when u removed the class when the services page is clicked I specified the class to be removed.
$('#balloons').removeClass("popup_yes");
After this when you click back the Home page the class has to be added back so i included this line after you animate the $('#buttons') div.
$("#balloons").addClass("popup_yes");
Now comes the changing of the hover effect on each of the balloons. I'll show the change I did to the first balloon element you can reproduce the same for the others.
$(".balloon_1").mouseover(function() {
if($(this).closest('#balloons').attr("class")=="popup_yes"){
$("#popup_1").show(400);
$(".balloon_1").addClass("hover");
}
});
$(".balloon_1").mouseout(function() {
if($(this).closest('#balloons').attr("class")=="popup_yes"){
$("#popup_1").hide(400);
$(".balloon_1").removeClass("hover");
}
});
What I modified is instead of checking for both the class for hovering I just checked the balloon_1 class and then I made the effect only if the closest element to it with an id balloons has the class popup_yes.
I tried it in chrome. Hope it works well in other browsers as well.

Related

toggle divs so only one is open at a time, but be able to close them all as well javascript

I have these divs that I can toggle onclick to scale larger one at a time. It works perfectly except that once one is enlarged, one is always enlarged. I am using toggleOpen for this. I am looking to be able to make it so that it can do what it already does, but then onclick of the enlarged div have it go back to its original size without having to toggle with another div. In other words, I need a way to make the page go back to a state where all the divs are in original size. I have tried else statements to no avail as well as adding another function to remove class. I only want a js solution - no jquery or anything else please. Here is the JS portion of it.
const event = document.querySelectorAll('.eventsBorder')
function toggleOpen() {
let opened = document.getElementsByClassName('large')[0];
if(opened!=undefined)
opened.classList.toggle('large');
this.classList.toggle('large');
}
event.forEach(eventsBorder => eventsBorder.addEventListener('click', toggleOpen));
Here is my codepen
Thanks in advance for any help!
The opened variable gives you back a list of all the HTML elements which have the large class, and when you click again on an already enlarged div that automatically satisfied this criteria. So, what happens is that if you click on the same item twice, your toggleOpen function first removes the large class from that item and then adds it again because of the following line in your code-
this.classList.toggle('large');
The best way to achieve what you want would be to make sure that in addition to opened not being undefined, you should also make sure opened is not the same item as the one you clicked on. You can accomplish that using-
if(opened != undefined && opened != this)
Here is a link to the updated codepen to see it in action.
So it looks like you are using querySelectorAll to select all elements with the class "large", then you're toggling the class. If you toggle the class, it will no longer be a part of that query selection, as it no longer has that class applied, so it will not be able to remove it.
const event = document.querySelectorAll('.eventsBorder')
event.forEach(eventsBorder =>
eventsBorder.onclick = () =>
eventsBorder.classList.toggle('large'));
This seems to accomplish what you'd like.

High contrast page, jQuery toggle class, if class is there and changing url put this class on element

So I'm trying to make a button on page that changes it to high contrast page on click, it is working already, but if I go to different link on this page this high contrast class is not there and I need to click my button again to have page in high contrast. This is not very useful. I'm trying to write some function, maybe if condition that if there is a class 'high contrast' on element and my url changes, this class will be still there on a new url. Is it even possible? Can someone help me?
And for changing class to 'high contrast' I'm using jQuery .togglelass(). Maybe I should use something different than this?
Wrote something like this for changing my page to high contrast, just changing classes where I need to put high contrast.
$('.change-contrast').click( function() {
$('.accessibility-icons span').toggleClass('high-contrast');
$('a').toggleClass('high-contrast');
$('.post-short').toggleClass('post-short-contrast');
$('.contact-page-container').toggleClass('contact-page-container-contrast');
$('.hours-container').toggleClass('hours-container-contrast');
$('.site').toggleClass('site-high-contrast');
$('.site-footer').toggleClass('site-info-contrast');
$('.footer-info').toggleClass('footer-info-contrast');
$('.bip').toggleClass('bip-contrast');
$('.form-wrapper').toggleClass('form-wrapper-contrast');
$('.menu-item').toggleClass('menu-item-contrast');
$('.header-carousel_title').toggleClass('header-carousel_title-contrast');
$('.logo-carousel').toggleClass('logo-carousel-contrast');
$('.home-title').toggleClass('home-title-contrast');
$('.hours-title').toggleClass('hours-title-contrast');
$('.page-main-title').toggleClass('page-main-title-contrast');
$('.gallery-title').toggleClass('gallery-title-contrast');
$('article').toggleClass('article-contrast');
$('.owl-item').toggleClass('owl-item-contrast');
$('.gallery-container').toggleClass('gallery-container-contrast');
$('.gallery-button').toggleClass('gallery-button-contrast');
$('.page-link-button').toggleClass('page-link-button-contrast');
$('.post-short_title').toggleClass('post-short_title-contrast');
$('.excerpt').toggleClass('excerpt-contrast');
})
This page is really colorful, so I had to change a lot in it.

How to pass an object in this case?

I have a page with a "left" div, that contains a menu, and a "right" div, which holds a content that changes, loaded using javascript as in:
document.getElementById("content").innerHTML='<object type="text/html" data="templates/login.htm"> </object>';
It works okay the first time I click a link on the left menu. Now, this new loaded content has also some inputs that should do the same thing. Only it seems that they can't see the "content" div as having this id, or something else. How do I accomplish this? (fixed menu on left, and on the right we would have changing content - which would have several inputs as well). Thanks.
ADDENDUM - The contents of the js function is just the line pasted above. Probably the flow will clarify?
Step 1 - load menu on left and initial content on right. No user intervention
Step 2 - click "login" on left menu. Login page (separate html) loaded on right side. All fine.
Step 3 - click "cancel" in newly loaded login menu on right side... nothing happens, despite that button having the exact same onclick that the left side menu had (the one used to load the login scren in step 2)
When tracing through parents of this "cancel" button, the trace never "saw" the div.
This was the output of "parent hunting"
object HTMLParagraphElement (button is in a )
object HTMLTableCellElement
object HTMLTableRowElement
object HTMLTableSectionElement
object HTMLTableElement (so far so good... this should be a table containing the button clicked)
object HTMLBodyElement (mmm shouldn't I have a div here?)
object HTMLhtmlElement
object HTMLDocument
null
(now... shouldn't I have a div between body and table elements?)
Seems the partial html loaded inside the div cannot see it?
If that code-sample is used in your project, the missing > might be the source of your troubles.
document.getElementById("content").innerHTML='<object type="text/html" data="templates/login.htm"></object>';
Okay...
Seems the loaded content can't intrinsically "see" the parent div or its id by default. The solution was to have:
parent.document.getElementById("content").innerHTML='<object type="text/html" data="templates/login.htm"></object>';
instead of
document.getElementById("content").innerHTML='<object type="text/html" data="templates/login.htm"></object>';

Expand/Collapse Text

The code below works fine with ONE Reveal/Hide Text process
<div class="reveal">Click Here to READ MORE...</div>
<div style="display:none;">
<div class="collapse" style="display:none;">Collapse Text</div>
However if this code is duplicated multiple times, the Collapse Text shows up and doesn't disappear and in fact conflicts with the Expand to reveal even more text instead of collapsing as it should.
In this http://jsfiddle.net/syEM3/4/ click on any of the Click Here to READ MORE...
Notice how the Collapse Text shows up at the bottom of the paragraphs and doesn't disappear. Click on the Collapse and it reveal more text.
How do I prevent this and getting to work as it should?
The two slideDown function calls are not specific to the .reveal and/or .collapse that you are currently doing. i.e.
$(".collapse").slideDown(100);
will find all the elements with the class .collapse on the page, and slide them down. irrespective of what element you just clicked.
I would change the slideDown call to be relavant to the element you just clicked i.e. something like this
$('.reveal').click(function() {
$(this).slideUp(100);
$(this).next().slideToggle();
$(this).next().next(".collapse").slideToggle(100);
});
in your code
$('.reveal').click(function() {
$(this).slideUp(100);
$(this).next().slideToggle();
$(".collapse").slideDown(100);
});
$('.collapse').click(function() {
$(this).slideUp(100);
$(this).prev().slideToggle();
$(".reveal").slideDown(100);
});
this two rows doesn’t do what you want as they act on all elements of the specified class
$(".reveal").slideDown(100);
$(".collapse").slideDown(100);
When you do $(".collapse").slideDown(100);, jQuery runs slideDown on everything with the .collapse class, not just the one that's related to your current this. To fix this, refer to the collapse based on its location to $(this).
Do do this, use something like $(this).siblings(".collapse").slideDown(100);
Note that this particular selector will only work if you enclose each text block in its own div. With each text element in its own div, like you have it now, .siblings(".collapse"), which selects all the siblings of $(this) with the collapse class, will still select both of the collapse elements.
Okay, I think you should take a different approach to your problem.
See, jQuery basically has two purposes:
Selecting one or more DOM elements from your HTML page
manipulate the selected elements in some way
This can be repeated multiple times, since jQuery functions are chainable (this means you can call function after function after function...).
If I understood your problem correctly, you are trying to build a list of blog posts and only display teasers of them.
After the user clicks the "read more" button, the complete article gets expanded.
Keep in mind: jQuery selects your elements very much like CSS would do. This makes it extremely easy to
come up with a query for certain elements, but you need to structure your HTML in a good way, like
you would do for formatting reasons.
So I suggest you should use this basic markup for each of your articles (heads up, HTML5 at work!):
<article class="article">
<section class="teaser">
Hey, I am a incredible teaser text! I just introduce you to the article.
</section>
<section class="full">
I am the articles body text. You should not see me initially.
</section>
</article>
You can replace the article and section elements with div elements if you like to.
And here is the CSS for this markup:
/* In case you want to display multiple articles underneath, separate them a bit */
.article{
margin-bottom: 50px;
}
/* we want the teaser to stand out a bit, so we format it bold */
.teaser{
font-weight: bold;
}
/* The article body should be a bit separated from the teaser */
.full{
padding-top: 10px;
}
/* This class is used to hide elements */
.hidden{
display: none;
}
The way we created the markup and CSS allows us to put multiple articles underneath.
Okay, you may have noticed: I completely omitted any "read more" or "collapse" buttons. This is done by intention.
If somebody visits the blog site with javascript disabled (maybe a search engine, or a old mobile which doesn't support JS or whatever),
the logic would be broken. Also, many text-snippets like "read more" and "collapse" are not relevant if they don't actually do anything and are not part of the article.
Initially, no article body is hidden, since we didn't apply the hidden css class anywhere. If we would
have embedded it in the HTML and someone really has no JavaScript, he would be unable to read anything.
Adding some jQuery magic
At the bottom of the page, we are embedding the jQuery library from the google CDN.
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
This is a best practice and will normally speed up your page loading time. Since MANY websites are embedding
jQuery through this URL, chances are high that its already in the visitors browser cache and doesn't have
to be downloaded another time.
Notice that the http: at the beginning of the URL is omitted. This causes browsers to use the pages current protocol,
may it be http or https. If you would try and embed the jQuery lib via http protocol on a https website, some browsers will refuse to download the file from a unsecure connection.
After you included jQuery into the page, we are going to add our logic into a script tag. Normally we would
save the logic into a separate file (again caching and what not all), but this time a script block will do fine.
Finally some JavaScript
At first, we want to hide all elements with the css-class full, since only teasers should remain displayed. This is very easy with jQuery:
$('.full').hide();
The beginning of the script $('.full') tells jQuery: I need all elements with the CSS-class full. Then we call a function on that result, namingly hide() which purpose should be clear.
Okay, in the next step, we want to add some "read more" buttons, next to every teaser. Thats an easy task, too:
$('.teaser').after('<button class="more">Read more</button>');
We now select every element with the css-class teaser and append some HTML code after() each element - a button with the css-class more.
In the next step, we tell jQuery to observe clicks on every one of this freshly created buttons. When a user has clicked, we want to expand the next element with the css-class full after the clicked button.
$('.more').on('click', function(){
//"this" is a reference to the button element!
$(this).slideUp().next('.full').slideDown();
});
Phew, what did we do here?
First, we told jQuery that we wanted to manipulate this, which is a reference to the clicked button. Then we told
jQuery to hide that button (since its not needed anymore) slowly with slideUp().
We immediately continued telling jQuery what to do: Now take the next() element (with the css-class full) and make it visible by sliding it down with slideDown().
Thats the power of jQuerys chaining!
Hiding again
But wait, you wanted to be able to collapse the articles again! So we need a "collapse" button, too and
some more JavaScript:
$('.full').append('<button class="collapse">Collapse text</button>');
Note: we didn't use the after() function to add this button, but the append() function to place the button
INSIDE every element with the css-class full, rather than next to it. This is because we want the
collapse buttons to be hidden with the full texts, too.
Now we need to have some action when the user clicks one of those buttons, too:
$('.collapse').on('click', function(){
$(this).parent().slideUp().prev('.more').slideDown();
});
Now, this was easy: We start with the button element, move the focus to its parent() (which is the element that contains the full text) and tell jQuery to hide that element by sliding it up with slideUp().
Then we move the focus from the full-text container to its previous element with the css-class more, which is its expanding button that has been hidden when expanding the text. We slowly show that button again by calling slideDown().
Thats it :)
I've uploaded my example on jsBin.

No title creation on first view

I bounced into a problem when I was trying to create a title on the first view I created within my application.
At first, i hopped over all the push actions I had within my application and applied after this create.view screen a title as refered in the code under here
this.StembureauView = Ext.create('UtrechtStem.view.Stembureaulijst_View', {
title: 'Stembureaulijst'
});
this.getMainnav().push(this.StembureauView);
this works fine, and I seem to have no problem with it. However, the first screen, so my main view, as loaded first view, doesnt accept the title statement.
Ext.create('UtrechtStem.view.MainNav', {
fullscreen: true,
title:'stembureau zoeker'
});
if i add nicely behind the fullscreen statement a title statement, it wont accept it. (this is done outside sencha architect, cause appearantly i cant modify it within sencha artchitect) It just shows blank. I tried removing the toolbar, to see if that was the mistake, but it didnt. I tried addding manualyy outside Sench
Does anybody have a clue why it wont accept the title statement there and to see if there is a work arround?
guess your class UtrechtStem.view.MainNav is inherited from the Ext.navigation.View. If yes, you can not set its title direct. Instead it borrow the active child's title.
Have a look at the doc site
Cheers, Oleg

Categories