Files
js/dialog.html
2025-11-26 22:34:43 +01:00

235 lines
6.1 KiB
HTML

<!DOCTYPE html>
<html lang="fr">
<head>
<title>Ma Page</title>
</head>
<body>
<h1>Titre de la page</h1>
<style>
.dialog {
position: absolute;
background: #f9f9f9;
border: 1px solid #999;
border-radius: 8px;
box-shadow: 0 4px 10px rgba(0,0,0,0.2);
overflow: hidden;
resize: none;
z-index: 10;
}
.dialog-bar {
height: 30px;
background: #2979ff;
color: white;
line-height: 30px;
padding: 0 8px;
font-weight: bold;
cursor: move;
user-select: none;
position: relative;
}
.dialog-close {
position: absolute;
top: 0;
right: 0;
width: 30px;
height: 30px;
line-height: 30px;
text-align: center;
cursor: pointer;
font-size: 20px;
}
.dialog-close:hover {
background: rgba(255,255,255,0.2);
}
.dialog-content {
width: 100%;
height: calc(100% - 30px);
overflow: auto;
padding: 8px;
box-sizing: border-box;
}
/* Resizers */
.resizer {
position: absolute;
background: transparent;
}
.resizer-n, .resizer-s {
height: 6px; width: 100%; cursor: ns-resize;
}
.resizer-e, .resizer-w {
width: 6px; height: 100%; cursor: ew-resize;
}
.resizer-n { top: -3px; left: 0; }
.resizer-s { bottom: -3px; left: 0; }
.resizer-e { right: -3px; top: 0; }
.resizer-w { left: -3px; top: 0; }
/* corners */
.resizer-ne, .resizer-nw, .resizer-se, .resizer-sw {
width: 10px; height: 10px;
position: absolute;
background: transparent;
}
.resizer-ne { top: -3px; right: -3px; cursor: nesw-resize; }
.resizer-nw { top: -3px; left: -3px; cursor: nwse-resize; }
.resizer-se { bottom: -3px; right: -3px; cursor: nwse-resize; }
.resizer-sw { bottom: -3px; left: -3px; cursor: nesw-resize; }
</style>
<script>
class Dialog {
constructor(box, title, content) {
this._id = 'dialog_' + Date.now();
this._box = box;
this._title = title;
this._content = content;
this.createDialog();
}
createDialog() {
// --- conteneur principal ---
this.el = document.createElement('div');
this.el.className = 'dialog';
Object.assign(this.el.style, {
top: this._box.top + 'px',
left: this._box.left + 'px',
width: this._box.width + 'px',
height: this._box.height + 'px'
});
// --- barre de titre ---
const bar = document.createElement('div');
bar.className = 'dialog-bar';
bar.textContent = this._title;
const close = document.createElement('span');
close.className = 'dialog-close';
close.innerHTML = '&times;';
bar.appendChild(close);
this.el.appendChild(bar);
// --- conteneur contenu ---
const container = document.createElement('div');
container.className = 'dialog-content';
if (typeof this._content === 'string')
container.innerHTML = this._content;
else
container.appendChild(this._content);
this.el.appendChild(container);
document.body.appendChild(this.el);
// --- interactions ---
this.makeDraggable(bar);
this.makeResizable();
close.addEventListener('click', () => this.close());
}
makeDraggable(bar) {
let isDragging = false;
let offsetX, offsetY;
bar.addEventListener('mousedown', (e) => {
isDragging = true;
const rect = this.el.getBoundingClientRect();
offsetX = e.clientX - rect.left;
offsetY = e.clientY - rect.top;
document.body.style.userSelect = 'none';
});
document.addEventListener('mouseup', () => {
isDragging = false;
document.body.style.userSelect = '';
});
document.addEventListener('mousemove', (e) => {
if (!isDragging) return;
this.el.style.left = (e.clientX - offsetX) + 'px';
this.el.style.top = (e.clientY - offsetY) + 'px';
});
}
makeResizable() {
const sides = ['n', 'e', 's', 'w', 'ne', 'nw', 'se', 'sw'];
sides.forEach(side => {
const r = document.createElement('div');
r.className = 'resizer resizer-' + side;
this.el.appendChild(r);
r.addEventListener('mousedown', (e) => this.startResize(e, side));
});
}
startResize(e, side) {
e.preventDefault();
const startX = e.clientX;
const startY = e.clientY;
const rect = this.el.getBoundingClientRect();
const startWidth = rect.width;
const startHeight = rect.height;
const startLeft = rect.left;
const startTop = rect.top;
const onMove = (ev) => {
const dx = ev.clientX - startX;
const dy = ev.clientY - startY;
if (side.includes('e'))
this.el.style.width = (startWidth + dx) + 'px';
if (side.includes('s'))
this.el.style.height = (startHeight + dy) + 'px';
if (side.includes('w')) {
this.el.style.width = (startWidth - dx) + 'px';
this.el.style.left = (startLeft + dx) + 'px';
}
if (side.includes('n')) {
this.el.style.height = (startHeight - dy) + 'px';
this.el.style.top = (startTop + dy) + 'px';
}
};
const onUp = () => {
document.removeEventListener('mousemove', onMove);
document.removeEventListener('mouseup', onUp);
};
document.addEventListener('mousemove', onMove);
document.addEventListener('mouseup', onUp);
}
close() {
if (this.el && this.el.parentElement)
this.el.parentElement.removeChild(this.el);
}
} ;
// --- helper de création ---
function createDialog(box, title, content) {
return new Dialog(box, title, content);
}
function lancerAuDemarrage() {
createDialog({ top: 100, left: 100, width: 400, height: 300 }, "Exemple Texte",
"<p>Bonjour 👋</p><p>Tu peux redimensionner et déplacer cette fenêtre.</p>"
);
}
// Appel direct de la fonction
lancerAuDemarrage();
</script>
</body>
</html>