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();
});
Related
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>
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/
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.
I'm using jQuery for a vertical site navigation menu, all links within site. I have the basic functionality working, but am at a loss as to the correct if-else to accomplish the following:
As the code stands, the submenu items are always initially hidden, but I want them to start shown if the user-selected li or one of its child lis is assigned the class currentpage.
The code as it stands is:
(function(){
$('li:has(ul)')
.click(function(event){
if (this == event.target || $(event.target).parent()[0] == this) {
if ($(this).children('ul').is(':hidden')) {
$(this)
.css('list-style-image','url(minus.gif)')
.children('ul').slideDown();
}
else {
$(this)
.css('list-style-image','url(plus.gif)')
.children('ul').slideUp();
}
}
})
.css({
cursor:'pointer',
'list-style-image':'url(plus.gif)'
})
.children('ul').hide();
$('li:not(:has(ul))').css({
cursor: 'default',
'list-style-image':'none'
});
});
Hopefully someone can put me on the right track.
Bob McLeod
I want them to start shown if the user-selected li or one of its child lis is assigned the class currentpage.
How about afterwards doing:
$('.currentpage').parents('ul').show();
I would make a showMenuItem() function and call it in both places where you want to show a menu item.
$(function() { $('.currentpage').each(function() {
if ($(this).parents().filter('ul').is(":hidden")) {
showMenuItem($(this).parents().filter('ul'));
} else {
showMenuItem(this);
}
}});
I am using jQuery to show / hide lists, but it takes two clicks on a link instead of just one to show the list. Any help?
jQuery.showList = function(object) {
object.toggle(function(){
object.html("▾");
object.siblings("ul.utlist").show("fast");
}, function(){
object.html("▸");
object.siblings("ul.utlist").hide("fast");
});
}
$(document).ready(function() {
$("#page").click(function (e){
e.preventDefault();
var target = $(e.target);
var class = target.attr("class");
if(class == "list")
$.showList(target);
});
});
It's probably because toggle thinks the object is already visible, and executes the 'hide' clause.
edit:
Eh.. quite circular logic; how else would a user be able to click on it :-)
PS. You changed the logic from is-object-visible? to is-list-visible? in your own reply.
Not sure if this will fix everything but stop using reserved keywords.
Change variable class to something like c. And Change object variable to at least obj.
Doing the following worked well
jQuery.showList = function(obj) {
var list = obj.siblings("ul.utlist");
if(list.is(":visible")){
obj.html("▸");
list.hide("fast");
} else {
obj.html("▾");
list.show("fast");
}
}