gpt4 book ai didi

javascript - jQuery UI 可拖动未绑定(bind)到父边界

转载 作者:行者123 更新时间:2023-11-29 23:05:40 25 4
gpt4 key购买 nike

我创建了一个基于 js 的节点编辑器。我有一个 div 元素用作节点的父元素。尽管我将容器定义为父级,但您可以将节点移到父级边界之外。但是,您不能将它移到最后一个文档元素的下方。 enter image description here

重要的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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com