调整窗口大小

窗口大小,我们可以非常方便的使用widthheight调整,但是如何知道 widthheight是一个问题?

在 Window 操作系统中,假如我们想要缩放,我们通常会把鼠标移动到窗口的右边栏,和底部边栏,以及右下边栏。

而且在不同的边栏,鼠标呈现的样式也是不一样的。当我们在右边栏的时候我们可以通过cursor: e-resize;模拟鼠标样式。

在底部边栏我们可以通过cursor: s-resize;来模拟样式,当我们是右下的时候可以用过cursor: nw-resize;模拟鼠标样式。

首先我们设想一种比较理想的情况,可以调整的盒子的左上角刚好就是页面的左上角,也就是坐标系的0点,横向的是x轴,竖着的是y轴。

当我们点击右边栏的时候,开始记录开始的点,同时也是开始设置盒子宽度的时候,之后我们可以在文档上面再监听一下鼠标的位置,通过事件的e.pageX属性可以拿到横坐标,其实这里的e.pageX就是我们的拖拽好了的width。

当然这是比较理想的情况下,通常我们的盒子并不一定是在左上角,此时我们需要把盒子左上角的点给计算出来。

6. 调整窗口大小效果 - 图1

这里有张图,我们先看 x 轴上面的情况。当用户点击我们的右边栏的时候,当然这里的点击指的是moursedown 鼠标按下,因为在拖拽的过程中,我们鼠标是不会放开的。 此时我们就可以拿到事件 e.pageX 和 右边栏距离盒子最左边的距离 offsetLeft 。

他们俩个相减就得到了盒子左上角点的x轴的坐标。也就是我们蓝线的值。

当我们把这个左边栏拖到新的位置的时候,我们把新的 pageX 减去 蓝线的值,就可以得到红线的值,而这个红线,就刚好等于我们需要设置的值。

  1. 首先准备 HTML
  1. <div class="panel" id="resizeAble" >
  2. <h1>Hello Window</h1>
  3. </div>

2.准备 CSS 样式

  1. .panel{
  2. position: relative;
  3. border: 1px solid #eee;
  4. width: 400px;
  5. height: 350px;
  6. margin: 100px;
  7. text-align: center;
  8. }
  9. .right-bar{
  10. width: 10px;
  11. height: 100%;
  12. position: absolute;
  13. right: 0;
  14. top: 0;
  15. cursor: e-resize;
  16. }
  17. .bottom-bar{
  18. height: 10px;
  19. width: 100%;
  20. position: absolute;
  21. bottom: 0;
  22. cursor: s-resize;
  23. }
  24. .right-bottom-bar{
  25. height: 20px;
  26. width: 20px;
  27. right: 0;
  28. bottom: 0;
  29. position: absolute;
  30. cursor: nw-resize;
  31. }

3.添加JS逻辑

首先添加控制栏

  1. // 动态的添加控制栏
  2. function addControlSideBar(panel){
  3. const rightBar = document.createElement('div');
  4. const bottomBar = document.createElement('div');
  5. const rightBottomBar = document.createElement('div');
  6. rightBar.className = 'right-bar';
  7. bottomBar.className = 'bottom-bar';
  8. rightBottomBar.className = 'right-bottom-bar';
  9. let controlArray = [ rightBar, bottomBar, rightBottomBar] ;
  10. controlArray.forEach((i) => {
  11. i.draggable = false; // 禁用拖拽
  12. panel.appendChild(i)
  13. });
  14. return controlArray;
  15. }

之后为控制栏添加监听器

  1. const panel = document.querySelector('#resizeAble');
  2. // 为控制栏添加监听
  3. function listenerControlSideBar(controlArray){
  4. controlArray.forEach((v, k) => {
  5. v.addEventListener('mousedown', setPanelStatus , false)
  6. v.addEventListener('selectstart', () => (false), false); // 禁止被选中
  7. })
  8. }
  9. let controlArray = addControlSideBar(panel);
  10. listenerControlSideBar(controlArray);

完成我们的 setPanelStatus 当用户点击我们的控制栏触发的回调函数。

  1. var move_to_x, move_to_y; // 移动后的新坐标
  2. var timer; // 不停设置面板宽度和高度的定时器
  3. let min_width = 300;
  4. let min_height = 250; // 最小的宽度和高度
  5. // 实时监听鼠标的状态
  6. document.onmousemove = (e) => {
  7. move_to_x = e.pageX;
  8. move_to_y = e.pageY;
  9. }
  10. // 设置面板的状态
  11. function setPanelStatus(e){
  12. console.log(e);
  13. // 当鼠标按下那一刻执行这个函数
  14. let start_x = e.pageX - e.target.offsetLeft;
  15. let start_y = e.pageY - e.target.offsetTop;
  16. // (start_x, start,y) 盒子左上角的坐标值.
  17. // 此时只要我们不放鼠标,那么高度就会跟随 move_to_x, 和 move_to_y 一直设置。 这个一直设置,我们需要用一个定时器来实现。
  18. timer = setInterval(() => {
  19. const width = Math.max(min_width, move_to_x - start_x);
  20. const height = Math.max(min_height, move_to_y - start_y);
  21. // 判断我们按下的是哪个控制栏,根据类别来设置宽和高
  22. // 这里的 10 和 20 分别是 变量的宽度
  23. switch(e.target.className){
  24. case 'right-bar':
  25. panel.style.width = width + 'px';
  26. break;
  27. case 'bottom-bar':;
  28. panel.style.height = height + 'px';
  29. break;
  30. case 'right-bottom-bar':
  31. panel.style.height = height + 'px';
  32. panel.style.width = width + 'px';
  33. break;
  34. }
  35. }, 10)
  36. }

之后我们完成我们的当用户放开鼠标,取消继续设置宽度和高度的定时器

  1. document.onmouseup = document.ondrag = (e) => { // ondrag 是拖拽时间,有的时候把边栏当做拖拽的时候,没有及时清除 timer 就会出现 bug
  2. clearInterval(timer);
  3. timer = null;
  4. }

有的时候,可能title 会被选中

  1. panel.onselectstart = () => (false); // 禁止面板中被选中

OK,这样我们就完成了我们的逻辑。