I need to return True if a page contains any of a list of element types. This code works.
var elements = 0;
var content = $('.TestModule');
if (content !== null && typeof (content) !== "undefined") {
elements += content.first().find('.btn').length;
elements += content.first().find('.textbox').length;
elements += content.first().find('.ui-jqgrid').length;
elements += content.first().find('.flexboxdiv').length;
elements += content.first().find('.headerlabel').length;
}
return elements > 0;
But always runs every test which is obviously inefficient so I changed to;
var valid = false;
var content = $('.TestModule');
if (content !== null && typeof (content) !== "undefined") {
var elementTypes = ['btn', 'textbox', 'ui-jqgrid', 'flexboxdiv', 'headerlabel'];
for (i = 0; i < elementTypes.length; i++) {
var num = content.first().find('.' + elementTypes[i]).length;
if (num > 0) {
valid = true;
break;
}
}
}
return valid;
Which also works and runs the minimum number of tests. But it looks pretty clunky to me. Can you suggest a better loop/structure/test, please? I don't need a count of element types, just to know whether one or more of any type exists.
-
\$\begingroup\$ @Kyll I wouldn't say "More strict", just different and strongly enforced. \$\endgroup\$Kaz– Kaz2015年11月24日 11:26:54 +00:00Commented Nov 24, 2015 at 11:26
-
\$\begingroup\$ @Zak I always say it to encourage users to actually read them =p \$\endgroup\$Kyll– Kyll2015年11月24日 11:27:54 +00:00Commented Nov 24, 2015 at 11:27
2 Answers 2
Join the string to create a jQuery selector
var elementTypes = ['btn', 'textbox', 'ui-jqgrid', 'flexboxdiv', 'headerlabel'];
var selector = '.' + elementTypes.join(', .');
return $('.TestModule').first().find(selector).length > 0;
The variable selector will return the string '.btn, .textbox, .ui-jqgrid, .flexboxdiv, .headerlabel' which can be used in the jQuery selector.
The statement
return $('.TestModule').first().find(selector).length > 0;
is equivalent to
return $('.TestModule').first().find('.btn, .textbox, .ui-jqgrid, .flexboxdiv, .headerlabel').length > 0;
after the string substitution.
To make it more dynamic, store complete selector in the array and join the array by ,-comma.
var elementTypes = ['.btn', '.textbox', '.ui-jqgrid', '.flexboxdiv', '.headerlabel', '#myId', 'input', 'input[name="firstname"]'];
var selector = elementTypes.join(', ');
-
2\$\begingroup\$ That's exactly the sort of cleverness I was looking for. Thanks a lot! \$\endgroup\$AnotherFineMess– AnotherFineMess2015年11月24日 11:33:55 +00:00Commented Nov 24, 2015 at 11:33
You can utilize Array.prototype.reduce to calculate the sum of length.
var $testModuleFirst = $('.TestModule').first();
var selectors = ['.btn', '.textbox', '.ui-jqgrid', '.flexboxdiv', '.headerlabel'];
var elements = selectors.reduce(function(a, b) {
return a + $testModuleFirst.find(b).length;
}, 0);
return elements > 0;
-
\$\begingroup\$ That is interesting. I was wondering about using an array function but didn't know how to go about it, so thanks for the example. \$\endgroup\$AnotherFineMess– AnotherFineMess2015年11月24日 11:36:43 +00:00Commented Nov 24, 2015 at 11:36