【问题标题】:Javascript way to locate all elements with margin: auto用边距定位所有元素的Javascript方法:自动
【发布时间】:2015-01-09 04:02:23
【问题描述】:

我正在寻找一种简单的方法来定位页面上将 margin-left 和 margin-right 设置为 auto 的元素。

我得到了这个脚本,它在某些时候对我有帮助:

(function() {
  var elementsList = [];
  for (var i = 0; i < document.styleSheets.length; i++) {
    var styleSheet = document.styleSheets[i];
    if (styleSheet.rules) {
      for (var j = 0; j < styleSheet.rules.length; j++) {
        var rule = styleSheet.rules[j];
        if (rule && rule.style && rule.style.marginLeft == 'auto' && rule.style.marginRight == 'auto') {
          var smallList = document.querySelectorAll(rule.selectorText);
          if (smallList.length)
            elementsList = elementsList.concat(smallList);

        }

      }
    }
  }
  return elementsList
})();

虽然这个函数完成了一些工作,但它并没有捕捉到我在网站上看到的大多数 margin: auto 的情况。

你能告诉我一个更好的方法吗?

【问题讨论】:

  • 有一个更简单的方法。你为什么不创建一个类?像 .margin-auto 之类的东西并通过所有这些元素进行搜索?
  • 这听起来像是一个 jQuery 选择器问题。你想要吗?
  • 如果你包含 jquery 并简单地使用那里的选择器,你会更容易。 @MDeSchaepmeester 咬你 ;)
  • 我认为您最好使用getComputedStyles 以可靠地过滤margin-left/right 等于auto 的元素。 document.styleSheets 也很聪明,但也有可能使用内联样式。话虽如此,代码将非常贪婪,因为您需要扫描许多页面元素。您可以通过跳过内联元素和 &lt;br&gt; 等元素来提高效率。
  • @dfsq 不幸的是,这在 FF 和 Safari 中失败了,当边距设置为 auto 时,即使它们正确居中渲染,两者都会返回 0px

标签: javascript css margin


【解决方案1】:

如果您可以使用 JQuery

正如 Martin Ernst 对 yonatan 的回答所说:'这将只选择 marginLeft/Right="auto" 的元素。'

此外,如 cmets 中所述,必须隐藏元素才能与 FF 和 safari 一起使用。

这应该使用 JQuery 工作:

$(document).ready(function() {
    var visibleElements = $('body *:visible');
    $('body *').hide();
    var elements = $('body *').filter(function() {
        return $(this).css('margin-left') == 'auto' && $(this).css('margin-right') == 'auto';
    })
    // show only elements that were visible
    visibleElements.show();
});

提示:如果由于某种原因,您不需要加载外部脚本,只需将缩小的 jquery 脚本的内容复制到您的开头即可。

【讨论】:

  • 不幸的是,这在 FF 和 Safari 中失败了,当边距设置为 auto 时,即使它们正确居中呈现,两者都会返回 0px
  • 你能在 dom 上做所有你想做的动作吗?如果可以,请致电 $('*').hide();在脚本的开头。这样做,将不会计算“自动”值(嗯,我想是这样......;))。如果可行,我会更新我的答案。
  • 正确,但 hide() 应该撤消这些计算(我曾经做过这种'肱'的事情^^)。
  • 如果我在控制台中键入以下代码,并显示这个 stackoverflow 页面,我会得到带有 chrome 和 FF 的元素,不是吗? $('*').hide();$('body *').filter(function() { return $(this).css('margin-left') == 'auto' && $(this). css('margin-right') == 'auto'; })
  • 是的,它有效,我在错误的脚本中做到了。包括它(在($(document).readyshow() 之后),我会投票。
【解决方案2】:

使用 jQuery:
$('*').filter(function(i, d){return d.style.marginLeft == "auto" &amp;&amp; d.style.marginRight == 'auto';});

【讨论】:

  • 他最好使用$('body *'),这样可以避免循环进入不必要的元素(head、meta等)。
  • 这将只选择在其style-attribute 中设置了marginLeft/Right="auto" 的元素,而不是那些由CSS 设置的元素。
【解决方案3】:

我不想这么说,但这个成功不如我自己的版本。

【讨论】:

  • 您的问题并非小事。你试过 Nicolas 回答吗?它应该可以在 Safari 中使用。
【解决方案4】:

这个问题不是小事。即使在window.getComputedStyle() 的日子里,当边距设置为auto 时,也很难为marginLeft/Right 获得跨浏览器的可靠答案。所以这肯定不是一个完整的答案,但会尝试帮助找到一个。

margin-leftmargin-right 在使用margin-shorthand 时也是auto

#elem {margin: auto;} // or:
#elem {margin: 100px auto;} // or:
#elem {margin: 100px auto 30px;} // or:
#elem {margin: 100px auto 30px auto;}

当您在样式表中搜索时,您也必须找到这些符号。在您的代码中在 var elementsList=[]; 之前包含此函数:

function expand(margin) {
    var parts = margin.split(' ');
    for (var i = 3; i; i--) parts[i] = parts[i] || parts[i - 2] || parts[0];
    return parts[1] == 'auto' && parts[3] == 'auto';
}

然后把你内心的if-condition改成:

if (rule && rule.style &&
    (rule.style.marginLeft == 'auto' && rule.style.marginRight == 'auto' || expand(rule.style.margin))
) {
    var smallList = document.querySelectorAll(rule.selectorText);
    if (smallList.length) elementsList = elementsList.concat(smallList);
}

现在您还可以了解使用 margin 的规则。但是您的代码仍然存在一些问题:

  • 当匹配多个规则时,可能会多次列出相同的元素
  • 并不是所有的listet 元素都真正使用marginLeft/Right = auto 呈现。也许那个 css 会被另一个更具体的规则覆盖。
  • 正如 dfsq 在他的评论中提到的那样,您可能找不到这种方式的内联样式。

【讨论】:

  • 我其实不太关心跨浏览器的兼容性。我想为任何浏览器创建一个插件,它将检测边距自动元素(并做一些事情,你需要了解:))
猜你喜欢
  • 1970-01-01
  • 2015-04-24
  • 1970-01-01
  • 1970-01-01
  • 2012-05-25
  • 2021-09-04
  • 1970-01-01
  • 2012-07-06
  • 1970-01-01
相关资源
最近更新 更多