【问题标题】:Is there a way to change the CSS resize corner's position?有没有办法改变 CSS 调整角的位置?
【发布时间】:2016-06-12 16:16:43
【问题描述】:

所以这是一个有点奇怪的问题。使用可调整大小的 div 编写 Web 应用程序。我目前正在使用 CSS resize 属性,因为它似乎是最简单的方法。问题是我的盒子有一个锁定的底部和左侧位置(我想保持),但默认选择的调整大小角是右下角,这会产生奇怪的结果来调整顶部的大小。在网上环顾四周,但找不到将那个角落移动到右上角而不是右下角的方法。关于如何产生这个结果的任何建议?也不反对使用不同的调整大小的方法。这是当前应用于盒子的样式:

display: block; 
font-size: 9pt; 
position: absolute; 
bottom: 50px; 
left: 20px; 
padding: 10px; 
min-height: 0; 
min-width: 0; 
border: solid 1px black; 
width:400px; 
height:400px; 
resize: both; 
overflow-x: auto; 
overflow-y: hidden;

这是一张有问题的 div 的图片,其中当前有调整大小工具的角被装箱。任何建议将不胜感激。我很乐意详细说明我可能错过的事情。谢谢!

Box I want to resize in question

【问题讨论】:

  • 在这里查看我对类似问题的回答:stackoverflow.com/a/62814513/1599699
  • 在你们阅读下面的答案之前 - 你不能只使用 CSS 来实现这一点,你必须使用 javascript(阅读下文)

标签: javascript html css resize


【解决方案1】:

以下解决方案使用“移动对象”技术,但保留右下角。左上角的标准 html 箭头接受向下的光标,您现在可以在左下角保持原位时“拖动”框,有效地重新调整框的大小,但从左上角开始。 此代码独立工作:

<html>
<head>
<script>
document.onmousedown=myMouseDown;
document.onmouseup=myMouseUp;
var can_drag=false;
var moving;

function obj_move(e) {
    if (can_drag) {
         moving.style.left =(e.clientX)+'px';
         moving.style.top =(e.clientY)+'px';
        return true;
    }
}
function myMouseUp(e) {
    can_drag=false;
}
function myMouseDown(e) {
    var selected_item=event.srcElement;
    if(selected_item.className=="drag")  {
        moving=document.getElementById('test');
        can_drag=true;
        document.onmousemove=obj_move;
    }
    return true;
}
</script>
</head>
<body>
<div style='position:absolute;top:50px; left:200px;right:600px;bottom:300px; border:1px solid black;overflow:scroll' id='test'>

<span class='drag' style='cursor:pointer'>&#8689;</span>

<br>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis vel velit blandit, convallis est vel, feugiat 
lorem. Suspendisse aliquam turpis eu posuere fermentum. Proin ullamcorper, purus vitae pulvinar congue, 
odio augue cursus diam, et semper mauris eros et odio. Nam vestibulum est scelerisque, accumsan ligula sed, 
pulvinar justo. Duis scelerisque ligula eget facilisis molestie. Suspendisse et consequat nunc, at ultrices risus.
 Duis varius nisl in nibh convallis fermentum. Mauris posuere neque placerat posuere ultrices. 
 Suspendisse eget massa ligula. Vestibulum quis elit justo. Maecenas sed augue fringilla, luctus leo eget, 
 tincidunt dui. Aliquam ligula enim, condimentum vitae vestibulum vitae, rutrum sed turpis. Vivamus vitae nibh erat. 
 Duis laoreet quis turpis eu eleifend. Suspendisse nec ultrices augue, vel suscipit sem.
<br>
</div>

【讨论】:

    【解决方案2】:

    从 Andrew Willems 到 JS 类的重构解决方案也可以保持您的全局范围清洁并能够将其应用于多个 div

    如果你在 Stack Overflow 中运行这段代码 sn-p,你需要在点击“Run code sn-p”后点击“Full page”来展开运行视图区域。

    class Resizehandler {
        constructor(targetDivID, pullTabID) {
            var d = document;
            var pullTab = d.getElementById(pullTabID);
            this.target = d.querySelector(targetDivID);
    
            this.ht = 400; this.wd = 400;
            this.x = 0; this.y = 0;
            this.dx = 0; this.dy = 0;
    
            var resizeFn = this.resize.bind(this);
            pullTab.addEventListener("mousedown", (evt) => {
                this.x = evt.screenX;
                this.y = evt.screenY;
                d.body.addEventListener("mousemove", resizeFn);
                d.body.addEventListener("mouseup", () => {
                    d.body.removeEventListener("mousemove", resizeFn);
                });
            });
        }
    
        resize(evt) {
            this.dx = evt.screenX - this.x;
            this.dy = evt.screenY - this.y;
            this.x = evt.screenX;
            this.y = evt.screenY;
            this.wd += this.dx;
            this.ht -= this.dy;
            this.target.style.width = this.wd + "px";
            this.target.style.height = this.ht + "px";
        };
    }
    new Resizehandler("#resizable", "rsz");
    #container {
      position: absolute;
      border: solid red 1px;
      margin: 0;
      height: 100%;
      width: 100%;
    }
    #resizable {
      display: block;
      font-size: 9pt;
      position: absolute;
      bottom: 50px;
      left: 20px;
      padding: 10px;
      min-height: 0;
      min-width: 0;
      border: solid 1px black;
      width: 400px;
      height: 400px;
      overflow-x: auto;
      overflow-y: hidden;
    }
    #rsz {
      position: absolute;
      right: 0;
      top: 0;
      width: 20px;
      height: 20px;
      background-color: rgba(255, 0, 0, 0.5);
    }
    #original {}
    <div id="container">
      <div id="resizable">
        <div id="rsz"></div>
        (some content)
      </div>
    </div>

    【讨论】:

      【解决方案3】:

      这是一个内联版本,就像我期望的一个正确的拖动锚一样。 请注意,它有两个手柄,一个在我想要的右上角,一个在底部用于垂直轴。

      关于垂直滚动的注意事项

      .vertical-scroll { //也可以用作多个 x-flip 和 x-flipback 元素的包装
      最小高度:20px; //这可以防止重叠到底片
      调整大小:垂直;
      溢出:自动; //如果没有设置高度属性,则在用户输入之前这是未定义的
      }

      作为 sn-p 的替代方法,我在元素外部使用了垂直滚动类。如果有多个子翻转和翻转元素,则可能会在底部对齐一个垂直滚动点时看起来更好。

      甚至去掉vertical-scroll类。

      .resize-x-handle-flip {
      transform: rotateX(180deg);
      resize: horizontal;
      overflow: auto;
      width: 200px;
      background:lightcyan;
      }
      .x-text-flip-back {
      transform: rotateX(180deg);
      }
      .vertical-scroll { 
      min-height:20px;  
      resize:vertical;
      overflow:auto;
      }
      <div class="resize-x-handle-flip">
       <div class="x-text-flip-back">
        <div class="vertical-scroll">
          Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et.<br> dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris.
        </div>
       </div>
      </div>

      【讨论】:

        【解决方案4】:

        另一个肮脏的技巧:将容器的direction 设置为rtl,角将在左侧

        .resizable {
            resize: both;
            overflow: auto;
            direction: rtl
        }
        

        请记住,您需要在内部 div 中将 direction 设置回 ltr,以便文本按您预期的方式显示:

        .content {
            direction: ltr
        }
        

        【讨论】:

        • 不幸的是,似乎不可能以这种方式将调整大小的角移到顶部。除非你使用transform: rotate(180deg);。 :-)
        【解决方案5】:

        几年后,仍在寻找方法。

        我现在找到了一种方法来调整右下角定位元素的大小,并使用左上角调整大小锚点。

        它似乎在 chrome 中按预期工作,但它取决于远未在任何标准中定义的行为,因此最好不要在任何生产环境中依赖它,除非您可以控制哪些客户端/浏览器使用此代码。

        在此处找到带有解释的完整示例: https://jsfiddle.net/ElMoonLite/zvok7p1f/

        核心代码:

        <div class="bottomright-with-nw-resize-outer">
            <div class="bottomright-with-nw-resize-inner">
                Lorem ipsum content Lorem ipsum content Lorem ipsum content.<br>
                Lorem ipsum content Lorem ipsum content Lorem ipsum content.
            </div>
        </div>
        
        .bottomright-with-nw-resize-outer {
            transform: rotateZ(180deg);
            resize: both;
            overflow: auto;
            padding: 0 8px 8px 0;
            position: fixed;
            bottom: 10px;
            right: 10px;
            height: 100px;
            width: 100px;
        }
        
        .bottomright-with-nw-resize-inner {
            transform: rotateZ(180deg);
            width: 100%;
            height: 100%;
            overflow: auto;
        }
        

        【讨论】:

          【解决方案6】:

          这里有一个技巧供你参考:

          .outer-ne-resize {
            resize: both;
            overflow: auto;
          }
          
          .inner-ne-resize,
          .outer-ne-resize {
            transform: rotateX(180deg);
            height: 100%;
            width: 100%;
          }
          
          .content {
            height: 100%;
            background-color: lightgray;
          }
          <div class="outer-ne-resize">
            <div class="inner-ne-resize">
              <div class="content">
                <p>Lorem ipsum content Lorem ipsum content Lorem ipsum content.<br>
                Lorem ipsum content Lorem ipsum content Lorem ipsum content.
                </p>
              </div>
            </div>

          这个 hack 的问题在于,它仍然在相同的 nwse 方向上调整大小,如光标所示。这意味着当您从顶部拉下时,它不会收缩,而是从底部扩展。

          【讨论】:

            【解决方案7】:

            这是一个起点。我基本上在右上角创建了一个自定义调整大小图标。然后我使用“mousedown”、“mousemove”和“mouseup”事件来跟踪调整大小的活动。您也许可以使用“拖动”和相关事件来做类似的事情。

            请注意,“mousedown”位于调整大小图标上,而“mousemove”和“mouseup”位于文档正文(或可调整大小的 div 后面的一些其他较大元素)上。

            为了简单起见,我在 JavaScript 中硬编码了宽度和高度。这意味着这些价值观存在于两个不同的地方,这是不好的。您可能应该只将它们放在 JavaScript 中或仅在 CSS 中,而不是像我所做的那样。

            我需要将可调整大小的 div 放入填充主体的容器中。否则,未注册可调整大小的 div 之外的“mousemove”事件。如果您在绝对定位的可调整大小元素“后面”已经有其他内容,这可能不是问题。

            供您参考:我最初也尝试使用本机调整大小功能。我使用transform: rotate(-90deg) 将resize 角移动到右上角,然后用transform: rotate(90deg) 放入一个内部div 以使内部内容再次向右上方。然而,虽然这将调整大小的角落放在了正确的位置,但调整大小本身却完全搞砸了,因为鼠标移动和实际调整大小本身偏离了 90 度。这有点难以用语言来描述,但可以这么说,如果没有一些重大的重新工作(或者可能是一些出色的代码或隐藏的功能),我无法让这个策略发挥作用。

            var
              doc = document,
              ht = 400,
              wd = 400,
              main = document.querySelector("#resizable"),
              x, y, dx, dy;
            
            var startResize = function(evt) {
              x = evt.screenX;
              y = evt.screenY;
            };
            
            var resize = function(evt) {
              dx = evt.screenX - x;
              dy = evt.screenY - y;
              x = evt.screenX;
              y = evt.screenY;
              wd += dx;
              ht -= dy;
              main.style.width = wd + "px";
              main.style.height = ht + "px";
            };
            
            rsz.addEventListener("mousedown", function(evt) {
              startResize(evt);
              doc.body.addEventListener("mousemove", resize);
              doc.body.addEventListener("mouseup", function() {
                doc.body.removeEventListener("mousemove", resize);
              });
            });
            #container {
              position: absolute;
              border: solid red 1px;
              margin: 0;
              height: 100%;
              width: 100%;
            }
            #resizable {
              display: block;
              font-size: 9pt;
              position: absolute;
              bottom: 50px;
              left: 20px;
              padding: 10px;
              min-height: 0;
              min-width: 0;
              border: solid 1px black;
              width: 400px;
              height: 400px;
              overflow-x: auto;
              overflow-y: hidden;
            }
            #rsz {
              position: absolute;
              right: 0;
              top: 0;
              width: 20px;
              height: 20px;
              background-color: rgba(255, 0, 0, 0.5);
            }
            #original {}
            <div id="container">
              <div id="resizable">
                <div id="rsz"></div>
                (some content)
              </div>
            </div>

            如果你从 Stack Overflow 中运行这段代码 sn-p,你需要在点击“Run code sn-p”后点击“Full page”来展开运行视图区域。

            【讨论】:

            • 是的,这可能是我能得到的最好的。虽然没有考虑旋转 div。这样做可能会受到打击。否则,这是一个很棒的选择。谢谢!
            • 很遗憾这可以开箱即用,Wc3 是否有机会添加它?
            • 你能用这个做一个 npm 包吗?
            猜你喜欢
            • 1970-01-01
            • 2012-10-27
            • 1970-01-01
            • 2021-10-09
            • 1970-01-01
            • 2012-11-17
            • 2021-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多