我正在尝试创建网站构建器(拖放页面构建器),并且想知道当某人更改元素的样式时在哪里存储样式。例如,在WordPress中,您可以在Customizer中键入自己的自定义CSS(图片示例:https://i.imgur.com/qaUiVl6.png)
在其他页面构建器(例如Wix或Google Chrome Inspect Element)中,您可以单击按钮来启用或禁用样式。
在对页面进行当前/实时CSS编辑时,这些样式在哪里以及如何保存? (我不是在谈论数据库,因为代码尚未保存。我是在进行现场更改时谈论这些“临时/实时” CSS样式在哪里保存?)
答案 0 :(得分:6)
您可以使用CSSStyleSheet API在内存中生成样式表,然后使用insert和delete方法随意在样式表中添加或删除规则。当用户完成修改后,您可以将生成的样式表传递回服务器端以保存烫发。
参考文档可以在这里找到: https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet#Methods
兼容性是IE9 +和所有其他现代浏览器,因此覆盖范围广。
下面的快速且肮脏的示例。
var style = (function() {
// Create the <style> tag
var style = document.createElement("style");
// Add the <style> element to the page
document.head.appendChild(style);
return style;
})();
function AddRule(){
//append rule from textbox to ss here
style.sheet.insertRule(document.getElementById("cssIn").value, 0);
document.getElementById("appliedRules").innerHTML = '';
var rules = style.sheet.cssRules;
for (var r in rules) {
if(rules[r].cssText){
document.getElementById("appliedRules").innerHTML += '<br>' + rules[r].cssText;
}
}
}
//enable this to see your special prize in the console
//console.log(style.sheet);
<div class="test"> here we go</div>
Add Rule: <input type="text" id="cssIn" value=".test {color:blue}">
<button type="button" onClick="AddRule();">Add</button>
<div id="appliedRules"></div>
答案 1 :(得分:3)
这里是一个超级简单的概念证明,它演示了如何使用纯JavaScript来完成此任务。只需单击“保存”按钮,即可查看textarea中的CSS应用于页面。 CSS仅存储为textarea元素的输入值。如注释中提到的,noobius基本上将其存储在“内存中”。您还可以通过使用localstorage甚至iframe或shadow dom使其变得更加复杂,从而仅影响“预览”窗格。但这只是一个简单的演示。
function saveStyles() {
document.querySelector('#styles').innerHTML = document.querySelector('#styleText').value;
}
<style id="styles"></style>
<textarea id="styleText">body{background:red;}</textarea>
<button onclick="saveStyles()">Save</button>
答案 2 :(得分:0)
这是将样式表放入内存并通过Blob URL加载的替代方法。
在某些情况下,它的行为比内联样式更像真实的样式表,这在某些情况下可能是理想的。它也可以在通过内容安全策略阻止内联样式的网页上运行(允许提供的Blob URL)。
(function() {
var styles = document.getElementById('styles');
var save = document.getElementById('save');
var link = null;
function getLink() {
if (!link) {
link = document.createElement('link');
link.rel = 'stylesheet';
document.head.appendChild(link);
}
return link;
}
save.addEventListener('click', function() {
var link = getLink();
if (link.href) {
URL.revokeObjectURL(link.href);
}
link.href = URL.createObjectURL(new Blob([styles.value], {type: 'text/css'}));
});
})();
#styles {
display: block;
width: 95%;
}
<textarea id="styles" rows="5">body {
background: green;
}
</textarea>
<button id="save">Save</button>
答案 3 :(得分:0)
根据讨论,我建议为每个元素ID使用单独的样式。这是草图。
<script>
function setStyle(id, style_text)
{
var style_id = "style_" + id;
var style_forId = "#" + id + " " + style_text;
var styleDom = document.getElementById(style_id);
if(!styleDom)
{
styleDom = document.createElement('style');
styleDom.type = 'text/css';
styleDom.id = style_id;
styleDom.innerHTML = style_forId;
document.getElementsByTagName("head")[0].appendChild(styleDom);
}
else
{
styleDom.innerHTML = style_forId;
}
}
</script>
<button id="myButton1" type="button" >My Button 1</button>
<button id="myButton2" type="button" >My Button 2</button>
<br>
<button onclick="setStyle('myButton1', '{color:red}'); "> Set Red color for myButton1 </button>
<br>
<button onclick="setStyle('myButton2', '{color:red}'); "> Set Red color for myButton2 </button>
<br>
<button onclick="setStyle('myButton1', '{color:green}'); "> Set Green color for myButton1 </button>
<br>
<button onclick="setStyle('myButton2', '{color:green}'); "> Set Green color for myButton2 </button>
<br>
答案 4 :(得分:0)
这里的答案集中在构建样式表和使用浏览器作为DOM api的一部分提供的常用方法添加CSS规则的方法上。这些是网络上任何UI框架都将使用的基础函数调用。
但是当您询问“此文件存储在哪里?”时。从某种意义上讲,您在问如何管理“状态”。如果您查看原始的jQuery / Web应用程序构建框架,例如Backbone.js,它的座右铭是“使模型脱离DOM”。因此,通常,用户界面构建工具的“元素”本身将表示为组件/模型。
如果您查看以视图为中心的框架,例如React或Vue,则更复杂的Web应用程序将使用Redux这样的框架来处理“状态”,该状态存储在单个对象存储中。这表示页面上所有组件的当前选项。
因此,最终,非玩具类所见即所得(WYSIWYG)网络编辑器可能会将每个“元素”都视为一个根据输入状态呈现其样式的组件。
这与控制状态变化的可控方式相结合,可以管理复杂的UI。例如,click方法将触发一个动作,该动作的行为类似于事件处理程序的名称,从而触发功能(在redux世界中,reduceors),最终改变状态(在我们的示例中为元素的颜色)。
在复杂的web-app / web-editor中对DOM进行简化的低级调用将被抽象掉。
答案 5 :(得分:0)
好答案已经在这里提出了不同的观点。
const style = document.createElement("style");
document.head.appendChild(style);
style.sheet.insertRule(`
header {
background: 'black'
}
`, 0);
我会采用这个简单的想法,并通过这样的数据结构来控制它。
// A JS Object to control and modify CSS styles on.
const css = {
header: {
background: 'black',
border: '2px green solid',
'font-size': '12px'
}
}
// Converts JS Object to CSS Text (This is not battle tested)
function objToCss(style) {
return Object.entries(style).reduce((styleString, [propName, propValue]) => {
propName = propName.replace(/[A-Z]/g, match => `-${match.toLowerCase()}`);
if (typeof propValue === 'object') {
return `${styleString}${propName}{${objToCss(propValue)}}`;
} else {
return `${styleString}${propName}:${propValue};`;
}
}, '')
}
// Setup
const style = document.createElement("style");
document.head.appendChild(style);
style.sheet.insertRule(objToCss(css), 0);
// Updates
css.header.border = '1px blue solid';
style.sheet.replace(objToCss(css), 0);