Optimize jquery code - javascript

$(textBox).focus( function() {
$(spans).css({"background-position": "0 100%"});
});
$(textBox).blur( function() {
$(spans).css({"background-position": "0 0"});
});
This is already short but it's either I am just too paranoid, or we could code this shorter by
$(textBox).bind('focus blur', function() { *do toggle here* });
or something else.
Any help would be greatly appreciated. =)

Try this:
$( textBox ).focus( function(){...} ).blur( function() {...} );
And yes, you can also use the bind() function as you specified.
I find my version more readable.
Good luck!

You can try this as well:
$(textBox).bind('focus blur', function(e) {
var bg = (e.type=='blur') ? '0 0' : '0 100%';
$(spans).css({"background-position": bg});
});

I think there's a line between optimization and code clarity. Without any further evidence, I don't believe you'll see any major improvements as far as optimizations go.
Keeping these two separate allows for a very quick and easy scan... No logic to go through. Its just "When this happens, then do this". Simple and you're probably losing, if anything, very little.
Edit:
If like you mentioned in a comment you want to toggle the class, you could
$(textBox).bind('focus blur', function() {
var currentClass = $(this).attr('class');
var newClass = currentClass == 'gotFocus' ? 'noFocus' : 'gotFocus';
$(this).removeClass(currentClass).addClass(newClass); });

If you want to use the same function for both the events, you need to use a way of changing the effect that can be used to turn it both ways. Something like:
$(textBox).bind('focus blur', function() { $(spans).toggleClass('over'); });
If there are a lot of elements that you want to change the effect on, you should consider using the cascading effect of CSS instead of letting jQuery change the class for all the elements, i.e. changing the class for a single parent element, and have a style that targets all the child elements that you want to affect:
#container span { background-position: 0 0; }
#container.over span { background-position: 0 100%; }
Changing the class of the parent will change the style of all affected children:
$(textBox).bind('focus blur', function() { $('#container').toggleClass('over'); });

$("#test").bind("focus blur", function (e) {
$(spans).css({"background-position": e.type === "focus" ? "0 100%" : "0 0"});
});

Related

jQuery Collapsible tabindex

Using jquery.collapsible.js I notice that the tabindex does not change when expanded/closed. I nearly have a solution but would appreciate it if someone could improve on this piece of code as I am sure there is a better way to do this.
$('.collapsible').each(function() {
$('.collapsible').on('click',function(e) {
if($('div').hasClass('collapsible collapse-open')) {
$('.collapsible.collapse-open').attr("tabIndex", 0);
} else {
$('.collapsible.collapse-close').attr("tabIndex", -1);
}
});
});
The problem is the tabindex only changes on the second click and then the 0,-1 order is wrong.
If you're just looking for a better way, and your solution already works, you could simplify it with this. You don't need to loop through each .collapsible with the each function just to add the click event handler.
$(".collapsible").on('click', function (e) {
var self = $(this);
var tabIndex = self.hasClass("collapse-open") ? 0 : -1;
self.attr("tabIndex", tabIndex);
});
This will select any element with the class collapsible, bind the click event, and then check if that element has the collapse-open class to determine which tab index to apply.
Thanks to Ihan for the more efficient script. It is working now I just had to change the default class from 'collapse-open' to 'collapse-close'.
$(".collapsible").on('click', function (e) {
var self = $(this);
var tabIndex = self.hasClass("collapse-close") ? 0 : -1;
self.attr("tabIndex", tabIndex);
});

Why is this hover toggle jQuery not working?

I have separate jQuery functions for "mouseenter" and "mouseleave" that work fine:
$('#imgPostTravel').mouseenter(function () {
$('#imgPostTravel').addClass('popout_image');
$('#imgPostTravel').addClass('shadow');
});
$('#imgPostTravel').mouseleave(function () {
$('#imgPostTravel').removeClass('popout_image');
$('#imgPostTravel').removeClass('shadow');
});
...but am hoping to consolidate it into one "hover" toggle operation.
I first want to make sure it really works, so tried the following on a jsfiddle here:
$( "ptVerbiage" ).hover(function() {
$(this).val('yep!');
}, function() {
$(this).val('nope!');
});
I've tried several things besides setting the value of "val" (changing the "disabled" attr, changing the color, backgroundcolor, etc.) but none of them does a thing. Is this the wrong way to hover/toggle, or what's wrong?
You forgot the hashtag to make reference to an ID. Also, your target element is a h2, that has no .val() method because it is not a form (text) input. You have to use .text() instead.
The portion of code should look like this (jsFiddle):
$("#ptVerbiage").hover(function() {
$(this).text('yep!');
}, function() {
$(this).text('nope!');
});
You seem to be missing a #
$("ptVerbiage") => $("#ptVerbiage")
AND
not .val() but .text(); as .val is for inputs
should look like this
$( "#ptVerbiage" ).hover(function() {
$(this).text('yep!');
}, function() {
$(this).text('nope!');
});
http://jsfiddle.net/n9sq7x8y/4/
Using everyone's suggestions, this is what works:
$( "#imgPostTravel" ).hover(function() {
$(this).addClass('popout_image');
$(this).addClass('shadow');
}, function() {
$(this).removeClass('popout_image');
$(this).removeClass('shadow');
});

listen for any div that goes from display: none to display:block

Is there any way to listen for elements being shown or hidden?
I would like categorically to--whenever an element goes from hidden to shown--put focus on the first input element within the newly shown element
I thought of attaching a click event to everything and putting it at the top of the document, thinking that would trigger before anything and I could track whether the clicked element's next("div") (or something) would have a css display property of none, then setting a small timeout, then setting the focus, but I get undefined when I try to access that CSS property
$("html").on("click", "body", function(){
alert($(this).next("div").css("display")); //undefined
});
Is there a way to do this?
You can try something like this (it’s kind of a hack). If you monkey-patch the css/show/hide/toggle prototypes in jQuery, you can test if the element changes it’s :hidden attribute after a "tick" (I used 4ms). If it does, it has changed it’s visibility. This might not work as expected for animations etc, but should work fine otherwise.
DEMO: http://jsfiddle.net/Bh6dA/
$.each(['show','hide','css','toggle'], function(i, fn) {
var o = $.fn[fn];
$.fn[fn] = function() {
this.each(function() {
var $this = $(this),
isHidden = $this.is(':hidden');
setTimeout(function() {
if( isHidden !== $this.is(':hidden') ) {
$this.trigger('showhide', isHidden);
}
},4);
});
return o.apply(this, arguments);
};
})
Now, just listen for the showhide event:
$('div').on('showhide', function(e, visible) {
if ( visible ) {
$(this).find('input:first').focus();
}
});
Tada!
PS: I love monkeypatching
You could:
var allEls = $('body *');
function isDisplayBlock(arr) {
var isBlock = [];
$.each(arr, function(i, e){
if ($(e).css('display') === 'block') {
isBlock.push(e);
}
})
return isBlock;
}
But ive no idea how to check if they changed, instead of just checking if they are block.
You can just use $('div:visible') to check whether a div has display: block or display: none. Those are the only two values that :visible looks at anyway.
Source: How do I check if an element is hidden in jQuery?
-edit-
I realise I didn't read thoroughly, you're asking about an event that tells you when display changed. There is none, see Nelson's comment on your question.

On second click; jQuery

<div class="example">
Test
</div>
$('.example').click(function(){
$(this).css('color','red');
});
When the code above get's clicked, it will apply the .css. Now what I need is for another bit of code (let's say $(this).css('color','blue');) to be applied, replacing the previous code when .example gets clicked a second time.
I've searched for this and askers seem to only need .show/.hide events which can be substituted with .toggle, which is obviously not the case here.
Since you may have many instances of class example, simply maintaining a state using a single variable is not feasible, what you can do is to maintain the state of each instance of example within itself:
Define two css classes
.example { background:blue }
.example.red { background:red }
Then your click method:
$('.example').click(function(){
$(this).toggleClass('red');
});
If you prefer not to define new css classes, you can use data(), to make sure that the state is exclusive within each .example, this is useful if you have many instances of .example
$('.example').click(function() {
var color = $(this).data('color');
if(color != 'blue') {
$(this).css('color', 'blue');
$(this).data('color', 'blue');
} else {
$(this).css('color', 'red');
$(this).data('color', 'red');
}
});
http://api.jquery.com/data/
Something like this would work to toggle between 2 colours (or styles).
$('.example').click(function(){
if($(this).css('color') == "red")
{
$(this).css('color','blue');
}
else
{
$(this).css('color','red');
}
});
<div class="example">
Test
</div>
just maintain a bool and you are done..
var isRed=false;
$('.example').click(function(){
if(isRed)
{
$(this).css('color','blue');
isRed=false;
}
else
{
$(this).css('color','red');
isRed=true;
}
});
Use addClass and removeClass
.blueColor
{
background-color: blue;
}
.redColor
{
background-color: red;
}
And use in your javascript the addClass and removeClass functions:
<script>
$(document).ready(function(){
$(".example").keypress(function() {
if($(".example").val().length > 0)
{
$(".example").addClass("redColor");
}
else {
if($(".example").val().length == 0)
{
$(".example").addClass("blueColor");
$(".example").removeClass("redColor");
}
}
});
});
</script>
I guess you need something more generic about click event exactly so I'd suggest you to use data method to leave the flags
$('.example').click(function() {
if (!$(this).data("custom-even")) {
// odd execution
$(this).data("custom-even", true)
} else {
// even execution
$(this).data("custom-even", false)
}
});​
$('.example').click(function(){
var theExample = $(this);
if(theExample.hasClass("clicked")){
theExample.css('color','blue').removeClass("clicked");
}else{
theExample.css('color','red').addClass("clicked");
}
});
http://jsfiddle.net/SnDgh/
Hiya Try this with toggle :)) http://jsfiddle.net/FVXAZ/
SO you can use toggle with your css and every second click will have the vice-a-versa affect. :)
Code
$(function() {
$('.example').toggle(function() {
$(this).css('color','red');
}, function() {
$(this).css('color','blue');
});
});
Have a nice man man, cheers!
Try this:
$('.example').click(function(){
if($('.example').data('isAlreadyClicked')=='true')
{
$(this).css('color','blue');
$('.example').data('isAlreadyClicked','false')
}
else
{
$(this).css('color','red');
$('.example').data('isAlreadyClicked','true')
}
});
Use the one method to handle one-time event binding is a good choice, however this solution will stop all events binded after this code, it may cause inconsistency.
$('.example')
.one('click', function(e) {
e.stopImmediagePropagation();
})
.on('click', function() {
$(this).css('color', blue');
});
Lot of answers all defining a single solution.
Basically, there are two ways that you should use. The other ways mentionned are either unperformant or unsemantic (using data for this kind of solution is overkill). Here are the two ways you may use:
// Toggle a class 'red' defined in your stylesheet
$('.example').on('click', function() {
$(this).toggleClass('red')
})
// Toggle the color with an "if" check
$('.example').on('click', function() {
if (this.style.color === 'red') { // using jQuery is not required
this.style.color === 'blue'
}
else {
this.style.color === 'red'
}
})
You can write:
$('#id').toggle(function() {
$('.css').css('color','red');}
,function() { /////////the second click
$('.css').css('color','blue');}
);

jQuery Problem - How to solve?

I have a jQuery requirement like:
I have an Image. If I click it once its size will get reduced. If I again click it it will again resize.
Do we have any functionality to do it easily in jQuery? Or do I have to set a flag and then work on mouseclick? Something like
$("#img1").click(function() {
$("#img1").addClass("img1");
});
Don't use toggle, when there is toggleClass function :)
$("#img1").click(function() {
$("#img1").toggleClass("img1");
});
jQuery toggle function might help.
In short=>
CSS:
.small{width: 10px;}
Javascript:
var makeSmall = function(){
$(this).addClass("small");
};
var makeNormal = function () {
$(this).removeClass("small");
};
$("#id").toggle(makeSmall, makeNormal);
Also - you might want to change CSS directly through jQuery:
var makeSmall = function(){
$(this).css({'width' : '10px'});
}
P.s. Thinker's approach with toggleClass is cleaner.

Categories