(getProperty
is the deepCss
function from here and retrieves the current (computed) style of an element).
function toggleElements()
{
for (var i = 0; i < arguments.length; i++) {
$(arguments[i])[0].style.display = (
getProperty($(arguments[i])[0], "display") !== "none"
? "none"
: "inline-block");
}
}
I use it like this:
<div id="searchdiv" onclick="toggleElements('#searchoplus',
'#searchominus',
'#search_simple',
'#search_extended');">
which will switch on those elements in the list that weren't visible, and switch off those that were.
I guess I can get rid of the for loop and use jQuery's idiomatic chained-expression syntax, but I don't know how.
3 Answers 3
My jQuery's a bit rusty but if #searchoplus
, #searchominus
, etc. initially have a display value of inline-block
you should be able to get your code down to:
function toggleElements() {
$.each(arguments, function(index, id) {
$(id).toggle();
});
}
toggle()
saves the initial value of the display and puts it back in place when it's re-toggled.
-
\$\begingroup\$
searchoplus
andsearch_simple
havedisplay: inline-block
whilesearchominus
andsearch_extended
initially havedisplay: none
. See my answer for a workaround. \$\endgroup\$Felix Dombek– Felix Dombek2012年11月21日 18:49:54 +00:00Commented Nov 21, 2012 at 18:49
I'm not certain I understood what you want, but this should at least be a starting point.
I have assumed that "idiomatic chained-expression syntax" is referring to chainable methods. In other words you could write this:
setElements('#searchoplus',
'#searchominus',
'#search_simple',
'#search_extended').toggle().doSomethingElse();
To accomplish this, you need to create a function that returns an object that has a method that also returns the object.
function setElements(){
//This is the class for creating the object
function elObj(argumentz){
//This method toggles and then returns the 'elObj' object
this.toggle=function(){
for (var i = 0; i < argumentz.length; i++) {
$(argumentz[i])[0].style.display = (
document.getProperty($(argumentz[i])[0], "display") !== "none"
? "none"
: "inline-block");
}
return this;
}
//This is another method that also returns the object
this.doSomethingElse=function(){
console.log("Something else");
return this;
}
}
//Create the new object and return it
return new elObj(arguments);
}
Here is the full code: http://jsfiddle.net/4Mpcs/7/
-
\$\begingroup\$ I definitely misunderstood. I was thinking you wanted a non-jQuery solution... \$\endgroup\$twiz– twiz2012年11月21日 18:57:57 +00:00Commented Nov 21, 2012 at 18:57
-
\$\begingroup\$ Just making sure, you don't want to just use
$('#searchoplus,#searchominus,#search_simple,#search_extended')
, right? \$\endgroup\$twiz– twiz2012年11月21日 21:40:56 +00:00Commented Nov 21, 2012 at 21:40 -
\$\begingroup\$ +1 Well, this is still a valuable answer, even though I was looking for a way to utilize the existing power of jQuery. \$\endgroup\$Felix Dombek– Felix Dombek2012年11月22日 05:35:47 +00:00Commented Nov 22, 2012 at 5:35
I have found that there are two possibilities.
1. The literal translation:
function toggleElements()
{
$(arguments).each(function (index, element) {
$(element)[0].style.display = (
getProperty($(element)[0], "display") !== "none"
? "none"
: "inline-block");
});
}
2. Using toggle()
:
function toggleElements()
{
$(arguments).each(function (index, element) {
$(element).toggle();
});
}
This second version needs a workaround to use the display: inline-block
attribute correctly. You need to specify this attribute in your CSS file even for elements which are hidden when the page is loaded, and hide them by setting display: none
in the style
attribute of the element itself to get the correct behaviour with the jQuery toggle
function.
-
1\$\begingroup\$ Be careful using
each()
, it's only meant for iterating over jQuery objects and can cause problems when used on anything else.jQuery.each()
is the safe alternative :) \$\endgroup\$Clive– Clive2012年11月21日 18:50:04 +00:00Commented Nov 21, 2012 at 18:50