简体   繁体   English

使用 javascript 将 css styles 转换为内联 styles

[英]Convert css styles to inline styles with javascript keeping the style units

We have a corporate content management system that allows for rich text editing/html markup, but does not allow for head elements or style sheets to be uploaded, attached, or used in any way.我们有一个企业内容管理系统,允许进行富文本编辑/html 标记,但不允许上传、附加或以任何方式使用头部元素或样式表 It provides some rich text editing controls and also access to the source html, but just for the html fragment -- there is no head, no body.它提供了一些富文本编辑控件,还可以访问源代码 html,但仅针对 html 片段——没有头部,没有主体。 We also have no access the whole system that presents these bits of markup on the page.我们也无法访问在页面上显示这些标记位的整个系统。 The only way to style the content is through inline style attributes on the elements.设置内容样式的唯一方法是通过元素上的内联样式属性。 It is best, it isn't pretty, but that is what we have and I'm trying to make the best of a bad situation.这是最好的,它并不漂亮,但这就是我们所拥有的,我正在努力在糟糕的情况下做到最好。

We also have high standards for visual presentation and would like to be able to quickly produce and modify/update content and keep it looking nice.我们对视觉呈现也有很高的标准,并希望能够快速生成和修改/更新内容并保持其美观。 It is difficult to correctly apply formatting using the system.使用系统很难正确应用格式。 For anybody who has tried to markup anything more than a paragraph or two with an RTE, you probably know what I mean.对于任何试图用 RTE 标记超过一两段的内容的人,你可能知道我的意思。 It seems like we should have a different system, but has anybody worked for a large company before?看起来我们应该有一个不同的系统,但是以前有人在大公司工作过吗? Just sayin.只是在说。

We do have access to another location where we could "author" and "store" actual styled content and then "compile it" for copypasta into the other system.我们确实可以访问另一个位置,我们可以在其中“创作”和“存储”实际样式的内容,然后“编译”以将其复制到另一个系统中。 In other words, we could author/design using css and best practices and then we could run some code that could convert those element, class, and id formatting into inline styles.换句话说,我们可以使用 css 和最佳实践进行创作/设计,然后我们可以运行一些可以将这些元素 class 和 id 格式转换为内联 styles 的代码。

I did my research and found this thread which also lead me to this code .我做了我的研究,发现这个线程也引导我找到这个代码

These both are very helpful in exploring solutions, but I've run into an issue.这两者对于探索解决方案都非常有帮助,但我遇到了一个问题。 These solutions use the javascript getComputedStyle() method.这些解决方案使用 javascript getComputedStyle()方法。 There are some other options for properties to only look at other properties or to be recursive on the children of the element provide, but basically it boils down to this.属性还有一些其他选项可以仅查看其他属性或对元素提供的子元素进行递归,但基本上可以归结为这一点。 (Since getComputeStyle returns an object and not an array, there is also a prototype/polyfill to allow iterating over an object with forEach, but none of that is part of the issue I'm facing.) (由于 getComputeStyle 返回 object 而不是数组,因此还有一个原型/polyfill 允许使用 forEach 迭代 object,但这些都不是我面临的问题的一部分。)

const computedStyle = getComputedStyle(element);常量计算样式 = 获取计算样式(元素); computedStyle.forEach(property => { element.style[property] = computedStyle.getPropertyValue(property); }); computedStyle.forEach(property => { element.style[property] = computedStyle.getPropertyValue(property); });

This works well for css attributes like font-size:24px or margin:0 15px .这适用于 css 属性,如font-size:24pxmargin:0 15px The issue I'm running into are when I'm using units other than px.我遇到的问题是当我使用 px 以外的单位时。 For example, if I'm trying to make something that has width:50% .例如,如果我正在尝试制作具有width:50%的东西。 getComputedStyle() converts the 50% to the actual number of pixels that 50% is currently using. getComputedStyle() 将 50% 转换为 50% 当前使用的实际像素数。

In the notes section of the MDN web docs I see that this is expected behavior.MDN web 文档的注释部分中,我看到这是预期的行为。 Although I'm not quite clear on what that last line means.虽然我不太清楚最后一行是什么意思。

...An example difference between pre- and post-layout values includes the resolution of percentages for width or height, as those will be replaced by their pixel equivalent only for used values. ...布局前和布局后值之间的示例差异包括宽度或高度百分比的分辨率,因为这些将被替换为仅用于使用值的像素等效值。

So what I'm trying to do is convert something like this所以我想做的是转换这样的东西

.container{width:50%;}

<div class="container">

into something like this变成这样的东西

<div class="container" style="width:50%">

Does anyone know of a way to complete this type of transformation?有谁知道完成这种转换的方法?

PS: If it matters we'll be using the more basic attributes in our css -- no transitions, grid, prefixing, etc. We still need to support IE 11 -- if that tells you anything. PS:如果重要的话,我们将在 css 中使用更基本的属性——没有过渡、网格、前缀等。我们仍然需要支持 IE 11——如果这能告诉你什么的话。 We won't need to account for every edge case or browser.我们不需要考虑每个边缘案例或浏览器。 Just some basic stuff so that all our H1 look the same.只是一些基本的东西,让我们所有的 H1 看起来都一样。

Couldn't find any way to do this using the built in getComputedStyle() .使用内置的getComputedStyle()找不到任何方法来执行此操作。 It also returned too many properties that I wasn't interested in. So I came up with a different approach.它还返回了太多我不感兴趣的属性。所以我想出了一个不同的方法。 Basically to use the same function to loop through an element (and maybe all its children elements) and the use Element.matches() to get all the css rules that apply to the element and apply the properties as they were specified in the stylesheet.基本上使用相同的 function 循环遍历一个元素(可能还有它的所有子元素)并使用Element.matches()来获取所有适用于元素的 css 规则并应用样式表中指定的属性。

I modified this answer a bit to get the rules from the stylesheet.我稍微修改了这个答案以从样式表中获取规则。

Has the added benefit that we can pull either from all the document stylesheets or just from a specific one that is needed for preparing the code to go into our content management systems's rich text editor.具有额外的好处,我们可以从所有文档样式表中提取,或者仅从将代码准备到 go 所需的特定样式表中提取到我们的内容管理系统的富文本编辑器中。

function applyInline(element, recursive = true) {

  if (!element) {
    throw new Error("No element specified.");
  }

  const matches = matchRules(element);

  // we need to preserve any pre-existing inline styles.
  var srcRules = document.createElement(element.tagName).style;
  srcRules.cssText = element.style.cssText;

  matches.forEach(rule => {
    for (var prop of rule.style) {

      let val = srcRules.getPropertyValue(prop) || rule.style.getPropertyValue(prop);
      let priority = rule.style.getPropertyPriority(prop);

      element.style.setProperty(prop,val,priority);
    }
  });

  if (recursive) {
    element.children.forEach(child => {
      applyInline(child, recursive);
    });
  }
}

function matchRules(el, sheets) {
  sheets = sheets || document.styleSheets;
  var ret = [];

  for (var i in sheets) {
    if (sheets.hasOwnProperty(i)) {
      var rules = sheets[i].rules || sheets[i].cssRules;
      for (var r in rules) {
        if (el.matches(rules[r].selectorText)) {
          ret.push(rules[r]);
        }
      }
    }
  }
  return ret;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将外部CSS样式表转换为内联样式,或转换为<style> tag, via Javascript - Convert external CSS stylesheet into inline styles, or into a <style> tag, via Javascript 使用javascript将外部和内部样式转换为嵌入式样式 - Convert external and internal styles into inline styles with javascript 如何使用客户端 javascript 将外部/内部 css 样式转换为内联样式属性 - How to convert external/internal css styles into inline style-attribute using client-side javascript 如何使用javascript擦除所有内联样式并仅保留css样式表中指定的样式? - How can I erase all inline styles with javascript and leave only the styles specified in the css style sheet? JSX CSS到内联样式 - JSX css to inline styles CSS Transitions:在“ height”样式属性的内联样式之间进行动画处理 - CSS Transitions: Animating between inline styles for “height” style attribute 如何将嵌套的 javascript object 转换为 CSS ZBC4150D023D32593136DB671D6Z1 的内联字符串? - How can I convert a nested javascript object into an inline string of CSS styles? ReactJS内联样式中的倍数样式 - Multiples styles in ReactJS inline style 嵌入样式是否覆盖内联样式? - Embedded style overriding inline styles? 如何在 javascript 中将 object 转换为有效的 css styles? - how to convert object to valid css styles in javascript?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM