jQUery .slideToggle() & .text replace - javascript

I've got the following problem (test version available http://jsfiddle.net/qmP8R/2/):
I have two <div> containing two versions of text and a third <div> used as a "container".
On load the container is populated with the shorten text. On the click of a button I want to change the short version for the long version with some animation (sliding up/down animation) and vice versa (swap short for long and long for short - basically toggle).
In the test version it works quite as expected, but I am not able to solve the following problems:
animation on 1st click does not work (but the text is changed to the long version)
on second click the whole container is slided up - not reverting to initial state
Basically what I waht to achieve is a kind of toggle behaviour, but connected with .text replacement rather than display: show/hide.
P.S.: AJAX content replacement is not available as a solution in my case.

How about sliding the text up, then changing it, and sliding it back down:
$(document).ready(function(){
$("#popis").text($("#popis_short").text());
var toggle_sw = true;
$("#popis_switch").click(function(){
var full = $("#popis_full").text(),
short = $("#popis_short").text();
if ( toggle_sw == true )
{
$("#popis").slideUp('slow', function () {
$(this).text(full).slideDown('slow');
});
toggle_sw = false;
}
else
{
$("#popis").slideUp('slow', function () {
$(this).text(short).slideDown('slow');
});
toggle_sw = true;
}
});
});
Here is a demo: http://jsfiddle.net/qmP8R/11/
Update
Since the text does not change, you can optimize your code a bit by selecting the text of the elements when the document is ready rather than doing so every-time the click event handler is called:
$(function(){
var $popis = $('#popis'),
toggle_sw = true,
full = $("#popis_full").text(),
short = $("#popis_short").text();
$popis.text(short);
$("#popis_switch").click(function(){
if ( toggle_sw ) {
$popis.slideUp('slow', function () {
$(this).text(full).slideDown('slow');
});
toggle_sw = false;
} else {
$popis.slideUp('slow', function () {
$(this).text(short).slideDown('slow');
});
toggle_sw = true;
}
});
});
Here is a demo of the optimized version: http://jsfiddle.net/qmP8R/13/
This example caches everything it can so no calculations have to happen that don't need to in the click event handler.

Check out JSFiddle. I've basically removed all the logic you had with changing the text.
There is a short div and a long div. The short div contains the first part and the long div contains the REST. Then all you need to do is slide up and down on the long div without changing any of the text.

This best way to do it in my opinion is to hide only the part of the text that should only be shown when you want the full text. This will save on the size of data required as well.
See my example here: http://jsfiddle.net/qmP8R/19/
The javascript is much simpler, and there is less html too:
$(document).ready(function(){
$("#popis_switch").on( 'click', function(){
if ( $("#popis_full").is(':visible') )
{
$("#popis_full").slideUp('slow');
}
else
{
$("#popis_full").slideDown('slow');
}
});
});

The sliding animation is hiding the toggle. I've edited the script to remove the animation and it shows the toggle working as intended. How you had it, the initial state is there but is hidden by the slide up.
$(document).ready(function(){
$("#popis").text($("#popis_short").text());
var toggle_sw = true;
$("#popis_switch").click(function(){
var full = $("#popis_full").text();
var short = $("#popis_short").text();
if ( toggle_sw == true )
$("#popis").text(full).slideDown('slow');
else
$("#popis").text(short).slideUp('slow').slideDown('slow');
toggle_sw = !toggle_sw;
});
});
EDIT:
Changing the order in the jquery chain, I was able to get a smooth animation:
$(document).ready(function(){
$("#popis").text($("#popis_short").text());
var toggle_sw = true;
$("#popis_switch").click(function(){
var full = $("#popis_full").text();
var short = $("#popis_short").text();
if ( toggle_sw == true )
$("#popis").slideUp('slow').text(full).slideDown('slow');
else
$("#popis").slideUp('slow').text(short).slideDown('slow');
toggle_sw = !toggle_sw;
});
});
Or : http://jsfiddle.net/qmP8R/24/

Related

How can I observe changes to my DOM and react to them with jQuery?

I have this function where I toggle a class on click, but also append HTML to an element, still based on that click.
The problem is that now, I'm not listening to any DOM changes at all, so, once I do my first click, yup, my content will be added, but if I click once again - the content gets added again, because as far as this instance of jQuery is aware, the element is not there.
Here's my code:
(function($) {
"use strict";
var closePluginsList = $('#go-back-to-setup-all');
var wrapper = $('.dynamic-container');
$('#install-selected-plugins, #go-back-to-setup-all').on('click', function(event) {
$('.setup-theme-container').toggleClass('plugins-list-enabled');
if ( !wrapper.has('.plugins-container') ){
var markup = generate_plugins_list_markup();
wrapper.append(markup);
} else {
$('.plugins-container').hide();
}
});
//Below here, there's a lot of code that gets put into the markup variable. It's just generating the HTML I'm adding.
})(jQuery);
Someone suggested using data attributes, but I've no idea how to make them work in this situation.
Any ideas?
You could just do something like adding a flag and check for it before adding your markup.
var flag = 0;
$('#install-selected-plugins, #go-back-to-setup-all').on('click', function(event) {
$('.setup-theme-container').toggleClass('plugins-list-enabled');
if ( !wrapper.has('.plugins-container') ){
var markup = generate_plugins_list_markup();
if(flag == 0){
wrapper.append(markup);
flag = 1;
}
} else {
$('.plugins-container').hide();
}
});
If you want to add element once only on click then you should make use of .one() and put logic you want to execute once only in that handler.
Example :
$(document).ready(function(){
$("p").one("click", function(){
//this will get execute once only
$(this).animate({fontSize: "+=6px"});
});
$("p").on("click", function(){
//this get execute multiple times
alert('test');
});
});
html
<p>Click any p element to increase its text size. The event will only trigger once for each p element.</p>

Jquery hasClass Code not Working

I'm trying to make it so when any other slide is active besides the home page slide it hides the menu: ocw2018.orangecoastwebsites.com
I was using this code:
$(document).ready(function () {
if ($('.about-us, .services, .portfolio, ocw-whole-testimonials, .ocw-blog, .contact-us').hasClass('uncode-scroll-active')) {
$('#menu-main-menu').hide();
} else {
$('#menu-main-menu').show();
}
});
In the console, it works fine, but I'm not sure why it's not working on the live site.
Edit:
Basically I want what this code is able to do but with a hasClass instead of hover
$(window).on('hover', function(){
if(
$('.about-us').hasClass('uncode-scroll-active') ||
$('.services').hasClass('uncode-scroll-active') ||
$('.portfolio').hasClass('active') ||
$('.ocw-whole-testimonials').hasClass('uncode-scroll-active') ||
$('.ocw-blog').hasClass('uncode-scroll-active') ||
$('.contact-us').hasClass('uncode-scroll-active')) {
$('#menu-main-menu').hide();
} else {
$('#menu-main-menu').show();
}
});
It is live on the URL I provide above, so you can see when you scroll to the next page, and move your mouse, the menu disappears. It's my workaround until I figure out how to make it hidden when a class is active.
It is very hard to know from your post actually exactly what you want. However see below whatever I guessed so far.
First of all you missed '.' on 'ocw-whole-testimonials' it should '.ocw-whole-testimonials'.
After that please breakdown the multiple condition instead single line selector series like following, it will confirm you more accurate output, suppose any selector may have the expected selector so will return true but any other one may not so what will be out put false? so avoid this confusion it is better to breakdown:
$(document).ready(function () {
function hideMenu(){
if(
$('.about-us').hasClass('uncode-scroll-active') ||
$('.services').hasClass('uncode-scroll-active') ||
$('.portfolio').hasClass('uncode-scroll-active') ||
$('.ocw-whole-testimonials').hasClass('uncode-scroll-active') ||
$('.ocw-blog').hasClass('uncode-scroll-active') ||
$('.contact-us').hasClass('uncode-scroll-active')) {
$('#menu-main-menu').hide();
} else {
$('#menu-main-menu').show();
}
}
hideMenu(); // Call when page load
$(window).scroll(function(){
hideMenu(); // Call when page scroll
})
});
Use this function.
$(window).scroll(function(){
//write your code here
});

Javascript Menu - Scrolling/Content Jumping

I have created a nice little javascript menu, which purposely doesn't use data tags as I was having issued with html purifier conflicts (another, long story).
Anyway, after alot of tinkering, the functionality and styling works exactly as I wanted, but with one exception - when I click on each menu item, it opens the content at different points on the screen, seemingly depending on the amount of content. I want it to always open at the top, so that the menu is always visible, along with the top of the content, and you can then scroll down as you wish.
I've been trying to resolve this for a while, so would appreciate any assistance, or amending of the attached fiddle.
Thanks in advance
Paul
https://jsfiddle.net/awcguxs5/
$(document).ready(function () {
var lastItem = null;
$('#listingmenu').on('click', 'a', function () {
newItem = this.getAttribute('href').substring(1);
if (newItem != lastItem) {
$('.current').not($(this).closest('li').addClass('current')).removeClass('current');
// fade out all open subcontents
$('.pbox:visible').hide(600);
// fade in new selected subcontent
$('#' + newItem).show(600);
lastItem = newItem;
}
}).find('a:first').click();
});
The problem is the references are still going to the corresponding ID locations. I've added one line of jquery that will scroll the page back to the top after the click. here is the line added:
$("html, body").animate({ scrollTop: 0 }, 1);
Here is your jsfiddle with this line:
https://jsfiddle.net/awcguxs5/2/
Let me know if this is what you were looking for! :)
$(document).ready(function () {
var lastItem = null;
$('#listingmenu').on('click', 'a', function () {
newItem = this.getAttribute('href').substring(1);
if (newItem != lastItem) {
$('.current').not($(this).closest('li').addClass('current')).removeClass('current');
// fade out all open subcontents
$('.pbox').hide( 600);
// fade in new selected subcontent
setTimeout( function(){$('#' + newItem).show(600)} , 600 );
lastItem = newItem;
}
}).find('a:first').click();
});
The settimeout fixes the issue and gives -i think- a nicer effect than firing the hide and the show simultaneously.
This happens precisely because you did not want to use "data tags".
Add this to onclick block:
$('#listingmenu').on('click', 'a', function (e) {
e.preventDefault();
.... //rest of your code.
e.preventDefault() will stop the default action of a-href, which in your case uses #div1 anchors to jump to that div.
Your updated fiddle here: https://jsfiddle.net/awcguxs5/3/

how to hide submenu after click

I'm creating a dropdown menu for mobile site
http://gthost.dyndns.org/kudu/en/
when I click on My Account and click on Who we are, submenu still show,,
I Want to hide it after I click on the link.
this is JavaScript code
var $j = jQuery.noConflict();
$j(document).ready(function () {
$j(".account").click(function () {
var X = $j(this).attr('id');
if (X == 1) {
$j(".submenu").hide();
$j(this).attr('id', '0');
} else {
$j(".submenu").show();
$j(this).attr('id', '1');
}
});
//Mouseup textarea false
$j(".submenu").mouseup(function () {
return false
});
$j(".account").mouseup(function () {
return false
});
//Textarea without editing.
$j(document).mouseup(function () {
$j(".submenu").hide();
$j(".account").attr('id', '');
});
});
i would try using:
$('.submenu').css({display:"none"});
instead of .hide();
Two things strike me as odd here.
Why are your ID's integers - valid names start with [a-z_] etc.
Why are you changing the ID? An ID is meant to be a unique identifier and should persist as long as the element does. If you wish to store information about the state of an element within the element itself, then perhaps look into data attributes.
Without seeing your HTML structure everyone is going to be guessing but rather than whatever you are trying to do with the ID's it looks like you could logically use jQuery.toggle:
$j(".account").click(function(){
$j(".submenu").toggle();
});

How to call a function with jQuery blur UNLESS clicking on a link?

I have a small jQuery script:
$('.field').blur(function() {
$(this).next().children().hide();
});
The children that is hidden contains some links. This makes it impossible to click the links (because they get hidden). What is an appropriate solution to this?
This is as close as I have got:
$('.field').blur(function() {
$('*').not('.adress').click(function(e) {
foo = $(this).data('events').click;
if(foo.length <= 1) {
// $(this).next('.spacer').children().removeClass("visible");
}
$(this).unbind(e);
});
});
The uncommented line is suppose to refer to the field that is blurred, but it doesn't seem to work. Any suggestions?
You can give it a slight delay, like this:
$('.field').blur(function() {
var kids = $(this).next().children();
setTimeout(function() { kids.hide(); }, 10);
});
This gives you time to click before those child links go away.
This is how I ended up doing it:
var curFocus;
$(document).delegate('*','mousedown', function(){
if ((this != curFocus) && // don't bother if this was the previous active element
($(curFocus).is('.field')) && // if it was a .field that was blurred
!($(this).is('.adress'))
) {
$('.' + $(curFocus).attr("id")).removeClass("visible"); // take action based on the blurred element
}
curFocus = this; // log the newly focussed element for the next event
});
I believe you can use .not('a') in this situation:
$('.field').not('a').blur(function() {
$(this).next().children().hide();
});
This isn't tested, so I am not sure if this will work or not.

Categories