6
\$\begingroup\$

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.

\$\endgroup\$
2
  • \$\begingroup\$ @Kyll I wouldn't say "More strict", just different and strongly enforced. \$\endgroup\$
    – Kaz
    Nov 24, 2015 at 11:26
  • \$\begingroup\$ @Zak I always say it to encourage users to actually read them =p \$\endgroup\$
    – Kyll
    Nov 24, 2015 at 11:27

2 Answers 2

5
\$\begingroup\$

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(', ');
\$\endgroup\$
1
  • 2
    \$\begingroup\$ That's exactly the sort of cleverness I was looking for. Thanks a lot! \$\endgroup\$
    – AnotherFineMess
    Nov 24, 2015 at 11:33
1
\$\begingroup\$

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;
\$\endgroup\$
1
  • \$\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
    Nov 24, 2015 at 11:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.