I'm trying to loop through each element of a class in javascript and display it after pausing a certain amount of seconds. I have the logic down, but because jQuery is calling the class, and not the unique instance of this, it displays everything all at once:
jQuery( document ).ready(function ($) {
$( ".fadein" ).hide();
$( ".fadein" ).each(function (index) {
$( "." + this.className ).delay(index * 800).fadeIn( "slow" );
});
});
The each loop is already designed to hand you the elements one at a time. The target element is passed as 'this', so just fadeIn the current element in your 'loop' instead of fetching all of them each time.
// Replace this
$( "." + this.className ).delay(index * 800).fadeIn( "slow" );
// with this
$( this ).delay(index * 800).fadeIn( "slow" );
// result:
$( ".fadein" ).each(function (index) {
$( this ).delay(index * 800).fadeIn( "slow" );
});
Related
Basically I want to slide down a element, then when the button is hit again I want it to slide up, empty the div, then slide down with the new results. I'v been trying to figure out how to do this for so long and I cant seem to get it working with jquery.
$(".search").on("click",function(){
$('.results').slideUp(500).empty().append("<p>Results</p>").hide().slideDown(500)
});
I understand this is kind of specific to my project kind of but I do feel others might find this useful
I'm not sure what exactly your problem is, but I think the slideUp animation is not shown in your example.
The slideUp method takes a second argument, which is the function callback. It is called when the slideUp action is finished. If you do the rest of your actions in this callback function, is guaranteed to be performed after the slideUp.
jQuery('#testbutton').on('click',function() {
$('#testlist').slideUp(500, function() {
$('#testlist').empty().append("<li>this is a test</li>").slideDown(500);
});
});
You can find a fully working example here:
https://jsfiddle.net/dxyybwyh/5/
I want to slide down a element, then when the button is hit again I
want it to slide up, empty the div, then slide down with the new
results.
It seems simple enough to me
let me know if you need anything more
$('#myButton').click(function () {
if ( $( ".myDiv" ).is( ":hidden" ) ) {
//show the div
$( ".myDiv" ).slideDown( "slow" );
//add content
$( ".myDiv" ).html("New Content")
} else {
//hide the div
$( ".myDiv" ).slideUp( "slow" );
//clear content
$( ".myDiv" ).html("");
}
});
http://codepen.io/Rohithzr/pen/jqmGXg
Updated the pen with append ability and more readability
$('#myButton').click(function () {
if ( $( ".myDiv" ).is( ":hidden" ) ) {
show();
} else {
hide();
clearContent();
appendContent("New Content");
}
});
function clearContent(){
//clear content
$( ".myDiv" ).html("");
}
function appendContent(content){
$( ".myDiv" ).html($( ".myDiv" ).html()+content);
}
function hide(){
//hide the div
$( ".myDiv" ).slideUp( "slow" );
}
function show(){
//show the div
$( ".myDiv" ).slideDown( "slow" );
}
My question concerns the swipe event on a mobile device (I'm using a Nexus 7) with Chrome. I am working off the Jquery Mobile 1.4.2 demo which can be found here:
http://demos.jquerymobile.com/1.4.2/swipe-page/
I'll ask my question and copy the sample javascript below. I can get everything to work, both on my laptop (using Chrome) and on my tablet (using Firefox), but the swipe works maybe one out of ten times in Chrome with my tablet. Any advice? Thanks!
// Pagecreate will fire for each of the pages in this demo
// but we only need to bind once so we use "one()"
$( document ).one( "pagecreate", ".demo-page", function() {
// Initialize the external persistent header and footer
$( "#header" ).toolbar({ theme: "b" });
$( "#footer" ).toolbar({ theme: "b" });
// Handler for navigating to the next page
function navnext( next ) {
$( ":mobile-pagecontainer" ).pagecontainer( "change", next + ".html", {
transition: "slide"
});
}
// Handler for navigating to the previous page
function navprev( prev ) {
$( ":mobile-pagecontainer" ).pagecontainer( "change", prev + ".html", {
transition: "slide",
reverse: true
});
}
// Navigate to the next page on swipeleft
$( document ).on( "swipeleft", ".ui-page", function( event ) {
// Get the filename of the next page. We stored that in the data-next
// attribute in the original markup.
var next = $( this ).jqmData( "next" );
// Check if there is a next page and
// swipes may also happen when the user highlights text, so ignore those.
// We're only interested in swipes on the page.
if ( next && ( event.target === $( this )[ 0 ] ) ) {
navnext( next );
}
});
// Navigate to the next page when the "next" button in the footer is clicked
$( document ).on( "click", ".next", function() {
var next = $( ".ui-page-active" ).jqmData( "next" );
// Check if there is a next page
if ( next ) {
navnext( next );
}
});
// The same for the navigating to the previous page
$( document ).on( "swiperight", ".ui-page", function( event ) {
var prev = $( this ).jqmData( "prev" );
if ( prev && ( event.target === $( this )[ 0 ] ) ) {
navprev( prev );
}
});
$( document ).on( "click", ".prev", function() {
var prev = $( ".ui-page-active" ).jqmData( "prev" );
if ( prev ) {
navprev( prev );
}
});
});
$( document ).on( "pageshow", ".demo-page", function() {
var thePage = $( this ),
title = thePage.jqmData( "title" ),
next = thePage.jqmData( "next" ),
prev = thePage.jqmData( "prev" );
// Point the "Trivia" button to the popup for the current page.
$( "#trivia-button" ).attr( "href", "#" + thePage.find( ".trivia" ).attr( "id" ) );
// We use the same header on each page
// so we have to update the title
$( "#header h1" ).text( title );
// Prefetch the next page
// We added data-dom-cache="true" to the page so it won't be deleted
// so there is no need to prefetch it
if ( next ) {
$( ":mobile-pagecontainer" ).pagecontainer( "load", next + ".html" );
}
// We disable the next or previous buttons in the footer
// if there is no next or previous page
// We use the same footer on each page
// so first we remove the disabled class if it is there
$( ".next.ui-state-disabled, .prev.ui-state-disabled" ).removeClass( "ui-state-disabled" );
if ( ! next ) {
$( ".next" ).addClass( "ui-state-disabled" );
}
if ( ! prev ) {
$( ".prev" ).addClass( "ui-state-disabled" );
}
});
I've done the same experiment and I've observed similar results with my tablet (Nexus 7 - Google Chrome).
You should not use heavy frameworks like jQueryMobile if you are going to create a web app or a mobile website because even if these tools make your life easier at the end the result, especially on Android devices, will be slow and sluggish.
In other words you should create your own .css and .js.
If you need to manipulate the DOM very often you should also look for alternatives to jQuery.
I suggest that you use Zepto.js.
In the end, I decided to use the jQuery touchSwipe plugin and write my own code, works fine in different browsers and across devices. Some of this may not make sense without the HTML, but essentially I determine the direction of the swipe based on the variable that is passed into the method. Then, by getting various attributes and class names, I am turning on and off the display of the various divs that have previously loaded the JSON into them from another method. The way I do that is through substrings, where the last digit of the id is a number. If anyone has any comments about how this code could be more efficient, I'd be happy to hear your thoughts. Cheers.
function swipeLiterary() {
$("#read").swipe({
swipe:function(event, direction, distance, duration, fingerCount) {
switch (direction) {
case 'left':
var thisPage = $('.display').attr('id');
var nextPageNum = parseInt(thisPage.substring(8)) + 1;
var nextPage = thisPage.substring(0,8) + nextPageNum;
if (nextPageNum > 9) {
break
}
$('#' + thisPage).removeClass('display').addClass('nodisplay');
$('#' + nextPage).removeClass('nodisplay').addClass('display');
console.log(nextPage);
break;
case 'right':
var thisPage = $('.display').attr('id');
var prevPageNum = parseInt(thisPage.substring(8)) - 1;
var prevPage = thisPage.substring(0,8) + prevPageNum;
if (prevPageNum < 0){
break;
}
$('#' + thisPage).removeClass('display').addClass('nodisplay');
$('#' + prevPage).removeClass('nodisplay').addClass('display');
console.log(prevPage);
break;
case 'up':
console.log('up');
break;
}
//$(this).text("You swiped " + direction );
//console.log(this);
}
});
}
So, I have this function in jQuery:
$(function(){
$( ".unfocused" ).click(function ClickHeader () {
$( this ).addClass( "focused" );
$( this ).removeClass( "unfocused" );
$(".header").not(this).addClass( "unfocused" );
$(".header").not(this).removeClass( "focused" );
});
});
It works perfectly when a header is clicked the first time, but when I try to click another unfocused header, the function doesn't work anymore. Is it because it runs on document .ready?
Thanks for your help!
Change it like this:
$( document ).on("click", ".unfocused", function() {
$( this ).addClass( "focused" );
$( this ).removeClass( "unfocused" );
$(".header").not(this).addClass( "unfocused" );
$(".header").not(this).removeClass( "focused" );
});
This basically registers the event on the document. When you click a header, the event bubbles up to the document. There, the given selector is validated and the function is executed if needed.
Here is a jsfiddle using the delegate operation for handling the event like you need.
http://jsfiddle.net/MN9Zt/2/
$("body").delegate(".unfocused", "click", function() {
$(this).addClass("focused");
$(this).removeClass("unfocused");
$(".header").not(this).addClass("unfocused");
$(".header").not(this).removeClass("focused");
});
I have a large block of HTML that needs to be replaced, which includes fadeOut/fadeIn transitions. I can't figure out how to add the HTML to the page (hidden) without wrapping it in a div.
$.get('/ajax', function(newHtml){
var $newEvent = $('<div class="new-event" />').hide().html(newHtml);
$('#content .event').fadeOut('slow', function(){
$(this).remove(); //old event
$newEvent.appendTo('#content').fadeIn('slow').removeClass('new-event'); //then remove the wrapper div that I didnt need in the first place
});
});
What is the best way to do this while utilizing best practices for performance?
Solution:
For some reason, I thought that creating a new element like this: $(newHtml) was less efficient (bad performance) than html(newHtml). But apparently, they are the same as far as performance goes (I have no data to back this up other than my own observations).
So the following code is just as efficient as the previous:
$.get('/ajax', function(newHtml){
var $newEvent = $(newHtml).hide();
$('#content .event').fadeOut('slow', function(){
$(this).remove(); //old event
$newEvent.appendTo('#content').fadeIn('slow');
});
});
When adding the code to the page, have top level elements all be hidden
<div style="display:none;">...</div>
When fadeIn is called jQuery automatically removes it for you.
If you can't modify the returned html just do it this way then,
$(newHtml).hide().appendTo('#content');
That will hide it before being added to the DOM.
How about something like
$('#content .event').fadeOut('slow', function()
{
$(this).html(newHtml).fadeIn('slow');
});
Why you don't simply replace the content of .event instead of removing it and creating a new one?
$.get( '/ajax', function( newHtml )
{
$( '#content .event' ).fadeOut( 'slow', function ()
{
$( this ).html( newHtml ).fadeIn( 'slow' );
});
});
Edit
If you really need to remove the entire node, you can do this instead
$( this ).remove();
$( '<div class="new-event">' ).appendTo( $('#content') ).html( newHtml ).fadeIn( 'slow' );
You could just have it as a javascript string, and add it when you need.
var $newEvent = $(newHtml);
// and later on
$( '#content .event' ).fadeOut('slow', function ()
{
$(this).append($newEvent).fadeIn( 'slow' );
});
Apologies if this is an overly simple question, but my searches are getting me nowhere.
I have a jQuery function which produces an error on some of my pages which do not contain the #message input:
Error: jQuery("#message").val() is undefined
Line: 56
And my jQuery function:
function updateCountdown()
{
var $left = 255 - jQuery( '#message' ).val().length;
jQuery( '#countdown' ).text( $left + ' Characters Remaining' );
}
$( document ).ready( function()
{
updateCountdown();
$( '#message' ).change( updateCountdown );
$( '#message' ).keyup( updateCountdown );
});
So my question is, how do I use a conditional to remove the error message from pages without the #message input? I believe my problem is a basic lack of knowledge of how JavaScript works.
I wouldn't bother to perform an explicit test on the jQuery object returned from the selector — let jQuery do that for you!
$(function() {
$('#message').each(function() {
var $self = $(this);
$self.bind('change keyup', function updateCountdown() {
$('#countdown').text((255 - $self.val().length)) + ' characters remaining');
});
});
});
If '#message' doesn't match anything, then the .each( ... ) call won't do anything.
The only problem is with your init code.. after that it'll run fine. So do:
$( document ).ready( function()
{
$( '#message' ).change( updateCountdown ).keyup( updateCountdown ).keyup();
});
Note the use of chaining.
Improve your selector to ensure that it's actually getting an input element (so that there is a value). Then check to see if your selector actually matched anything before working with it. Note that the length of the jQuery object returned is the number of matching elements (it must be greater than 0). Oh, and you can consistently use the $ function as long as there aren't any conflicts with other javascript frameworks.
function updateCountdown()
{
var msg = $('input#message');
if (msg.length > 0) {
var $left = 255 - msg.val().length;
$( '#countdown' ).text( $left + ' Characters Remaining' );
}
}
You just need to check if the jQuery object contains any items. I would do it like this.
$( document ).ready( function()
{
var $message = jQuery( '#message' );
if($message.length > 0) {
updateCountdown();
$( '#message' ).change( updateCountdown );
$( '#message' ).keyup( updateCountdown );
}
});
Then I'd change your updateCountdown() function to use the this keyword rather than doing another jQuery lookup. jQuery sets this to be the DOM element the event occurred on.
function updateCountdown()
{
var $left = 255 - jQuery( this ).val().length;
jQuery( '#countdown' ).text( $left + ' Characters Remaining' );
}