如何在CSS和JS中创建可滚动/可接触的网格?

发布于 2025-02-10 01:54:06 字数 165 浏览 2 评论 0原文

我对如何用不确定的列和行制作网格感兴趣,这些列和行可以放入另一个Div中,而不会溢出到其他对象中或与父母大小混乱。

我希望它是正方形的,我正在使用尾风CSS,但我可以适应SCSS或Vanilla CSS。我也希望它在台式机上使用鼠标和触摸功能的设备可接触/可移动。

我将如何实现这一目标?

I'm interested in how I can make a grid with an undetermined amount of columns and rows that I can put inside another div and have it not spill into others objects or mess with the parent size.

I want it to be square and I'm using Tailwind CSS but I can adapt to SCSS or vanilla CSS. Also I want it to be touchable/moveable with a mouse on desktop and touch capable devices.

How would I go about accomplishing this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

心的位置 2025-02-17 01:54:06

假设我已经正确理解了您的问题,这是您可以做到的一种方法。我没有使用触摸设备对其进行测试,但是也不难对其进行修改以响应触摸事件。

const items = [
  ['a0', 'a1', 'a2'],
  ['b0', 'b1', 'b2'],
  ['c0', 'c1', 'c2']
];

let html = '';
for (let rowItems of items) {
  html += '<div class="row">';
  for (let item of rowItems) {
    html += '<div class="item">';
    html +=   item;
    html += '</div>';
  }
  html += '</div>';
}

const viewElem = document.querySelector('#view');
const outputElem = document.querySelector('#output');
outputElem.innerHTML = html;



let mouseStartPos = null;
let startOffset = null;

outputElem.addEventListener('mousedown', e => {
  outputElem.classList.remove('animate');
  mouseStartPos = {
    x: e.clientX,
    y: e.clientY
  };
  startOffset = {
    x: outputElem.offsetLeft - viewElem.offsetLeft,
    y: outputElem.offsetTop - viewElem.offsetTop
  };
});

window.addEventListener('mouseup', e => {
  mouseStartPos = null;
  startOffset = null;

  outputElem.classList.add('animate');
  const xGridOffset = -1 * Math.max(0, Math.min(Math.round((outputElem.offsetLeft - viewElem.offsetLeft) / -100), items.length - 1));
  const yGridOffset = -1 * Math.max(0, Math.min(Math.round((outputElem.offsetTop - viewElem.offsetTop) / -100), items[0].length - 1));
  outputElem.style.left = `${xGridOffset * 100}px`;
  outputElem.style.top = `${yGridOffset * 100}px`;  
});

window.addEventListener('mousemove', e => {
  if (mouseStartPos) {
    const xOffset = mouseStartPos.x - e.clientX;
    const yOffset = mouseStartPos.y - e.clientY;
    outputElem.style.left = `${-1 * xOffset + startOffset.x}px`;
    outputElem.style.top = `${-1 * yOffset + startOffset.y}px`;
  }
});
#view {
  width: 100px;
  height: 100px;
  overflow: hidden;
  
  border: 2px solid blue;
}

#output {
  position: relative;
}

.row {
  display: flex;  
}

.item {
  display: flex;
  min-width: 100px;
  width: 100px;
  height: 100px;
  box-sizing: border-box;
  
  justify-content: center;
  align-items: center;
  border: 1px solid red;
}

#output.animate {
  transition: left 1s ease 0s, top 1s ease 0s;
}
Drag it!<br/>
<br/>
<div id="view">
  <div id="output"></div>
</div>

Assuming I've understood your question correctly, here is one way you could do it. I haven't tested it with a touch device but it shouldn't be hard to modify it to also respond to touch events.

const items = [
  ['a0', 'a1', 'a2'],
  ['b0', 'b1', 'b2'],
  ['c0', 'c1', 'c2']
];

let html = '';
for (let rowItems of items) {
  html += '<div class="row">';
  for (let item of rowItems) {
    html += '<div class="item">';
    html +=   item;
    html += '</div>';
  }
  html += '</div>';
}

const viewElem = document.querySelector('#view');
const outputElem = document.querySelector('#output');
outputElem.innerHTML = html;



let mouseStartPos = null;
let startOffset = null;

outputElem.addEventListener('mousedown', e => {
  outputElem.classList.remove('animate');
  mouseStartPos = {
    x: e.clientX,
    y: e.clientY
  };
  startOffset = {
    x: outputElem.offsetLeft - viewElem.offsetLeft,
    y: outputElem.offsetTop - viewElem.offsetTop
  };
});

window.addEventListener('mouseup', e => {
  mouseStartPos = null;
  startOffset = null;

  outputElem.classList.add('animate');
  const xGridOffset = -1 * Math.max(0, Math.min(Math.round((outputElem.offsetLeft - viewElem.offsetLeft) / -100), items.length - 1));
  const yGridOffset = -1 * Math.max(0, Math.min(Math.round((outputElem.offsetTop - viewElem.offsetTop) / -100), items[0].length - 1));
  outputElem.style.left = `${xGridOffset * 100}px`;
  outputElem.style.top = `${yGridOffset * 100}px`;  
});

window.addEventListener('mousemove', e => {
  if (mouseStartPos) {
    const xOffset = mouseStartPos.x - e.clientX;
    const yOffset = mouseStartPos.y - e.clientY;
    outputElem.style.left = `${-1 * xOffset + startOffset.x}px`;
    outputElem.style.top = `${-1 * yOffset + startOffset.y}px`;
  }
});
#view {
  width: 100px;
  height: 100px;
  overflow: hidden;
  
  border: 2px solid blue;
}

#output {
  position: relative;
}

.row {
  display: flex;  
}

.item {
  display: flex;
  min-width: 100px;
  width: 100px;
  height: 100px;
  box-sizing: border-box;
  
  justify-content: center;
  align-items: center;
  border: 1px solid red;
}

#output.animate {
  transition: left 1s ease 0s, top 1s ease 0s;
}
Drag it!<br/>
<br/>
<div id="view">
  <div id="output"></div>
</div>

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文