简体   繁体   English

父级div妨碍了其子级的注意力

[英]Parent div obstructs focus of its child

I'm trying to make a simple plugin to be able to make a div draggable. 我正在尝试制作一个简单的插件,以使div可拖动。 Of course a div can have a content inside (typically a form) and it should be dragged with it. 当然,一个div可以在内部包含一个内容(通常是一个表单),并且应该随它一起拖动。

Here is a prototype: http://jsfiddle.net/Xcb8d/539/ 这是一个原型: http : //jsfiddle.net/Xcb8d/539/

The problem is that the texbox inside this div never gets focus, so I cannot type in it: 问题是此div中的texbox永远不会获得焦点,因此我无法输入它:

<div id="draggable-element">Drag me!
<form>
    <input type="text" style="width:50px;"/>
    <button>ok</button><br><br>
    <input type="checkbox">check it</input>
 </form>
</div>

As you can see, this does not happen to other elements on the form. 如您所见,表单上的其他元素不会发生这种情况。 Checkbox can be regularily used, as well as the button. 复选框和按钮都可以正常使用。

In addition, I would like only the grey coloured area to be draggable, and not the inner elements. 另外,我只希望灰色区域是可拖动的,而不是内部元素。 On this example, you can place the mouse cursor fully inside the textbox and start the drag of the whole parent div. 在此示例中,您可以将鼠标光标完全放在文本框中,并开始拖动整个父div。

the onmousedown handler on the draggable element return false and there by stopping event propagation, allowing it will make the input focus-able and the dragging still works. 可拖动元素上的onmousedown处理函数返回false,并在那里停止事件传播,从而使输入可聚焦,并且拖动仍然有效。 (at least on chromium) (至少在铬上)

document.getElementById('draggable-element').onmousedown = function (e) {
    // memorize the offset to keep is constant during drag!
    x_offset = e.clientX - x_elem;
    y_offset = e.clientY - y_elem;    
    _drag_init(this);
    return true;
};

In your onmousedown handler you end with a return false . onmousedown处理程序中,您以return false结尾。 This prevents the click event from happening when you click on the input, and thus it never gets focus. 这样可以防止在单击输入时发生单击事件,因此它永远不会成为焦点。 What I think you are looking for is this: 我认为您正在寻找的是:

// Bind the functions...
document.getElementById('draggable-element').onmousedown = function (e) {
    if (e.id == 'draggable-element') {
        // memorize the offset to keep is constant during drag!
        x_offset = e.clientX - x_elem;
        y_offset = e.clientY - y_elem;    
        _drag_init(this);
        return false;
    }
};

paradoxix's answer was correct in stating that the return false on the mousedown event is preventing the propagation of all other events. paradoxix的回答是正确的,它指出mousedown事件的return false阻止了所有其他事件的传播。

On any element listening to the mousedown event you won't have any problems, because the event happens for them first, and only after for the box itself. 在侦听mousedown事件的任何元素上,您都不会有任何问题,因为该事件首先发生在它们身上,然后才发生在盒子本身上。 But the input listens to the focus event, which never happens due to the return false in the box's event. 但是输入侦听focus事件,由于框事件中的return false ,该事件永远不会发生。

The solution is to prevent onmousedown from bubbling from the child elements into the box, like so: 解决方案是防止onmousedown从子元素冒泡到框中,如下所示:

var nodes = document.getElementById('draggable-element').childNodes;
for(var i=0; i<nodes.length; i++) {
    nodes[i].onmousedown = function(e) {
        e.stopPropagation();
    }
}

Working fiddle: http://jsfiddle.net/Xcb8d/546/ 工作提琴: http : //jsfiddle.net/Xcb8d/546/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM