如何通过Jquery找出类中是否存在样式?

时间:2016-08-30 07:04:04

标签: jquery css dom

我试图google out" jquery函数返回具有类的#ss属性的对象"但我没有找到有价值的结果。

假设在DOM中我有一个div节点,其className =" A B C"。 我有一个名为" search"的有效Jquery对象。其中包含html元素。我需要找出它是否包含一些样式和值,如果它们我发现我将执行一个动作(从node.className中删除该类)

var search = $("div.A");
var css_arr = search.prop("className").split(" ");

以下是要测试的样式的条件:

float != "none" or Float != "" -> if yes, remove the class
position != "absolute" or position != "" -> if yes, remove the class
left is present ... remove the class -> if yes, remove the class
top is present ... remove the class -> if yes, remove the class

我的问题如何进行测试?

JQuery中是否有函数返回具有指定类的css属性的对象?

实例: http://kod.djpw.cz/gwac

修改 我已经开始在基于读取工作表对象的代码中工作。

cssList = function(node) {
    var sheets = document.styleSheets, o = {};
    var sheet;
    for (var i in sheets) {
      if ( sheets[i].hasOwnProperty('cssRules') )
        sheet = sheets[i].cssRules;
      else
      if ( sheets[i].hasOwnProperty('rules') )
        sheet = sheets[i].rules;
      else
        continue;

      var rules = sheets[i].rules || sheets[i].cssRules;
      for (var r in rules) {
          if (node.is(rules[r].selectorText)) 
            {
              o = $.extend(o, make_it_easy.easy.css2json(rules[r].style), css2json(node.attr('style')));
            }
        }  

    }
    return o;
}

此处出现问题:sheets[i].hasOwnProperty('cssRules')sheets[i].hasOwnProperty('rules')始终返回false。为什么?在调试器中,我看到了cssRules属性,但我无法检查它是否存在。

3 个答案:

答案 0 :(得分:2)

jQuery的克隆元素正在获取默认样式,我们可以这样使用它:

$.fn.extend({
    removeClassWithStyles: function(properties) {
        function filterClasses(child, cloned) {
            var thisClassAttr = child.attr("class");
            if (thisClassAttr) {
                var splitClassName = thisClassAttr.split(/\s+/);
                $.each(splitClassName, function(c, className) {
                    cloned.removeClass(className);
                    $.each(properties, function(p, prop) {
                        if (child.css(prop) != cloned.css(prop)) {
                            console.log('remove class: ' + className);
                            child.removeClass(className);
                            return false;
                        };
                    });
                });
            };

        };
        return this.each(function() {
            var thisElement = $(this);
            thisElement.find('*').each(function(e) {
                var child = $(this);
                var cloned = $(this).clone();
                filterClasses(child, cloned);
            });
        });
    }
});
$('body').removeClassWithStyles([
    'float', 'position', 'top', 'right', 'bottom', 'left'
]);
body {
    position: relative;
}
.left {
    float: left;
}
.right-abs {
    position: absolute;
    top: 20px;
    right: 100px;
}
.top-abs {
    position: absolute;
    top: 20px;
}
.center {
    text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="left">
    <h1>Hello</h1>
</div>
<div class="right-abs top-abs center">
    <h3>World</h3>
</div>

同样在 Fiddle

<强>解释

我们正在将元素样式与默认浏览器样式进行比较,因此我们知道这些样式是否由特定类更改。

答案 1 :(得分:0)

我不认为你的计划将会产生适当的解决方案。

AAA ID确实从类hello中浮动正确,但是即使文档准备就绪,获取类hello css仍然会给我们

以下方式实验代码,

http://codepen.io/anon/pen/ozvzwX?editors=1111

同一个类可以为不同的元素设置不同的样式。

&#13;
&#13;
$( document ).ready(function(){
  var search = $("div#left");
  var class_arr = search.prop("className").split(" ");
  console.log("hello "+class_arr)

  $.each(class_arr,function(){
    console.log($("."+class_arr).css("float"))
    console.log($("#AAA").css("float"))  
    //hello hello
    //left
    //right
  })
})
&#13;
div #left { float: left }
div #right { float: right}
.hello {float:right}
&#13;
<script src="http://ajax.googleapis.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
</head>
<body>
<div>

<div id="left" class="hello">
<h1>Hello</h1>
</div>

<div id="right" class="hello">
<h3>World</h3>
</div>
  
<div id="AAA" class="hello">
<h3>AAAAAAAAAAAAAAA</h3>
</div>
  
</div>
&#13;
&#13;
&#13;

为什么不删除你不想要的样式,你可以让它变得动态?

&#13;
&#13;
$("#left").css("float","none"); 
$( document ).ready(function(){
      console.log("Final "+$("#left").css("float"))
      //none
    })
&#13;
div #left { float: left }
div #right { float: right}
.hello {float:right}
&#13;
<script src="http://ajax.googleapis.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
</head>
<body>
<div>

<div id="left" class="hello">
<h1>Hello</h1>
</div>

<div id="right" class="hello">
<h3>World</h3>
</div>
  
<div id="AAA" class="hello">
<h3>AAAAAAAAAAAAAAA</h3>
</div>
  
</div>
&#13;
&#13;
&#13;

答案 2 :(得分:0)

基于scobaljic建议,我已经制作了这段代码。 scobaljic代码包含一些我纠正过的错误。我的目标不是寻找嵌套元素。我还添加了一个检查id的函数。这里的关键是内联样式的备份,在比较之前从元素中删除它们并在比较后恢复它们。我仍在调试代码,因此将来可能会修改错误。

/* Remove classes and ids with unwanted styles */
$.fn.extend({
removeClassWithStyles: function(properties, collectWidthAndPadding = false) 
  {
  paddingAttribs = ["padding", "padding-left", "padding-right"];
  widthAttribs = ["width", "max-width"];
  heightAttribs = ["height", "max-height"];

  function checkObjectProp( obj, element )
  {
    return ( obj.prop == "float" && obj.exclude 
       && 
       (
       obj.exclude == element.css( obj.prop ) 
       )
     ) ? true : false;
  }

  function remove_attr( properties, element, backupObj )
  {
  backupObj;
  for (var p in properties)
    {
    if ( typeof properties[p] === 'object' )
      {
      backupObj.attr.push(properties[p].prop);      
      backupObj.val.push( element.css(properties[p].prop) );
      element.css(properties[p].prop,"");
      }
    else
      {      
      backupObj.attr.push(properties[p]);      
      backupObj.val.push( element.css(properties[p]) );
      element.css(properties[p],"");
      }
    }
  }

  function restore_attr( properties, element, backupObj )
  {
  for (var p in backupObj.attr)
     element.css(backupObj.attr[p], backupObj.val[p]);
  backupObj = { attr: [], val: [] } // reset
  }

  /*
  To detect classes rules and ids rules
  I need to create copy of the original
  element or to backup the inline styles.
  I choosed to backup the inline styles
  because it is faster then clone.
  After I inline styles, I will create 
  clone of the element and compare the
  styles with the modified element.
  Then I restore the styles.
  */
  function filterClasses(element, className, id) 
  {
  if ( className )
    {
    var class_contains_width = false;
    var class_contains_height = false;
    element.css("position", "relative");    
    element.css("float", "left");

    $.each( className.split(/\s+/),
      function(c, className) 
      {
      /* 
      Find out if current class 
      contains the style
      */
      var cloned = $(element).clone();


      // remove class
      cloned.removeClass(className);

      /* Detect padding in element or clone */
      if ( collectWidthAndPadding && cloned.checkPropertiesPresent(element, paddingAttribs) )
        search_padding_collection_classes = search_padding_collection_classes.add(element);            
      /* Detect if width/height could be removed with a class
         + prevent from calling multiple times
         */
      if ( collectWidthAndPadding && !class_contains_width && search_width_classes && cloned.checkPropertiesPresent(element, widthAttribs) )
        search_width_classes = search_width_classes.add(element);
      // div#BlogArchive1 div.widget-content

      $.each(properties, function(p, prop) 
        {
        /* Then remove classes */
        if ( typeof prop === 'object' )
          {
          // A) The style has been inserted
          if ( element.css(prop.prop) != cloned.css(prop.prop) )
            {
            if ( checkObjectProp( prop, cloned ) )
              { // skip it
              }
            else
              {
              // element.removeClass(className);
              return false;
              }              
            }
          else // B) The style has not been inserted
            {
            if (element.css(prop))
              if ( checkObjectProp( prop, element ) )
                { // skip it
                }
              else
                {
                // element.removeClass(className);
                return false;
                }              
            }
          }
        else // prop is not object
          {
          // A) The style has been inserted
          // element.css("right") != cloned.css("right")
          if (element.css(prop) != cloned.css(prop))
            {
            // element.removeClass(className);
            return false;
            }
          else // B) The style has not been inserted
            {
            if (element.css(prop))
              {
              // element.removeClass(className);
              return false;
              }
            }
          }
        });
      });
    };
  };
  function filterIds(element, className, id) 
  {
  if ( id )
    {
    /* 
    Find out if current id 
    contains the style
    */
    var cloned = $(element).clone();
    // remove id    
    cloned.removeAttr("id");

    /* Detect padding in element or clone */
    if ( collectWidthAndPadding && cloned.checkPropertiesPresent(element, paddingAttribs) )
      search_padding_collection_classes = search_padding_collection_classes.add(element);            
    /* Detect if width/height could be removed with a class
       + prevent from calling multiple times
       */
    if ( collectWidthAndPadding && search_width_ids && cloned.checkPropertiesPresent(element, widthAttribs) )
      search_width_ids = search_width_ids.add(element);
    // div#BlogArchive1 div.widget-content

    $.each(properties, function(p, prop) 
      {
      /* Then remove classes */
      if ( typeof prop === 'object' )
        {
        // A) The style has been inserted
        if ( element.css(prop.prop) != cloned.css(prop.prop) )
          {
          if ( checkObjectProp( prop, cloned ) )
            { // skip it
            }
          else
            {
            // element.removeAttr("id");
            return false;
            }              
          }
        else // B) The style has not been inserted
          {
          if (element.css(prop))
            if ( checkObjectProp( prop, element ) )
              { // skip it
              }
            else
              {
              // element.removeAttr("id");
              return false;
              }              
          }
        }
      else // prop is not object
        {
        // A) The style has been inserted
        // element.css("right") != cloned.css("right")
        if (element.css(prop) != cloned.css(prop))
          {
          // element.removeAttr("id");
          return false;
          }
        else // B) The style has not been inserted
          {
          if (element.css(prop))
            {
            // element.removeAttr("id");
            return false;
            }
          }
        }
      });
    };
  };

  return function(element){
    var className = element.attr("class");
    var id = element.attr("id");    
    var backup_inline_styles = { attr: [], val: [] }
    if ( className || id )
      { 
      remove_attr( properties, element, backup_inline_styles );
      }
    filterClasses(element,className,id);
    filterIds(element,className,id);
    if ( className || id )
      restore_attr( properties, element, backup_inline_styles );
  }($(this))

  }
});

实施

window.onload = function() {  
  search_padding_collection_classes = $();
  search_width_classes = $();
  search_padding_collection_ids = $();
  search_width_ids = $();
  var search = $("div.column-right-outer");
  $(search).removeClassWithStyles([ { prop: 'float', exclude: 'none' }, 'position', 'top', 'right', 'bottom', 'left' ], true);
  $(search).compressElementsWidth();
  // console.log($('div.column-right-outer').find("*").filter(":visible"));
};