Писал свою функцию для присвоения свойств к псевдоэлементам и заметил неведомую ошибку. Присваивание свойств идёт через добавления строк в styleSheet.
Когда в третьем случае вызываю функцию, почему то красится в синий первый элемент, хотя color для него я не ставил.
(function() {
var setPseudoElement = function(parameters) {
for (var element of parameters.elements.get()) {
if (!element.pseudoElements) element.pseudoElements = {
styleSheet: null,
before: {
index: null,
properties: null
},
after: {
index: null,
properties: null
}
};
var selector = (function() {
if (element.id) {
return '#' + element.id + '::' + parameters.pseudoElement;
} else {
var parentsList = $(element).parents().map(function() {
return this.tagName.toLowerCase();
}).get().reverse().join(' > ') + ' > ' + element.tagName.toLowerCase();
var elementClass = element.classList.length ? '.' + $(element.classList).get().join('.') : '';
var elementAttributes = element.hasAttributes() ? $(element.attributes).get().map(function(className) {
return className.nodeName !== 'class' ? className.nodeValue ? '[' + className.nodeName + '="' + className.nodeValue + '"]' : '[' + className.nodeName + '"]' : '';
}).join('') : '';
var elementNthChild = ':nth-child(' + ($(element).index() + 1) + ')';
return parentsList + elementClass + elementAttributes + elementNthChild + '::' + parameters.pseudoElement;
};
})();
if (!element.pseudoElements.styleSheet) {
if (document.styleSheets[0]) {
element.pseudoElements.styleSheet = document.styleSheets[0];
} else {
var styleSheet = document.createElement('style');
document.head.appendChild(styleSheet);
element.pseudoElements.styleSheet = styleSheet.sheet;
};
};
if (element.pseudoElements[parameters.pseudoElement].properties !== null && element.pseudoElements[parameters.pseudoElement].index !== null) {
element.pseudoElements.styleSheet.deleteRule(element.pseudoElements[parameters.pseudoElement].index);
};
if (typeof parameters.argument === 'object') {
if (!element.pseudoElements[parameters.pseudoElement].properties && !element.pseudoElements[parameters.pseudoElement].index) {
var newIndex = element.pseudoElements.styleSheet.rules.length || element.pseudoElements.styleSheet.cssRules.length || element.pseudoElements.styleSheet.length;
element.pseudoElements[parameters.pseudoElement].index = newIndex;
element.pseudoElements[parameters.pseudoElement].properties = parameters.argument;
};
var properties = '';
for (var property in parameters.argument) {
element.pseudoElements[parameters.pseudoElement].properties[property] = parameters.argument[property];
};
for (var property in element.pseudoElements[parameters.pseudoElement].properties) {
properties += property + ': ' + element.pseudoElements[parameters.pseudoElement].properties[property] + ' !important; ';
};
element.pseudoElements.styleSheet.addRule(selector, properties, element.pseudoElements[parameters.pseudoElement].index);
} else if (parameters.argument !== undefined && parameters.property !== undefined) {
} else if (parameters.argument !== undefined && parameters.property === undefined) {
} else {
console.error('Invalid values!');
return false;
};
};
};
$.fn.cssBefore = function(argument, property) {
setPseudoElement({
elements: this,
pseudoElement: 'before',
argument: argument,
property: property
});
};
})();
$(function() {
// Случай 1
$('.el0').cssBefore({
'content': '"Новый \'before\'"',
'color': 'green'
});
// Случай 2
$('.el1').cssBefore({
'content': '"Новый \'before\' №2"',
'color': 'blue'
});
// Случай 3
$('.el0').cssBefore({
'content': '"Новый \'before\' №3"'
});
});
.element {
width: 480px;
margin: 0 auto;
border: 2px solid red;
}
.element:before {
content: "Старый 'before'";
color: orange;
}
Почему в третьем случае красится в синий первый элемент? Как это исправить?
UPDATA:
Если выводить в консоль значения элементов после каждого присваивания, то выходят очень странные значения:
(function () { var i = 1; var setPseudoElement = function (parameters) { for (var element of parameters.elements.get()) { if (!element.pseudoElements) element.pseudoElements = {styleSheet: null, before: {index: null, properties: null}, after: {index: null, properties: null}}; var selector = (function () { if (element.id) { return '#' + element.id + '::' + parameters.pseudoElement; } else { var parentsList = $(element).parents().map(function () { return this.tagName.toLowerCase(); }).get().reverse().join(' > ') + ' > ' + element.tagName.toLowerCase(); var elementClass = element.classList.length ? '.' + $(element.classList).get().join('.') : ''; var elementAttributes = element.hasAttributes() ? $(element.attributes).get().map(function (className) { return className.nodeName !== 'class' ? className.nodeValue ? '[' + className.nodeName + '="' + className.nodeValue + '"]' : '[' + className.nodeName + '"]' : ''; }).join('') : ''; var elementNthChild = ':nth-child(' + ($(element).index() + 1) + ')'; return parentsList + elementClass + elementAttributes + elementNthChild + '::' + parameters.pseudoElement; }; })(); if (!element.pseudoElements.styleSheet) { if (document.styleSheets[0]) { element.pseudoElements.styleSheet = document.styleSheets[0]; } else { var styleSheet = document.createElement('style'); document.head.appendChild(styleSheet); element.pseudoElements.styleSheet = styleSheet.sheet; }; }; if (element.pseudoElements[parameters.pseudoElement].properties !== null && element.pseudoElements[parameters.pseudoElement].index !== null) { element.pseudoElements.styleSheet.deleteRule(element.pseudoElements[parameters.pseudoElement].index); }; if (typeof parameters.argument === 'object') { if (!element.pseudoElements[parameters.pseudoElement].properties && !element.pseudoElements[parameters.pseudoElement].index) { var newIndex = element.pseudoElements.styleSheet.rules.length || element.pseudoElements.styleSheet.cssRules.length || element.pseudoElements.styleSheet.length; element.pseudoElements[parameters.pseudoElement].index = newIndex; element.pseudoElements[parameters.pseudoElement].properties = parameters.argument; }; var properties = ''; for (var property in parameters.argument) { element.pseudoElements[parameters.pseudoElement].properties[property] = parameters.argument[property]; }; for (var property in element.pseudoElements[parameters.pseudoElement].properties) { properties += property + ': ' + element.pseudoElements[parameters.pseudoElement].properties[property] + ' !important; '; }; element.pseudoElements.styleSheet.addRule(selector, properties, element.pseudoElements[parameters.pseudoElement].index); console.log('Номер запуска: ' + Math.round(i / 2) + '; Номер присваивания элементу: ' + i); console.log({ 'Элемент 1': $('.el0:not(.el1)').get(0).pseudoElements, 'Элемент 2': $('.el0.el1').get(0).pseudoElements, 'Элемент 3': $('.el1:not(.el0)').get(0).pseudoElements }); i++; } else if (parameters.argument !== undefined && parameters.property !== undefined) { } else if (parameters.argument !== undefined && parameters.property === undefined) { } else { console.error('Invalid values!'); return false; }; }; }; $.fn.cssBefore = function (argument, property) { setPseudoElement ({ elements: this, pseudoElement: 'before', argument: argument, property: property }); }; })(); $(function() { // Случай 1 $('.el0').cssBefore({ 'content': '"Новый \'before\'"', 'color': 'green' }); // Случай 2 $('.el1').cssBefore({ 'content': '"Новый \'before\' №2"', 'color': 'blue' }); // Случай 3 $('.el0').cssBefore({ 'content': '"Новый \'before\' №3"' }); }); .element { width: 480px; margin: 0 auto; border: 2px solid red; } .element:before { content: "Старый 'before'"; color: orange; }
Если смотреть в консоль, то уже при первом вызове функции, элемент №1 имеет синий цвет и содержимое №3
Ответ
Думаю что я нашел проблему:
element.pseudoElements[parameters.pseudoElement].properties = parameters.argument;
где parameters.argument — это объект.
Когда мы делаем первый проход, мы задаем его для первого и второго элемента.
Когда на втором проходе мы меняем его для второго случая, он меняется и для первого тоже.
И вот пруф и решение
element.pseudoElements[parameters.pseudoElement].properties = Object.assign({}, parameters.argument);
Комментариев нет:
Отправить комментарий