> For the complete documentation index, see [llms.txt](https://lochiwei.gitbook.io/web/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lochiwei.gitbook.io/web/browser/event/type/mouse/move/drag-the-bar.md).

# drag the bar

[browser](/web/browser.md) ⟩ [event](/web/browser/event.md) ⟩ [type](/web/browser/event/type.md) ⟩ [mouse](/web/browser/event/type/mouse.md) ⟩ "[mousemove](/web/browser/event/type/mouse/move.md)" ⟩ example ⟩ drag the bar &#x20;

{% hint style="success" %}
drag the bar to change its width.

* <mark style="color:purple;">**bar**</mark>.<mark style="color:yellow;">**onmouse**</mark><mark style="color:red;">**down**</mark> -> <mark style="color:yellow;">**listen**</mark> to "<mark style="color:yellow;">**mouse**</mark><mark style="color:red;">**move**</mark>" events
* "<mark style="color:yellow;">**mouse**</mark><mark style="color:red;">**move**</mark>" with [event.buttons](/web/browser/event/type/mouse/.buttons.md) = <mark style="color:yellow;">**0**</mark> ("mouseup" on anything) -> <mark style="color:red;">**stop**</mark>**&#x20;**<mark style="color:yellow;">**listening**</mark>.
  {% endhint %}

{% tabs %}
{% tab title="💈範例" %}

* replit ⟩ [drag the bar](https://replit.com/@pegasusroe/drag-the-bar#index.js)

```javascript
const { log } = console
const {max} = Math;

// ⭐️ import
import { $, $all, elem } from './js/ext/Node_ext.js'; // Node extension
// --------------------------------------------------------------------

let lastX;                 // tracks the last observed mouse X position

const bar = $("#bar");
const span = $('#width');

span.textContent = bar.offsetWidth + 'px';

// bar.onmousedown
bar.addEventListener("mousedown", event => {
    
    // ⭐️ left mouse down 
    //   -> 1. register window.onmousemove  
    //   -> 2. prevent selection
    if (event.button === 0) {
        
        lastX = event.clientX;
        
        // ⭐️ the "mousemove" handler is registered on the whole `window`. 
        //    Even if the mouse goes outside of the bar during resizing, 
        //    as long as the button is held we still want to update its size.
        window.addEventListener("mousemove", onDrag);
        log(`➕ window.onmousemove: handler registered ...`);
        
        // ⭐️ prevent selection (not working for tablets?)
        event.preventDefault();     
    }
    
});

// window.onmousemove
function onDrag(event) {
    
    // ⭐️ when mouse button released (stops dragging) -> stop resizing
    //    when `event.buttons = 0`, no buttons are down. (note the plural)
    if (event.buttons === 0) {
        window.removeEventListener("mousemove", onDrag);
        log(`➖ window.onmousemove: handler removed ...`);
        return;
    }

    // ⭐️ when mouse button held (dragging) -> resize bar
    let dx = event.clientX - lastX;
    let newWidth = max(10, bar.offsetWidth + dx);    // width >= 10px
    bar.style.width = newWidth + "px";
    span.textContent = newWidth + 'px';
    lastX = event.clientX;
}
```

{% endtab %}

{% tab title="📗 參考" %}

* [ ] Eloquent JS ⟩ [Ch. 15: Event Handling](https://eloquentjavascript.net/15_event.html) ⟩ [Mouse Motion](https://eloquentjavascript.net/15_event.html#i_XojjiOmg7v)
  {% endtab %}

{% tab title="📘 手冊" %}

* [Event](https://developer.mozilla.org/en-US/docs/Web/API/Event) ⟩ [UIEvent](https://developer.mozilla.org/en-US/docs/Web/API/UIEvent) ⟩ [MouseEvent](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent) ⟩
  * [.clientX](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/clientX) , [.clientY](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/clientY) - relative to [viewport](/web/browser/dom/type/window/viewport.md).
  * [.buttons](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons) - which buttons are pressed.
    {% endtab %}
    {% endtabs %}
