Компоненты Фактическая ширина не получается при установке начальной позицииJavascript

Форум по Javascript
Ответить
Anonymous
 Компоненты Фактическая ширина не получается при установке начальной позиции

Сообщение Anonymous »

Я пытаюсь создать пользовательский компонент для обучения, который позволит контенту иметь возможность плавать на странице и быть перетаскиваемым. Я столкнулся с проблемой при установлении исходной позиции компонента в правой стороне страницы. Я использую систему проектирования кальцита и ArcGIS JS, и мне нужно отображать компонент ArcGIS-Sketch в моем пользовательском компоненте. Установка исходной позиции на верхнюю правую я пытаюсь позиционировать ее, используя левый атрибут CSS, однако, когда я пытаюсь получить позицию, она не работает из-за того, что виджет эскизов все еще отображается, поэтому я получаю неправильное значение ширины. Я попытался использовать запрос QuestionAnimationFrame, изменить размер наблюдателя и слушателя событий Slotchange, но он все еще не работает. Я также пытаюсь сделать компонент для обработки какого -либо контента, но я не уверен, что это глупо или нет. Я также знаю, что я мог бы использовать компонент диалога кальцита, но я пытаюсь сделать свой собственный учиться и для некоторых других проблем.
toggleSketchLayout()}>
toggleDock("draw")}>




< /code>
import html from './floater.html?raw';
import styleText from './floater.css?inline';
class Floater extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: "open" });

// Wait for Calcite's to be defined before injecting HTML
customElements.whenDefined("calcite-action").then(() => {
// Initial state
this.isDragging = false;
this.offsetX = 0;
this.offsetY = 0;

// Link the css file
const style = document.createElement("style");
style.textContent = styleText
this.shadowRoot.appendChild(style);

// Inject template from raw HTML
const template = document.createElement("template");
template.innerHTML = html;
this.shadowRoot.appendChild(template.content.cloneNode(true));

this._init();
});
}

_init() {
this.floater = this.shadowRoot.querySelector(".floater");
this.heading = this.shadowRoot.querySelector(".floater-heading")
this.hTitle = this.shadowRoot.querySelector(".floater-heading-title");
this.originalhTitle = this.hTitle?.outerHTML || null;
this.headingEnd = this.shadowRoot.querySelector(".floater-heading-end")
this.closeButton = this.shadowRoot.querySelector("calcite-action");
this.originalCloseButton = this.closeButton?.outerHTML || null
this.contentSlot = this.shadowRoot.querySelector('slot:not([name])');

requestAnimationFrame(() => {
this._onReady()
});
}

// Trigger after component has been created
_onReady() {
this._updateTitle();
this._updateClose();
this._setScale();

window.addEventListener("resize", this._onResize);
this.heading.addEventListener("mousedown", this._onMouseDown);
this.closeButton.addEventListener("click", () => this.remove());

// Wait for the next repaint to ensure rendering is complete
requestAnimationFrame(() => {
this._setInitalPosition();
});
}

// Trigger on component delete
disconnectedCallback() {
window.removeEventListener("resize", this._onResize)
document.removeEventListener("mousemove", this._onMouseMove);
document.removeEventListener("mouseup", this._onMouseUp);
}

static get observedAttributes() {
return ["title", "close-disabled", "scale"];
}

// Trigger when attribute changes
attributeChangedCallback(name, oldValue, newValue) {
if (name === "title") this._updateTitle();
if (name === "close-disabled") this._updateClose();
if (name === "scale") this._setScale();
}

_onResize = () => {
console.log("resize")
}

// This function will either create or delete, depending on the attribute
_handleElementLife = (atr, currentEl, originalEl, parent) => {
// If empty then remove the element
if (!atr.trim()) {
if (currentEl) currentEl.remove()
return null;
}

// Add the element
if (!currentEl && originalEl) {
const temp = document.createElement("div");
temp.innerHTML = originalEl;
currentEl = temp.firstElementChild;
parent.insertBefore(currentEl, parent.firstChild);
}

if (currentEl) {
currentEl.textContent = atr;
return currentEl;
}
}

_updateTitle = () => {
const titleAtr = this.getAttribute("title") || "";
this.hTitle = this._handleElementLife(titleAtr, this.hTitle, this.originalhTitle, this.heading)
}

_updateClose = () => {
const disabled = this.hasAttribute("close-disabled");
if (disabled) {
this.closeButton.remove();
this.closeButton = null;
return;
}

// Add the element
if (!this.closeButton && this.originalCloseButton) {
const temp = document.createElement("div");
temp.innerHTML = this.originalCloseButton;
this.closeButton = temp.firstElementChild;
this.headingEnd.append(this.closeButton);
}
}

_setInitalPosition = () => {
const positionAtr = this.getAttribute("position") || "center";

// Reset existing positions
this.floater.style.top = "0px";
this.floater.style.left = "0px";
this.floater.style.transform = "none";

console.log(this.floater)
switch (positionAtr) {
case "center":
this.floater.style.top = "50%";
this.floater.style.left = "50%";
this.floater.style.transform = "translate(-50%, -50%)";
break;
case "top-left":
this.floater.style.top = "10px";
this.floater.style.left = "10px";
break;
case "top-right":
console.log(window.innerWidth)
console.log("width", this.floater.offsetWidth);
this.floater.style.top = "10px";
this.floater.style.left = `${window.innerWidth - this.floater.offsetWidth}px`;
break;
case "bottom-left":
this.floater.style.bottom = "10px";
this.floater.style.left = "10px";
break;
case "bottom-right":
this.floater.style.bottom = "10px";
this.floater.style.left = `${window.innerWidth - this.floater.offsetWidth}px`;
break;
}
// Change transform to position style
if (positionAtr === "center") {
requestAnimationFrame(() => this._convertTransformToPosition());
}
}

_convertTransformToPosition = () => {
const rect = this.floater.getBoundingClientRect();
const style = getComputedStyle(this.floater);
const transform = style.transform;

if (transform && transform !== "none") {
const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;

const actualLeft = rect.left + scrollLeft;
const actualTop = rect.top + scrollTop;

this.floater.style.left = `${actualLeft}px`;
this.floater.style.top = `${actualTop}px`;
this.floater.style.transform = "none";
}
}

_setScale = () => {
let scaleAtr = this.getAttribute("scale") || "s";
if(this.closeButton) this.closeButton.dataset.scale = scaleAtr
}

// Handle floater movement
_onMouseDown = (e) => {
this.isDragging = true;

// Compute position based on visual location
const rect = this.floater.getBoundingClientRect();
this.offsetX = e.clientX - rect.left;
this.offsetY = e.clientY - rect.top;

document.addEventListener("mousemove", this._onMouseMove);
document.addEventListener("mouseup", this._onMouseUp);
};

_onMouseMove = (e) => {
if (!this.isDragging) return;
let newLeft = e.clientX - this.offsetX;
let newTop = e.clientY - this.offsetY;
const windowWidth = window.innerWidth;
const windowHeight = window.innerHeight;
const floaterWidth = this.floater.offsetWidth;
const floaterHeight = this.floater.offsetHeight;

newLeft = Math.max(0, Math.min(windowWidth - floaterWidth, newLeft));
newTop = Math.max(0, Math.min(windowHeight - floaterHeight, newTop));

this.floater.style.left = `${newLeft}px`;
this.floater.style.top = `${newTop}px`;
}

_onMouseUp = () => {
this.isDragging = false;
document.removeEventListener("mousemove", this._onMouseMove);
document.removeEventListener("mouseup", this._onMouseUp);
}
}

if (!customElements.get("custom-floater"))
customElements.define("custom-floater", Floater);
< /code>
.floater{
/* min-width: 150px; */
display: block;
position: fixed;
top: 0;
left: 0;
z-index: var(--calcite-z-index-modal);
box-sizing: border-box;
border-radius: 0.25rem;
background-color: var(--floater-background-color);
font-family: var(--calcite-sans-family);
box-shadow: var(--calcite-shadow-sm);
}

.floater-heading{
display: flex;
flex-direction: row;
flex-wrap: nowrap;
border-bottom: 1px solid var(--calcite-color-border-3);
cursor: move;
user-select: none;
}

.floater-heading-title{
padding: var(--calcite-spacing-xs) var(--calcite-spacing-md-plus);
font-weight: var(--calcite-font-weight-medium);
font-size: var(--calcite-font-size-0);
color: var(--calcite-color-text-1);
}

.floater-heading-end{
margin-left: auto;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
}

.floater-close{
height: 100%;
width: auto;
background-color: transparent;
border: 0;
cursor: pointer;
}

.floater-content{
padding: var(--calcite-spacing-md);
}
< /code>














Подробнее здесь: https://stackoverflow.com/questions/796 ... l-position
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Javascript»