- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我创建了一个基于 js 的节点编辑器。我有一个 div 元素用作节点的父元素。尽管我将容器定义为父级,但您可以将节点移到父级边界之外。但是,您不能将它移到最后一个文档元素的下方。
重要的html代码是:
<button type="button" class="btn btn-primary" onclick="sendData(fetchData())">Send data</button>
<div id="node-container" class="node-container" style="height: 500px; width: 90%">
<svg id="svg"/>
</div>
<button type="button" class="btn btn-primary" onclick="sendData(fetchData())">Send data</button>
draggable 的 js 是:
$(this.domElement).draggable({
containment: 'parent',
cancel: '.connection,.output,.data',
drag: function(event, ui){
that.updatePosition();
}
});
也许我在育儿方面做错了,所以这里也是:
this.domElement = document.createElement('div');
document.getElementById('node-container').appendChild(this.domElement);
我没有太多地使用 JavaScript,但仍在学习中!
编辑:这里是节点容器的定义:
<div id="node-container" class="node-container" style="height: 500px; width: 90%">
</div>
完整的 StoryNode.js: https://hastebin.com/kiyoyekoce.js
// ===================================================================
// Node class. Represents a javascript version of the java Node class
// ===================================================================
var nodes = []; //Have second reduced node version running, maybe as a method in the Node? Call simple for loop in web-link
function StoryNode(name) {
this.name = name;
let that = this;
nodes.push(this);
// Add our graphical representation
this.domElement = document.createElement('div');
document.getElementById('node-container').appendChild(this.domElement);
this.domElement.classList.add('node');
this.domElement.classList.add('container-fixed');
this.domElement.setAttribute('title', name.replace("Node",""));
let remDom = document.createElement('div');
remDom.classList.add('delete-node');
remDom.innerHTML ='<i class="fa fa-trash" aria-hidden="true"/>';
this.domElement.appendChild(remDom);
remDom.onclick = function (e) {
that.detachAll();
for( let i = 0; i < nodes.length; i++){
if ( nodes[i] === that) {
nodes.splice(i, 1);
}
}
that.domElement.parentElement.removeChild(that.domElement);
};
// Add the node body
// Directories
var innerDomGroup = document.createElement('div');
innerDomGroup.classList.add('row');
this.domElement.appendChild(innerDomGroup);
// Outputs
this.outputDomGroup = document.createElement('div');
this.outputDomGroup.classList.add('col-fixed-small-1');
innerDomGroup.appendChild(this.outputDomGroup);
// Inner Data
this.dataDomGroup = document.createElement('div');
this.dataDomGroup.classList.add('col-fixed-medium-1');
innerDomGroup.appendChild(this.dataDomGroup);
// Inputs
this.inputDomGroup = document.createElement('div');
this.inputDomGroup.classList.add('col-fixed-small-1');
innerDomGroup.appendChild(this.inputDomGroup);
//Node data
this.inputs = [];
this.data = [];
this.outputs = [];
}
StoryNode.prototype.addInput = function(name, inputType){
let input = new NodeInput(name, inputType);
input.node = this;
this.inputs.push(input);
this.inputDomGroup.appendChild(input.domElement);
return input;
};
StoryNode.prototype.addOutput = function(name, outputType){
let output = new NodeOutput(name, outputType);
output.node = this;
this.outputs.push(output);
this.outputDomGroup.appendChild(output.domElement);
return output;
};
StoryNode.prototype.addData = function(name, outputType){
let data = new NodeData(name, outputType);
data.node = this;
this.data.push(data);
this.dataDomGroup.appendChild(data.domElement);
return data;
};
StoryNode.prototype.ownsInput = function(input){
for(let i = 0; i < this.inputs.length; i++){
if(this.inputs[i] === input)
return true;
}
return false;
};
Node.prototype.ownsOutput = function(output){
for(let i = 0; i < this.outputs.length; i++){
if(this.outputs[i] === output)
return true;
}
return false;
};
StoryNode.prototype.detachAll = function(output){
for(let item of this.inputs){
if(item.output)
item.output.detachInput();
}
for(let item of this.outputs){
if(item.input)
item.detachInput();
}
};
StoryNode.prototype.updatePosition = function(){
for(let j = 0; j < this.outputs.length; j++){
if(this.outputs[j].input != null){
let oP = this.outputs[j].getOutputPoint();
let iP = this.outputs[j].input.getAttachPoint();
let pStr = this.createPath(iP, oP);
this.outputs[j].input.path.setAttributeNS(null, 'd', pStr);
}
}
for(let j = 0; j < this.inputs.length; j++){
if(this.inputs[j].output != null){
let iP = this.inputs[j].getAttachPoint();
let oP = this.inputs[j].output.getOutputPoint();
let pStr = this.createPath(iP, oP);
this.inputs[j].path.setAttributeNS(null, 'd', pStr);
}
}
};
StoryNode.prototype.createPath = function(a, b){
let diff = {
x: b.x - a.x,
y: b.y - a.y
};
let pathStr = 'M' + a.x + ',' + a.y + ' ';
pathStr += 'C';
pathStr += a.x + diff.x / 3 * 2 + ',' + a.y + ' ';
pathStr += a.x + diff.x / 3 + ',' + b.y + ' ';
pathStr += b.x + ',' + b.y;
return pathStr;
};
StoryNode.prototype.moveTo = function(point){
this.domElement.style.top = point.y + 'px';
this.domElement.style.left = point.x + 'px';
this.updatePosition();
};
StoryNode.prototype.initUI = function(){
let that = this;
// Make draggable
// noinspection JSValidateTypes
$(this.domElement).draggable({
containment: 'parent',
cancel: '.connection,.output,.data',
drag: function(event, ui){
that.updatePosition();
}
});
//Mak node design smaller as it holds no data inputs
if(this.data.length === 0) {
this.domElement.classList.remove('container-fixed');
this.domElement.classList.add('container-fixed-min');
this.dataDomGroup.classList.remove('col-fixed-medium-1');
this.dataDomGroup.classList.add('col-fixed-medium-1-min');
}
// Fix positioning
this.domElement.style.position = 'absolute';
document.body.appendChild(this.domElement);
// Update Visual
this.updatePosition();
};
// Node 1
let node = new StoryNode('Page');
// Move to initial positions
node.moveTo({x: 150, y: 20});
// Connect Nodes
// Add to DOM
node.initUI();
body{
background-color: #101010;
color: #d4d4d4;
font-family: sans-serif;
}
.node:before{
content:attr(title) " ";
display: block;
border-top-left-radius:.75em;
border-top-right-radius:.75em;
background-color:#6e6e6e;
padding:0.1em .3em 0em;
margin:-.1em -.3em 0.2em;
}
.node{
background-color: #4e4e4e;
border-radius: .75em;
display: inline-block;
padding:0.1em .3em .25em;
position:absolute;
cursor: move;
}
.connection:after{
position:absolute;
border:solid 1px #dedede;
background-color: #2e2e2e;
width:0.5em;
height:0.5em;
border-radius:0.5em;
}
.delete-node{
display: inline-block;
font-weight: 400;
text-align: center;
white-space: nowrap;
vertical-align: middle;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
font-size: 1rem;
line-height: 1.5;
transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
position:absolute;
color: #b8b8b8;
background-color: transparent;
border-radius:0.5em;
width:22px;
height:22px;
cursor: default;
top: 3px;
right: 8px;
}
.connection.filled:after{
border:solid 1px transparent;
}
.connection:hover:after{
border-color:red;
}
.output{
left: .1em;
top:.1em;
cursor: pointer;
}
.input{
left: 2em;
top: .1em;
cursor: pointer;
}
.connection{
width:100%;
position:relative;
padding-right:0.5em;
cursor:pointer;
}
.connection:after{
content:"";
right:0em;
top:0.25em;
}
.filled-node:after{
background-color: #d4d9de;
}
.empty-node:after{
border: 2px solid #d4d9de;
}
.filled-boolean:after{
background-color: #4f8fde;
}
.empty-boolean:after{
border: 2px solid #4f8fde;
}
svg{
position:absolute;
top:0px;
left:0px;
z-index:-100;
width:100%;
height:100%;
}
textarea {
resize: none;
}
/* The switch - the box around the slider */
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
/* Hide default HTML checkbox */
.switch input {
opacity: 0;
width: 0;
height: 0;
}
/* The slider */
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked + .slider {
background-color: #2196F3;
}
input:focus + .slider {
box-shadow: 0 0 1px #2196F3;
}
input:checked + .slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
.round-edge {
border-radius: 15px;
}
.container-fixed {
width: 200px !important;
}
.container-fixed-min {
width: 100px !important;
}
.col-fixed-small-1 {
width: 5px;
}
.col-fixed-small-2 {
width: 5px;
}
.col-fixed-medium-1 {
width: 180px;
padding-left: 15px;
margin-right: -12px;
}
.col-fixed-medium-1-min {
width: 80px;
padding-left: 15px;
margin-right: -12px;
}
.node-container {
background-color: #2e2e2e;
border-radius: 10px;
height: 500px;
width: 90%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js"></script>
<div id="node-container" class="node-container">
<svg id="svg"/>
</div>
<button type="button" class="btn btn-primary">Send data</button>
最佳答案
我怀疑问题出在您追加元素时。如果在初始化 draggable 时没有附加它,它可能无法理解 parent
关系。
考虑以下示例:
$(function() {
function addNode(title, content, tObj) {
if (title == undefined) {
title = "New Node";
}
if (content == undefined) {
content = "<p></p>";
}
if (tObj == undefined) {
tObj = $("#node-container");
}
var node = $("<div>", {
class: "node-element"
}).appendTo(tObj);
$("<div>", {
class: "node-title"
}).html(title).appendTo(node);
$("<span>", {
class: "btn btn-delete-node"
}).html("x").click(function() {
var r = confirm("Are you sure you want to delete this node?");
if (r) {
$(this).closest(".node-element").remove();
}
}).appendTo($(".node-title", node));
$("<div>", {
class: "node-content"
}).html(content).appendTo(node);
node.draggable({
containment: 'parent',
handle: ".node-title",
cancel: '.connection,.output,.data',
stop: function(e, ui) {
// update position
}
});
}
$(".add-node-btn").click(function() {
addNode();
});
});
body {
background-color: #000;
font-family: "arial", san-seriff;
}
.node-container {
background-color: #2a2a2a;
border-radius: 10px;
margin: 3px;
}
.btn-primary {
border: 0;
border-radius: 6px;
padding: 4px;
background-color: #0000ff;
color: #FFF;
}
.node-container .node-element {
background-color: #212121;
border-radius: 6px;
border: 0;
width: 125px;
height: 75px;
}
.node-container .node-element .node-title {
background-color: #484848;
border-radius: 6px 6px 0 0;
border: 0;
min-height: 1em;
color: #fff;
text-align: center;
}
.node-container .node-element .node-title .btn-delete-node {
float: right;
padding-right: 6px;
cursor: pointer;
}
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<button type="button" class="btn btn-primary">Send data</button> <button type="button" class="btn btn-primary add-node-btn">Add Node</button>
<div id="node-container" class="node-container" style="height: 500px; width: 90%">
<svg id="svg" />
</div>
<button type="button" class="btn btn-primary">Send data</button>
由于您的示例代码不是最小的、完整的或可验证的示例,因此很难确定您的元素是在何时以及如何添加和初始化的。
希望对您有所帮助。
关于javascript - jQuery UI 可拖动未绑定(bind)到父边界,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54832431/
我目前正在寻找一些关于 jQuery 的建议,因为我认为我做错了,即使我得到了我想要的结果。 我想在更改时将输入的值更改为最接近的具有 .milestone 类的输入的值。我想要更改的输入是保持输入,
我已经阅读有关绑定(bind)、调用、申请的文章近一周了,对我来说仍然很复杂。我想我写的这个 jsfiddle 需要它们。然而,我没能做到,因为我仍然很困惑。 我尽力写了一些我上周从遇到这个问题的开发
我有一个项目生成代码。生成时间真的很长,所以我把它分成了多个项目,每个项目产生了整体的 20%。原始 POM 成为“父 POM”,子项依赖于它,仅包含一个单独的 Artifact ID 和一两个更改的
我正在使用局部 View 来创建父 subview 。我最理想的是父 View 上的提交按钮,用于保存子值。 我有以下模型。 public class Course { public int
我刚刚开始学习Rust,并且在理解所有权如何在我的案例中遇到一些麻烦: use std::ops::IndexMut; // =====================================
我是 JavaScript 新手,想了解更多有关它实例化父/子对象的顺序的信息。更具体地说,我想从编译器/浏览器的 Angular 理解以下代码片段。 var parent = { child:
我正在测试 Azure IaaS,并遇到了一个非常基本的问题。我有一个父 VHD 和子 VHD,已使用 csupload 将其作为页面 blob 上传,并且门户中显示图像和磁盘。然后我尝试将 pare
我的应用程序会定期为我坚持使用的对象请求更新 Core Data到网络服务。然后我需要更新我在主要上下文中拥有的对象(默认情况下 AppDelegate 中提供的对象)。编辑对象的不是用户,所以我需要
texT text text text text text 如何直接获取来自.menu ? 里面的 child 不应该采取。
我一直需要影响与其他元素相关的元素,但我的方法有点业余! 即到 // matched item where script is called from LINK 我使用; $(thi
我有两个表: 父子“类别”: id name parent_id 1 Food NULL 2 Pizza 1 3 Pasta
Linux 上的 Python 2.7.6。 我正在使用从父级继承的测试类。父类保存了许多子类共有的许多字段,我需要调用父类的 setUp 方法来初始化这些字段。调用 ParentClass.setU
我有一个处理图像、相册和相册类别的数据库。 一个专辑可以有多个专辑(子专辑),并且只有 1 级深度。 一张专辑仅属于一个专辑类别。 在这里做了一些研究,我相信最合适的数据库模型是这个 album_ca
我有一个关键字表,其中每个关键字都分配有一个 ID,并且是唯一的。我有第二个表,将父关键字的 ID 链接到子关键字的 ID。一个关键字最多可以有大约 800 个 child 或根本没有。 child
我经常使用这个 CSS 选择器 parent>child。我的设计在 Mozilla 和 Opera 中看起来不错。 但在 IE 中,它很糟糕。我知道 > 在 IE 中无法识别,但在 IE 中有什么替
我一直在用一个父对象构建一个系统,它在其中创建各种子对象,每个子对象都需要一个主对象才能运行。现在,到目前为止,我一直在创建 shared_ptr和 Child* ,所以当 Parent 和 所有 C
我从以下两个类中收到序列化兼容性错误。只有父类CommericalCustomer 实现了序列化。当具有如下所示的父/子关系时,使用可序列化接口(interface)的正确方法是什么? public
我正在开发一个程序并学习父/子进程。目前我的子进程是 exit(variable); 在我的 main() 中我有: signal(SIGCHLD, chldHandler); 在我的 main()
考虑以下两个具体类: public class A { protected void foo() { System.out.println("A foo"); bar
所以,我正在尝试建立这样的父/子类关系: class ParentClass where C : ChildClass { public void AddChild(C child)
我是一名优秀的程序员,十分优秀!