我想制作一个Web组件标签,其中包含具有一些附加功能的编辑器。我现在正在使用ACE-JSON编辑器。
主要代码是这个,我确实还有其他一些js文件。
<!DOCTYPE HTML>
<html>
<head>
<title>JSONEditor</title>
<meta charset="utf-8">
<link href="https://cdnjs.cloudflare.com/ajax/libs/jsoneditor/5.32.5/jsoneditor.css" rel="stylesheet" type="text/css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsoneditor/5.32.5/jsoneditor.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2014-11-29/FileSaver.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<script src="app.js"></script>
<!-- <script src="worker.js"></script> -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<style>
html,
body {
font: 11pt sans-serif;
}
#jsoneditor {
width: 700px;
height: 600px;
}
#paste,
#link,
#file {
margin-top: 25px;
align-content: center;
}
</style>
</head>
<body>
<div class="container-fluid">
<h1 align="center">Load and save JSON documents</h1>
<br><br><br>
<div class="row">
<div class="col">
<div id="jsoneditor"></div>
</div>
<div class="col col-centered">
<div class="row">
<div class="col">
<select id="test" name="form_select" onchange="showDiv(this)">
<option value="paste">paste json</option>
<option value="file">Upload file</option>
<option value="link">use link</option>
</select>
</div>
<div class="col">
<p>
Save a JSON document: <input type="button" id="saveDocument" value="Save" />
</p>
</div>
</div>
<div class="row">
<div class="col">
<div id="file" style="display: none;" class="col-sm col-centered">
Load a JSON document: <input type="file" id="loadDocument" value="Load" />
<button class="button" onclick="readFile()">LOAD JSON</button>
</div>
<div id="paste" style="display: none;" class="col-sm col-centered">
<h3>Paste JSON data </h3>
<textarea id="myText" rows="4" cols="50"></textarea>
<button class="button" onclick="loadText()">LOAD JSON</button>
</div>
<div id="link" style="display: none;" class="col-sm col-centered">
<h3>URL</h3>
<input type="text" id="url">
<button class="button" onclick="urlOnclick()">LOAD JSON</button>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
<script>
var options = {
mode: 'tree',
modes: ['code', 'form', 'text', 'tree', 'view'], // allowed modes
onError: function (err) {
alert(err.toString());
},
onModeChange: function (newMode, oldMode) {
console.log('Mode switched from', oldMode, 'to', newMode);
}
};
// create the editor
var editor = new JSONEditor(document.getElementById('jsoneditor'), options);
// Save a JSON document
document.getElementById('saveDocument').onclick = function () {
// Save Dialog
fname = window.prompt("Save as...");
// Check json extension in file name
if (fname.indexOf(".") == -1) {
fname = fname + ".json";
} else {
if (fname.split('.').pop().toLowerCase() == "json") {
// Nothing to do
} else {
fname = fname.split('.')[0] + ".json";
}
}
var blob = new Blob([editor.getText()], { type: 'application/json;charset=utf-8' });
saveAs(blob, fname);
};
</script>
</html>
如何将其包装在Web组件中? 我使用JS进行了尝试,但是大多数教程都给出了一个简单标签的小例子。该网站的大部分内容都指向聚合物,但我没有找到关于我想做什么的适当参考。 请您为我提供指导或提供一些参考。
答案 0 :(得分:0)
第三方库通常不设计用于Web组件。
您将遇到的问题是jQuery和jQuery插件的使用。创建Web组件时,您正在#document-fragment
的{{1}}组件中创建#shadowRoot
。这意味着我们用于选择元素(shadowDOM
)的标准DOM语句将无法在document.getElementById(...)
中选择元素。这是因为shadowDOM
与根文档是隔离的。因此,您只能找到简单标签的示例。
JSONEditor,例如uses document.createElement()
extensively。
我已将您的HTML / JS转换为Web组件 ,由于上述原因,该组件无法正常运行 。这至少将向您展示如何进行更复杂的示例。
如下面的示例所示,很容易将外部脚本和样式表加载到组件中。可以使用模块shadowDOM
的语法,而不是创建脚本标签,但是这些库不支持该语法。
以下是关键的运动部件:
import
标记内,该标记用于保存自定义元素的DOM元素<template>
customElements.define('my-editor', MyEditor);
放入HTML文件有关详细信息,请参阅源代码注释。
<my-editor></my-editor>
class MyEditor extends HTMLElement {
constructor () {
super();
this.requiredScripts = [
'https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js',
'https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js',
'https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js',
'https://cdnjs.cloudflare.com/ajax/libs/jsoneditor/5.32.5/jsoneditor.js',
'https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2014-11-29/FileSaver.min.js',
];
// Grab a reference to the custom element
let template = document.getElementById('my-custom-editor');
// Get the #document-fragment
let templateContent = template.content;
// Place the template from the Web Component in to the active DOM
this.attachShadow({ mode: 'open' }).appendChild(templateContent.cloneNode(true));
}
// lifecycle hook that fires when custom element is placed into DOM
connectedCallback () {
// load required external resources
this.loadScripts(0);
}
loadScripts (idx) {
const tag = document.createElement('script');
tag.src = this.requiredScripts[idx];
tag.onload = () => {
if (idx < this.requiredScripts.length - 1) {
// when a script has finished, go get the next one
this.loadScripts(++idx);
} else {
// Once all the script files are loaded, initialize the working parts of the component
this.initEditor();
}
}
tag.onload.bind(this);
document.head.appendChild(tag);
}
initEditor () {
// Need a reference to the #document-fragment
// Every instance of "document" in this method has been replaced with "component"
const component = document.getElementById('my-custom-editor').content;
const options = {
mode: 'tree',
modes: ['code', 'form', 'text', 'tree', 'view'], // allowed modes
onError: function (err) {
alert(err.toString());
},
onModeChange: function (newMode, oldMode) {
console.log('Mode switched from', oldMode, 'to', newMode);
}
};
// create the editor IN THE compoent (rathar than the DOM)
var editor = new JSONEditor(component.getElementById('jsoneditor'), options);
component.getElementById('saveDocument').onclick = function () {
fname = window.prompt("Save as...");
if (fname.indexOf(".") == -1) {
fname = fname + ".json";
} else {
if (fname.split('.').pop().toLowerCase() == "json") {
} else {
fname = fname.split('.')[0] + ".json";
}
}
var blob = new Blob([editor.getText()], {
type: 'application/json;charset=utf-8'
});
saveAs(blob, fname);
};
}
}
customElements.define('my-editor', MyEditor);
html,
body {
font: 11pt sans-serif;
}