Я хочу иметь возможность анализировать встроенный CSS и иметь его в качестве объекта в парах ключей. Что-то вроде:

<div background-image: url('http://domain.com/images/image.jpg');background-size: cover;padding: 100px 0;">

{ 
  backgroundImage : "http://domain.com/images/image.jpg",
  backgroundSize: "cover",
  padding: "100px 0"
} 

Эта функция прекрасно работает для большей части. У меня проблема с фоновым изображением

Он полностью удаляется, и вместо этого я получаю URL (http).

function parseCss(el) {
    var output = {};

    if (!el || !el.attr('style')) {
        return output;
    }

    var camelize = function camelize(str) {
        return str.replace(/(?:^|[-])(\w)/g, function(a, c) {
            c = a.substr(0, 1) === '-' ? c.toUpperCase() : c;
            return c ? c : '';
        });
    }

    var style = el.attr('style').split(';');
    for (var i = 0; i < style.length; ++i) {
        var rule = style[i].trim();
        if (rule) {
            var ruleParts = rule.split(':');
            var key = camelize(ruleParts[0].trim());
            output[key] = ruleParts[1].trim();
        }
    }

    return output;
}

Я уверен, что необходимо заменить функцию «замена», чтобы она работала с URL-адресом изображения.

1
Alko 11 Дек 2016 в 21:29

3 ответа

Лучший ответ

Вы можете попробовать это, протестировано на нескольких примерах:

styleObj={};
style=$('div').attr('style');
rules=style.split(';');
rules = rules.filter(function(x){
  return (x !== (undefined || ''));
}); // https://solidfoundationwebdev.com/blog/posts/remove-empty-elements-from-an-array-with-javascript



for (i=0;i<rules.length;i++) {

rules_arr=rules[i].split(/:(?!\/\/)/g); // split by : if not followed by //
rules_arr[1]=$.trim(rules_arr[1]).replace('url(','').replace(')','');

if(rules_arr[0].indexOf('-')>=0) {
rule=rules_arr[0].split('-');
rule=rule[0]+rule[1].charAt(0).toUpperCase()+rule[1].slice(1);
}
else {
rule=rules_arr[0];
}
styleObj[$.trim(rule)]=rules_arr[1];

}

console.log(styleObj);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="font-size: x-large; color: #ff9900; background-image: url('http://placehold.it/100x100');">Using inline style sheets - or is that inline styles?</div>

Демонстрация (проще для тестирования различных встроенных стилей): https://jsfiddle.net/n0n4zt3f/2/

Постскриптум Тримминг и верблюжий чехол остались ... можно добавить, конечно ...

0
sinisake 11 Дек 2016 в 20:19

Вместо чтения атрибута style вы можете перебирать свойства style. Таким образом вы избежите проблем с разделителями, встроенными в значения стилей:

function parseCss(el) {
    function camelize(key) {
        return key.replace(/\-./g, function (m) {
            return m[1].toUpperCase();
        });
    }
    
    var output = {};
    for (var a of el.style) {
        output[camelize(a)] = el.style[a];
    }
    return output;
}
// Demo 
var css = parseCss(document.querySelector('div'));
console.log(css);
<div style="background-image: url('http://domain.com/images/image.jpg');background-size: cover;padding: 100px 0;">
</div>

Это расширяет некоторые объединенные стили, которые вы можете использовать в атрибуте style, например padding, который разделяется на paddingLeft, paddingRight, ... и т. Д.

С использованием некоторых дополнительных функций ES6 вышеупомянутое можно сжать до:

function parseCss(el) {
    let camelize = key => key.replace(/\-./g, m => m[1].toUpperCase());
    return Object.assign(
        ...Array.from(el.style, key => ({[camelize(key)]: el.style[key]})));
}
// Demo 
let css = parseCss(document.querySelector('div'));
console.log(css);
<div style="background-image: url('http://domain.com/images/image.jpg');background-size: cover;padding: 100px 0;">
</div>
1
trincot 11 Дек 2016 в 19:40

Возможно, вы сможете сделать что-то подобное, но в некоторых крайних случаях с контентом все равно не получится. Это не ваш случай верблюда, но это достаточно просто позвонить.

var x = document.getElementById("x");
var str = x.getAttribute("style"); //x.style.cssText;
console.log(str);
var rules = str.split(/\s*;\s*/g).reduce( function (details, val) {
    if (val) {
      var parts = val.match(/^([^:]+)\s*:\s*(.+)/);
      details[parts[1]] = parts[2];
    } 
    return details;
}, {});
console.log(rules);
div {
  font-family: Arial;
}
<div style="color: red; background: yellow; background-image: url('http://domain.com/images/image.jpg');background-size: cover;padding: 100px 0;" id="x">test</div>
0
epascarello 11 Дек 2016 в 19:08