I'm having a bit of trouble figuring out what Crazy Egg used for their F.A.Q.s. I would like to implement the same thing exactly (where the questions slide down upon clicked - and show a blue box for the current active question).
Ex) https://www.crazyegg.com/help
I went through the code and I see it has javascript events, but I am unable to script this myself. Is there a plugin I can use for this behavior? Some form of showing/hiding divs I presume?
You should be able to code it yourself with jquery. Just look into very basic jQuery tutorial that goes over selectors, hiding and showing and click events. All you do is assign an id to each header that you click on, and then on click you hide all content and show the one clicked. You should read some stuff online, try something, and then come back with code and ask questions.
This effect can be achieved easily with jQuery's slideToggle function:
HTML:
<span class="faq">This is a FAQ question...</span>
<div class="answer" style="display: none;">
And this is the answer.
</div>
JavaScript:
$(document).ready(function(){
$(".faq").click(function(){
$(this).next("div.answer").slideToggle();
});
});
JSFiddle: http://jsfiddle.net/ySahP/
Related
I've tried looking at the documentation for addThis and it seems like it's being updated or something because all the links these help posts link to don't even mention the API bits they describe.
Anyway,
I just need to be able to programmatically click an addThis button. However, I can't seem to do it via console before I implement it in my code.
I read that this has something to do with how the addThis listeners are added only when the document is done loading. This doesn't make sense to me because even if I manually try to trigger a click in console, it still does nothing but return the html of the link I'm trying to trigger. For example:
`$('.at-svc-facebook').click();`
OR `$('.at-svc-facebook').trigger('click');`
OR `$('.at-share-btn.at-svc-facebook').click();`
I mean, by the time I open console the dom is ready. So then what else might be preventing me from clicking these buttons via jQuery?
I've tried adding a listener to an element myself, and then clicking it programmatically, and it works. So something is different about the way addThis listens for a click. I may update this question with something I find after inspecting their js.
===================
This is what is in the DOM which addThis populates and listens to:
<div class="addthis_sharing_toolbox"></div>
This is what ^ that code is turned in to from addThis:
<div class="addthis_sharing_toolbox" data-url="http://localhost:8001/halloween/" data-title="33 Halloween Costume Ideas">
<div id="atstbx" class="at-share-tbx-element addthis_32x32_style addthis-smartlayers addthis-animated at4-show">
<a class="at-share-btn at-svc-facebook">
<span class="at4-icon aticon-facebook" title="Facebook"></span>
</a>
<a class="at-share-btn at-svc-twitter">
<span class="at4-icon aticon-twitter" title="Twitter"></span>
</a>
<a class="at-share-btn at-svc-google_plusone_share">
<span class="at4-icon aticon-google_plusone_share" title="Google+"></span>
</a>
</div>
</div>
Now, you can see the jQuery I'm using to click the buttons and the code it's trying to click.
The issue is that addThis was putting a second link with the exact same class in the DOM for some reason. It generates some HTML and appends it to body.
So what I needed to do to select the button and trigger a click was to specify the 2nd element in the array of elements and call click on that one. Like so:
$('.at-svc-facebook')[1].click();
Now, the next problem I face is chrome block a programatic popup, but that's beyond the scope of this question. :(
change the
var class_name = $(this)[0].className;
as below,
var class_name = $(this)[0].attr('class');
and it'll work. :)
I am adding a series of divs with dragdealerjs functionality. The problem is I need to be able to tap and hold the ".handle" div inorder to expose a slider/drawer below it. I have simplified my code down to get to the root of the problem. I am appending the ".innerGroup" div to the ".groups" div.
HTML:
<div class="groups scroll">
<div class="innerGroup">
<div id="demo-simple-slider1" class="dragdealer">
<div class="igIcon1"></div>
<div class="handle"></div>
</div>
</div>
</div>
Javascript:
This code doesn't work,
$(document).on('taphold', '.handle', function() {
alert('Tapped');
});
This code does work though,
$(document).on('click', '.handle', function() {
alert('Tapped');
});
I know there are several other similar answers to this one here but I fear that drag dealer may be complicating the issue. I also think the problem is related to adding the innerGroup after the DOM has loaded. Thanks in advance.
The error here is that drag dealer actually takes control of the taphold event. To work around you need to take a two stage check with a 750 millisecond time out (same as a standard taphold) and put the distance the slider can move as .49-.51 (or something similar ). If anyone wants the code leave a comment here and ill post what I come up with.
Happy coding
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.
In YouTube when you click the top right button of your profile it drops a whole section on the top, moving all the content down, when you click it again, the section disappears, moving all the content back up. How do they do that?
P.S. I'm new to Javascript, so I don't even know how to search docs for this particular solution. Please be specific in description.
Thanks!
http://jsfiddle.net/qT3Em/
unless you want to write the animation yourself (not recomended)
you shuld use a libary witch comes with animations like jquery http://www.jquery.com
it commes with a function .toggle http://api.jquery.com/toggle/
that i used in the example belove
<button>A button</button>
<div style="display:none;">
<h1>Hidden Content</h1>
</div>
<h1>Lower Content</h1>
$(function() {
$("button").click(function() {
$("div").toggle("slow");
});
});
that will give you the effect you want
In trying to understand javascript best practices, I'm attempting to recreate a piece of inline javascript by adding an event listener from an external javascript file.
The inline code works fine and looks like this:
<p id="inline" align="left">
This is a body paragraph which changes alignment
when a user clicks on a link below
</p>
<p>
Align Right
</p>
Concerning my problem, the important thing to note here is that return false; prevents the page from reloading (I'm not actually sure why, and wouldn't mind finding out, especially if it relates to the solution to my problem...). This is what I want. I don't need the page to reload to move the text to the right.
However, I have no idea what the best way to keep the page from reloading is when my javascript is in an external file. Here's what my first attempt looks like. I started with html that looks like this:
<p id="external" align="left">
This is a body paragraph which changes alignment
when a user clicks on a link below. It uses an
external .js file.
</p>
<p>
Align Right
</p>
And javascript that looks like this:
function alignListener () {
document.getElementById('external').setAttribute('align', 'right');
}
function installListeners () {
var aRight = document.getElementById('aRight');
aright.addEventListener('click', alignListener, false);
}
This almost works, but not at all how I would expect. When I click on the 'Align Right' link, the text briefly aligns right, but then, I follow the link to the current page, which resets the alignment back to the left.
I found a way to sort of fix that problem, by using <a href="#" ... instead of <a href="" .... While this doesn't reload the page (so the text stays aligned), it does take me to the top, which isn't really what I want. I'd like a solution similar to the return false; that works with the inline javascript. Is there a simple way to do this? Or am I doing it wrong completely?
I highly recommend the mozilla developer network for most of these types of answers. It's easy to read and will help you understand JavaScript and the DOM. (JavaScript is good!, DOM is awkward...)
Specifically, for events: https://developer.mozilla.org/en/DOM/event
In general, https://developer.mozilla.org/
There are a few ways to stop events, preventDefault(), stopPropagation(), return false;, or use a JavaScript framework as suggested above. jQuery is good, there are many many others out there (YUI, Dojo, MooTools, etc.), and they all endeavor to make your JavaScript more compatible with different browsers.
Use <button> instead of <a> tag.
That helped me.
You can use:
function event(e){
var e=window.event||e;
//do stuff
if(e.preventDefault){e.preventDefault()}else{e.returnValue=false}
}
Note that this doesn't need to go on a new function: .addEventListener("click",function(e){/*the above function*/})
Cross-compatible event listener:
if(element.addEventListener){
element.addEventListener(eventName, function, false);
}else{
element.attachEvent("on"+eventName, function);
}