0

$('[class*=" col-"], [class^="col-"]').css('text-decoration','underline');
[class*=" col-"], [class^="col-"]
{
  background: #39F;
  color: #FFF;
  border: 10px solid #16A;
  height: 50px;
  text-align: center;
  line-height: 28px;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
  <div class="row">
    <div class="first-class col-xs-9 col-md-7">.col-xs-9 .col-md-7</div>
    <div class="col-xs-3 col-md-5">.col-xs-3 .col-md-5</div>
  </div>

  <div class="row">
    <div class="col-xs-6 col-md-10">.col-xs-6 .col-md-10</div>
    <div class="start-with-something-else col-xs-6 col-md-2">.col-xs-6 .col-md-2</div>
  </div>

  <div class="row">
    <div class="so many classes 
                col-xs-6">.col-xs-6</div>
    <div class="bootstrap spam helper classes
                col-xs-6">.col-xs-6</div>
  </div>  
</div>

So a very similar question has been asked in the past, but I guess my question involves a little more, namely I'm wondering if this is yet another example that using bootstrap on a production site is a bad idea.

In jQuery( or CSS) you can use the [class^="foo-"] to select elements via the beginning of their selector. But sometimes the target class I'm looking for isn't the first class in the array of classes.

For instance in bootstrap you use a number of helper classes to build up your site. And I'd like to test if an element has any one of the numerous col-* classes that bootstrap uses. But the same elements could have any number of other classes applied. So using mySelectedJqueryElement.is('[class^="col-"]') almost always returns false even when the item has a class that starts with col-.

In this answer to this very similar question they first suggest making a class for just that prefix, however for the same reason you select a framework like bootstrap, I'd rather not edit the core bootstrap code. It that answer they then go on to suggest using a starts with and a contains selector... While that might work, I was wondering if there is any way to explicitly look through the array of classes for any class that starts with col- or foo-, if you will. I do realize that I could write a function that extracts the array of classes and runs a regex function to manually check the beginning of each of the classes in the array to see if any of them start with a predetermined pattern. This just seems like something that should exist in javascript or jQuery.

There are a few other questions and answers that are similar, but none of them solve this problem entirely and accurately.

Marked as a duplicate of an included question... And I know it is similar, but I guess I'm asking two questions here which is bad practice. One, I was wondering if there was any better answer to the problem of selecting the elements by checking the prefix of all classes. The current answer is using two selectors to accomplish a single task if this is really the only way then I guess I can live with it however it seems inefficient and non-specific. In theory the wildcard selector with whitespace should never find anything that you don't want it to, but it seems heavy handed. Secondly I assumed that the virtual DOM stored classes in an array, but apparently I was mistaken. I definitely feel that this is a bad practice to store a series of variables as a single string.

My second question is if there is any quick fix to bootstrap that could solve this problem more like what was suggested in the "duplicate" question where they suggest to make "apple-" a new class. Would there be a quick regex replace I could run that would make "col" a class on its own? That sounds like a better solution to this problem, but that would make Bootstrap classes even less "object-oriented" which is why I think I'll be dumping them all together.

Community
  • 1
  • 1
Spencer O'Reilly
  • 515
  • 1
  • 7
  • 20
  • 2
    Possible duplicate of [jQuery: using 'starts with' selector on individual class names](http://stackoverflow.com/questions/2178416/jquery-using-starts-with-selector-on-individual-class-names) – MJH Jan 13 '17 at 22:15

2 Answers2

1

Atribute contains string selector: http://api.jquery.com/attribute-contains-selector/

from the jQuery api:

This is the most generous of the jQuery attribute selectors that match against a value. It will select an element if the selector's string appears anywhere within the element's attribute value. Compare this selector with the Attribute Contains Word selector (e.g. [attr~="word"]), which is more appropriate in many cases.

The contains word selector (for comparison): http://api.jquery.com/attribute-contains-word-selector/

flish
  • 596
  • 1
  • 6
  • 17
  • That would be a different method... but I believe it's even less specific to the task at hand... which is why I'm not a fan of the suggestions to other questions. – Spencer O'Reilly Jan 16 '17 at 19:02
0

From the research I've done and the responses to this question, I've determined that at this point in time there is no clean way to perform this action. So I have resigned to using a hack job that breaks the classes down into an array and performs a check on the start of each class for the string.

$.fn.hasClassStartingWith = function(needle){
  var found_match = false;
  
  $(this).each(
  function(i){
      var classlist = this.className.split(/\s+/);
      $.each(classlist,function(){
          if(this.startsWith(needle))
          {
            found_match = true;
          }
      });
    }
  );
  
  return found_match;
  }
$("*").each(function(){
  if($(this).hasClassStartingWith('col-'))
   {
       $(this).css('background','#39F');
   }
  
});
[class*=" col-"], [class^="col-"]
{
  background: red;
  color: #FFF;
  border: 10px solid #16A;
  height: 50px;
  text-align: center;
  line-height: 28px;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
  <div class="row">
    <div class="first-class col-xs-9 col-md-7">.col-xs-9 .col-md-7</div>
    <div class="col-xs-3 col-md-5">.col-xs-3 .col-md-5</div>
  </div>

  <div class="row">
    <div class="col-xs-6 col-md-10">.col-xs-6 .col-md-10</div>
    <div class="start-with-something-else col-xs-6 col-md-2">.col-xs-6 .col-md-2</div>
  </div>

  <div class="row">
    <div class="so many classes 
                col-xs-6">.col-xs-6</div>
    <div class="bootstrap spam helper classes
                col-xs-6">.col-xs-6</div>
  </div>  
</div>
<p>If the javascript worked then the above column elements have a background of blue instead of red.</p>
Spencer O'Reilly
  • 515
  • 1
  • 7
  • 20