Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Editorial review: Add docs for scroll snap events #36057

Merged
merged 6 commits into from
Oct 11, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Add docs for scroll snap events
chrisdavidmills committed Sep 26, 2024
commit e6108c4c54516ba5f905bbd9dd514efb751ff0c6
4 changes: 4 additions & 0 deletions files/en-us/web/api/document/index.md
Original file line number Diff line number Diff line change
@@ -364,6 +364,10 @@ Listen to these events using `addEventListener()` or by assigning an event liste
- : Fired when the document view or an element has been scrolled.
- {{DOMxRef("Document/scrollend_event", "scrollend")}}
- : Fired when the document view or an element has completed scrolling.
- {{domxref("Document/scrollsnapchange_event", "scrollsnapchange")}} {{experimental_inline}}
- : Fired at the end of a scrolling operation when a new scroll snap target (as implemented using features of the [CSS scroll snap module](/en-US/docs/Web/CSS/CSS_scroll_snap)) is selected.
- {{domxref("Document/scrollsnapchanging_event", "scrollsnapchanging")}} {{experimental_inline}}
- : Fired when the browser determines that a new scroll snap target is pending (i.e., it will be selected when the current scroll gesture ends).
Copy link
Member

@estelle estelle Oct 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- {{domxref("Document/scrollsnapchange_event", "scrollsnapchange")}} {{experimental_inline}}
- : Fired at the end of a scrolling operation when a new scroll snap target (as implemented using features of the [CSS scroll snap module](/en-US/docs/Web/CSS/CSS_scroll_snap)) is selected.
- {{domxref("Document/scrollsnapchanging_event", "scrollsnapchanging")}} {{experimental_inline}}
- : Fired when the browser determines that a new scroll snap target is pending (i.e., it will be selected when the current scroll gesture ends).
- {{domxref("Document/scrollsnapchange_event", "scrollsnapchange")}} {{experimental_inline}}
- : Fired on the scroll container at the end of a scrolling operation when a new scroll snap target has been selected.
- {{domxref("Document/scrollsnapchanging_event", "scrollsnapchanging")}} {{experimental_inline}}
- : Fired on the scroll container when the browser determines a new scroll snap target will be selected when the current scroll gesture ends.

remove link to module as this is a brief intro, and the page itself should contain that info.
tried shortening the scrollsnapchanging to be inline with other content on the page.
likely important that it is the container and not the snapped element that has the event.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call. I mostly used your text here, although I did keep the "pending" terminology, i.e. "...scroll snap target is pending, i.e. it will...", as I think it is useful, and used in many other places.

I also made the same changes on the Element and Window landing pages.


### Selection events

30 changes: 30 additions & 0 deletions files/en-us/web/api/document/scrollsnapchange_event/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
title: "Document: scrollsnapchange event"
short-title: scrollsnapchange
slug: Web/API/Document/scrollsnapchange_event
page-type: web-api-event
status:
- experimental
browser-compat: api.Document.scrollsnapchange_event
---

{{APIRef}}{{SeeCompatTable}}

The **`scrollsnapchange`** event of the {{domxref("Document")}} interface is fired at the end of a scrolling operation when a new scroll snap target (as implemented using features of the [CSS scroll snap module](/en-US/docs/Web/CSS/CSS_scroll_snap)) is selected.

This event works in exactly the same way as its counterpart implemented on the {{domxref("Element")}} interface — see [`Element`: `scrollsnapchange` event](/en-US/docs/Web/API/Element/scrollsnapchange_event) for more information.
Copy link
Member

@estelle estelle Oct 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The **`scrollsnapchange`** event of the {{domxref("Document")}} interface is fired at the end of a scrolling operation when a new scroll snap target (as implemented using features of the [CSS scroll snap module](/en-US/docs/Web/CSS/CSS_scroll_snap)) is selected.
This event works in exactly the same way as its counterpart implemented on the {{domxref("Element")}} interface — see [`Element`: `scrollsnapchange` event](/en-US/docs/Web/API/Element/scrollsnapchange_event) for more information.
The **`scrollsnapchange`** event of the {{domxref("Document")}} interface is fired on the [scroll container](/en-US/docs/Glossary/Scroll_container) at the end of a scrolling operation when a new scroll snap target is selected.
Part of the [CSS scroll snap](/en-US/docs/Web/CSS/CSS_scroll_snap) module, this event works in exactly the same way as the {{domxref("Element")}} interface's [`scrollsnapchange`](/en-US/docs/Web/API/Element/scrollsnapchange_event) event.

Removing parenthesis from the first sentence, as that is used as the tool tip in apps.
So, moved the module link to the next sentence.

making the link/sentence structure to the counterpart event match how we write "this is the same as" on other API feature pages which favors in paragraph links over "see ...".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

works for me. Updated.


## Specifications

{{Specifications}}

## Browser compatibility

{{Compat}}

## See also

- The {{domxref("Document/scrollsnapchanging_event", "scrollsnapchanging")}} event
- {{domxref("SnapEvent")}}
- [CSS scroll snap module](/en-US/docs/Web/CSS/CSS_scroll_snap)
- [Scroll Snap Events](https://developer.chrome.com/blog/scroll-snap-events) on developer.chrome.com (2024)
30 changes: 30 additions & 0 deletions files/en-us/web/api/document/scrollsnapchanging_event/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
title: "Document: scrollsnapchanging event"
short-title: scrollsnapchanging
slug: Web/API/Document/scrollsnapchanging_event
page-type: web-api-event
status:
- experimental
browser-compat: api.Document.scrollsnapchanging_event
---

{{APIRef}}{{SeeCompatTable}}

The **`scrollsnapchanging`** event of the {{domxref("Document")}} interface is fired when the browser determines that a new scroll snap target (as implemented using features of the [CSS scroll snap module](/en-US/docs/Web/CSS/CSS_scroll_snap)) is pending (i.e., it will be selected when the current scroll gesture ends).

This event works in exactly the same way as its counterpart implemented on the {{domxref("Element")}} interface — see [`Element`: `scrollsnapchanging` event](/en-US/docs/Web/API/Element/scrollsnapchanging_event) for more information.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same feedback as above

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've rewritten it in exactly the same way.


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
## Examples
We use the event name in with the {{domxref("EventTarget.addEventListener", "addEventListener()")}} method:
```js
Document.addEventListener("scrollsnapchange", (event) => {
// code that runs when the scrollsnapchange event occurs
});
```end

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than add a really trivial example that is very similar to the standard event syntax section, I've elected to just include the syntax section on the document and window events pages.

## Specifications

{{Specifications}}

## Browser compatibility

{{Compat}}

## See also

- The {{domxref("Document/scrollsnapchange_event", "scrollsnapchange")}} event
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- The {{domxref("Document/scrollsnapchange_event", "scrollsnapchange")}} event
- {{domxref("Document/scrollsnapchange_event", "scrollsnapchange")}} event

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

- {{domxref("SnapEvent")}}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- The {{domxref("Document/scrollsnapchange_event", "scrollsnapchange")}} event
- {{domxref("SnapEvent")}}
- {{domxref("Document/scrollsnapchange_event", "scrollsnapchange")}} event
- {{domxref("SnapEvent")}}
- {{domxref("SnapEvent.snapTargetBlock")}}
- {{domxref("SnapEvent.snapTargetInline")}}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not convinced these are really needed, when we already link to the event object?

- [CSS scroll snap module](/en-US/docs/Web/CSS/CSS_scroll_snap)
- [Scroll Snap Events](https://developer.chrome.com/blog/scroll-snap-events) on developer.chrome.com (2024)
4 changes: 4 additions & 0 deletions files/en-us/web/api/element/index.md
Original file line number Diff line number Diff line change
@@ -311,6 +311,10 @@ Listen to these events using `addEventListener()` or by assigning an event liste
- : Fired when the document view or an element has been scrolled.
- {{domxref("Element/scrollend_event", "scrollend")}}
- : Fires when the document view has completed scrolling.
- {{domxref("Element/scrollsnapchange_event", "scrollsnapchange")}} {{experimental_inline}}
- : Fired at the end of a scrolling operation when a new scroll snap target (as implemented using features of the [CSS scroll snap module](/en-US/docs/Web/CSS/CSS_scroll_snap)) is selected.
- {{domxref("Element/scrollsnapchanging_event", "scrollsnapchanging")}} {{experimental_inline}}
- : Fired when the browser determines that a new scroll snap target is pending (i.e., it will be selected when the current scroll gesture ends).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same feedback as above

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same wording used as above.

- {{domxref("Element/securitypolicyviolation_event","securitypolicyviolation")}}
- : Fired when a [Content Security Policy](/en-US/docs/Web/HTTP/CSP) is violated.
- {{domxref("Element/wheel_event","wheel")}}
76 changes: 76 additions & 0 deletions files/en-us/web/api/element/scrollsnapchange_event/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
---
title: "Element: scrollsnapchange event"
short-title: scrollsnapchange
slug: Web/API/Element/scrollsnapchange_event
page-type: web-api-event
status:
- experimental
browser-compat: api.Element.scrollsnapchange_event
---

{{APIRef}}{{SeeCompatTable}}

The **`scrollsnapchange`** event of the {{domxref("Element")}} interface is fired at the end of a scrolling operation when a new scroll snap target (as implemented using features of the [CSS scroll snap module](/en-US/docs/Web/CSS/CSS_scroll_snap)) is selected.

Note that this event fires:

- When a scrolling gesture is completed (i.e. the user has finished scrolling a scroll container and releases the gesture), but only if a new snap target is selected.
- Just before the {{domxref("Element/scrollend_event", "scrollend")}} event fires.
Copy link
Member

@estelle estelle Oct 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The **`scrollsnapchange`** event of the {{domxref("Element")}} interface is fired at the end of a scrolling operation when a new scroll snap target (as implemented using features of the [CSS scroll snap module](/en-US/docs/Web/CSS/CSS_scroll_snap)) is selected.
Note that this event fires:
- When a scrolling gesture is completed (i.e. the user has finished scrolling a scroll container and releases the gesture), but only if a new snap target is selected.
- Just before the {{domxref("Element/scrollend_event", "scrollend")}} event fires.
The **`scrollsnapchange`** event of the {{domxref("Element")}} interface is fired on the [scroll container](/en-US/docs/Glossary/Scroll_container) at the end of a scrolling operation, just before the {{domxref("Element/scrollend_event", "scrollend")}} event fires, if a new scroll snap target has been selected.
Defined in the [CSS scroll snap module](/en-US/docs/Web/CSS/CSS_scroll_snap)), this event fires when a scrolling gesture is completed if the browser determines a new snap target has been selected before the`scrollend` event has fired. A scroll gesture is complete when the user has finished scrolling within a scroll container and releases the gesture.

not sure if what i wrote is fully accurate, as I haven't read the whole thing yet, but that seems to be what it means; it is only fired if the new snap target is selected before the scrollend event has fired.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about this a bit, end ended up changing it to:

The scrollsnapchange event of the {{domxref("Element")}} interface is fired on the scroll container at the end of a scrolling operation when a new scroll snap target has been selected, just before the corresponding {{domxref("Element/scrollend_event", "scrollend")}} event fires.

A scrolling operation ends when the user finishes scrolling within a scroll container — for example using a touch gesture or by dragging the mouse pointer on a scroll bar — and releases the gesture.

I felt like your version was a bit overly repetitious, plus I didn't think we needed to link to the scroll snap module page here, as it and the spec are both linked to later on.

I also removed the scroll snap module links from the top of the other pages, for the same reason.


## Syntax

Use the event name in methods like {{domxref("EventTarget.addEventListener", "addEventListener()")}}, or set an event handler property.

```js
addEventListener("scrollsnapchange", (event) => {});

onscrollsnapchange = (event) => {};
```

## Event type

A {{domxref("SnapEvent")}}.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does it inherit? Do we need to add "inherits from Event"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be useful to say that, yes. I've updated the section to the following on both document event pages, and added it to the element and window event pages too:

## Event type

A {{domxref("SnapEvent")}}, which inherits from the generic {{domxref("Event")}} type.


## Examples

In the following `scrollsnapchange` handler function snippet (set on a scrolling container element), we set a `select-section` class on the {{domxref("SnapEvent.snapTargetBlock")}} element, which could be used to style a newly-selected snap target to look like it has been selected (for example, with an animation).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of including a copy of the CSS_scroll_snap using scroll snap events guide, just include a the first line and maybe toggle a class.

scrollingElem.addEventListener("scrollsnapchange", (event) => {
   event.snapTargetBlock.classList.remove("currentScroller");
}

or, even better, remove the class from the target element, and add the class to the next element that is going to be scrolled.

Copy link
Contributor Author

@chrisdavidmills chrisdavidmills Oct 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've cut it down a bit and changed the example so it's not exactly the same.


Note that this handler is intended to be set on a block-direction scroll container (vertically-scrolling if the page is set to a left-to-right {{cssxref("writing-mode")}}), therefore only the `snapTargetBlock` element will change between multiple events firing. The element snapped to in the inline direction will always be the same, therefore {{domxref("SnapEvent.snapTargetInline")}} will always contain a reference to the same element.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if this not is for the event in general, and not this example specifically, add this to the description before the syntax section.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've just removed it, as really its about the event object rather than the event. I do explain it in the event object page too.


```js
scrollingElem.addEventListener("scrollsnapchange", (event) => {
if (document.querySelector(".select-section")) {
document.querySelector(".select-section").className = "deselect-section";
} else {
document.querySelector("section").className = "select-section";
}

event.snapTargetBlock.className = "select-section";

// Logs the id of the new block-direction snap target element
console.log(event.snapTargetBlock.id);

// Always logs the same ID; the inline-direction snap target
// element will always be the same
console.log(event.snapTargetInline.id);
});
```

At the start of the function, we also include an `if...else` block to look for a previously-selected snap target. If one is found, it has a `deselect-section` class applied to it, which for example could be used to apply a deselection animation. If not, the first snap target in the page is given the `select-section` class, which means that it will be given the appropriate selected styles when the page first loads.

See the [Using scroll snap events](/en-US/docs/Web/CSS/CSS_scroll_snap/Using_scroll_snap_events) guide for full examples and explanation.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since we're reducing this to a simple, self contained example that isn't displayed, add this link to the #see also instead

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've moved it to see also


## Specifications

{{Specifications}}

## Browser compatibility

{{Compat}}

## See also

- The {{domxref("Element/scrollsnapchanging_event", "scrollsnapchanging")}} event
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- The {{domxref("Element/scrollsnapchanging_event", "scrollsnapchanging")}} event
- {{domxref("Element/scrollsnapchanging_event", "scrollsnapchanging")}} event

(on all pages)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

- {{domxref("SnapEvent")}}
- [CSS scroll snap module](/en-US/docs/Web/CSS/CSS_scroll_snap)
- [Scroll Snap Events](https://developer.chrome.com/blog/scroll-snap-events) on developer.chrome.com (2024)
76 changes: 76 additions & 0 deletions files/en-us/web/api/element/scrollsnapchanging_event/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
---
title: "Element: scrollsnapchanging event"
short-title: scrollsnapchanging
slug: Web/API/Element/scrollsnapchanging_event
page-type: web-api-event
status:
- experimental
browser-compat: api.Element.scrollsnapchanging_event
---

{{APIRef}}{{SeeCompatTable}}

The **`scrollsnapchanging`** event of the {{domxref("Element")}} interface is fired when the browser determines that a new scroll snap target (as implemented using features of the [CSS scroll snap module](/en-US/docs/Web/CSS/CSS_scroll_snap)) is pending (i.e., it will be selected when the current scroll gesture ends).

Note that this event fires during a scrolling gesture, each time the user moves over a potential new snap target — imagine a user scrolling slowly by dragging their finger on a touch screen device, or holding down the mouse button on a scroll bar and moving the mouse. `scrollsnapchanging` can therefore fire multiple times for each scrolling gesture.

However, `scrollsnapchanging` does not fire on all potential snap targets for a gesture that spans multiple snap targets at once — just the last target that the snapping will potentially rest on. In this case, imagine a user flicking their finger hard on the screen to scroll past several potential targets before starting to come to rest near a target further down the scroll container.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar feedback. My suggestion (if accurate??):

Suggested change
The **`scrollsnapchanging`** event of the {{domxref("Element")}} interface is fired when the browser determines that a new scroll snap target (as implemented using features of the [CSS scroll snap module](/en-US/docs/Web/CSS/CSS_scroll_snap)) is pending (i.e., it will be selected when the current scroll gesture ends).
Note that this event fires during a scrolling gesture, each time the user moves over a potential new snap target — imagine a user scrolling slowly by dragging their finger on a touch screen device, or holding down the mouse button on a scroll bar and moving the mouse. `scrollsnapchanging` can therefore fire multiple times for each scrolling gesture.
However, `scrollsnapchanging` does not fire on all potential snap targets for a gesture that spans multiple snap targets at once — just the last target that the snapping will potentially rest on. In this case, imagine a user flicking their finger hard on the screen to scroll past several potential targets before starting to come to rest near a target further down the scroll container.
The **`scrollsnapchanging`** event of the {{domxref("Element")}} interface is fired when the browser determines that a new scroll snap target is pending and will be selected when the current scroll gesture ends.
This event, defined in the [CSS scroll snap module](/en-US/docs/Web/CSS/CSS_scroll_snap), fires during a scrolling gesture, each time the user moves over a potential new snap target. For example, the event will fire when a user scrolls by slowly dragging their finger on a touchscreen device or holding down the mouse button on a scroll bar and moving the mouse.
While the `scrollsnapchanging` event can fire multiple times for each scrolling gesture, it does not fire on all potential snap targets for a gesture that spans multiple snap targets at once — just the last target that the snapping will potentially rest on. For example, if a user flicks their finger hard on the screen to scroll past several potential targets before starting to come to rest near a target further down the scroll container, the `scrollsnapchanging` event will fire when the target near the end of the scroll container is reached.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated; I've mostly used your wording.


## Syntax

Use the event name in methods like {{domxref("EventTarget.addEventListener", "addEventListener()")}}, or set an event handler property.

```js
addEventListener("scrollsnapchanging", (event) => {});

onscrollsnapchanging = (event) => {};
```

## Event type

A {{domxref("SnapEvent")}}.

## Examples

In the following `scrollsnapchanging` handler function snippet (set on a scrolling container element), we set the {{domxref("SnapEvent.snapTargetBlock", "snapTargetBlock")}} element's `class` attribute to `pending` using the {{domxref("Element.className")}} property, which could be used to style the element differently when it becomes a pending snap target.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same feedback on the example as the scrollsnapchange paage

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cut down in a similar way as before.


Note that this handler is intended to be set on a block-direction scroll container (vertically-scrolling if the page is set to a left-to-right {{cssxref("writing-mode")}}), therefore only the `snapTargetBlock` element will change between multiple events firing. The element snapped to in the inline direction will always be the same, therefore {{domxref("SnapEvent.snapTargetInline")}} will always contain a reference to the same element.

```js
scrollingElem.addEventListener("scrollsnapchanging", (event) => {
// remove previously-set "pending" classes
const pendingElems = document.querySelectorAll(".pending");
pendingElems.forEach((elem) => {
elem.className = "";
});

// Set current pending snap target class to "pending"
event.snapTargetBlock.className = "pending";

// Logs the id of the new block-direction snap target element
console.log(event.snapTargetBlock.id);

// Always logs the same ID; the inline-direction snap target
// element will always be the same
console.log(event.snapTargetInline.id);
});
```

At the start of the function, we select all elements that previously had the `pending` class applied and remove it, so that only the most recent pending snap target is styled.

See the [Using scroll snap events](/en-US/docs/Web/CSS/CSS_scroll_snap/Using_scroll_snap_events) guide for full examples and explanation.

## Specifications

{{Specifications}}

## Browser compatibility

{{Compat}}

## See also

- The {{domxref("Element/scrollsnapchange_event", "scrollsnapchange")}} event
- {{domxref("SnapEvent")}}
- [CSS scroll snap module](/en-US/docs/Web/CSS/CSS_scroll_snap)
- [Scroll Snap Events](https://developer.chrome.com/blog/scroll-snap-events) on developer.chrome.com (2024)
94 changes: 94 additions & 0 deletions files/en-us/web/api/snapevent/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
---
title: SnapEvent
slug: Web/API/SnapEvent
page-type: web-api-interface
status:
- experimental
browser-compat: api.SnapEvent
---

{{APIRef("Snap Events")}}{{SeeCompatTable}}

The **`SnapEvent`** interface defines the event object for the {{domxref("Element/scrollsnapchanging_event", "scrollsnapchanging")}} and {{domxref("Element/scrollsnapchange_event", "scrollsnapchange")}} events, which are related to the [CSS scroll snap module](/en-US/docs/Web/CSS/CSS_scroll_snap). Respectively, these fire when the browser determines that a new snap target is pending (will be selected when the current scroll gesture ends), and when a new snap target is selected.

These can be used to run code in response to new elements being snapped to; `SnapEvent` exposes references to the element snapped to in the inline and/or block direction.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The **`SnapEvent`** interface defines the event object for the {{domxref("Element/scrollsnapchanging_event", "scrollsnapchanging")}} and {{domxref("Element/scrollsnapchange_event", "scrollsnapchange")}} events, which are related to the [CSS scroll snap module](/en-US/docs/Web/CSS/CSS_scroll_snap). Respectively, these fire when the browser determines that a new snap target is pending (will be selected when the current scroll gesture ends), and when a new snap target is selected.
These can be used to run code in response to new elements being snapped to; `SnapEvent` exposes references to the element snapped to in the inline and/or block direction.
The **`SnapEvent`** interface defines the event object for the {{domxref("Element/scrollsnapchanging_event", "scrollsnapchanging")}} and {{domxref("Element/scrollsnapchange_event", "scrollsnapchange")}} events. Respectively, these fire when the browser determines that a new snap target is pending (will be selected when the current scroll gesture ends), and when a new snap target is selected.
Defined in the [CSS scroll snap module](/en-US/docs/Web/CSS/CSS_scroll_snap), these can be used to run code in response to new elements being snapped to; `SnapEvent` exposes references to the element snapped to in the inline and/or block direction.

move the module out of all the first sentences. where it's defined doesn't need to show up in search, devtools, etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated


{{InheritanceDiagram}}

## Constructor

- {{domxref("SnapEvent.SnapEvent", "SnapEvent()")}} {{Experimental_Inline}}
- : Creates a new `SnapEvent` object instance.

## Instance properties

_Inherits properties from its parent, {{DOMxRef("Event")}}._

- {{domxref("SnapEvent.snapTargetBlock", "snapTargetBlock")}} {{ReadOnlyInline}} {{Experimental_Inline}}
- : Returns a reference to the element snapped to in the block direction when the event fired.
- {{domxref("SnapEvent.snapTargetInline", "snapTargetInline")}} {{ReadOnlyInline}} {{Experimental_Inline}}
- : Returns a reference to the element snapped to in the inline direction when the event fired.

## Examples

See the [Using scroll snap events](/en-US/docs/Web/CSS/CSS_scroll_snap/Using_scroll_snap_events) guide for full examples and explanation.

### `scrollsnapchanging` example

In the following `scrollsnapchanging` handler function snippet (set on a scrolling container element), we set the {{domxref("SnapEvent.snapTargetBlock", "snapTargetBlock")}} element's `class` attribute to `pending` using the {{domxref("Element.className")}} property, which could be used to style the element differently when it becomes a pending snap target.

Note that this handler is intended to be set on a block-direction scroll container (vertically-scrolling if the page is set to a left-to-right {{cssxref("writing-mode")}}), therefore only the `snapTargetBlock` element will change between multiple events firing. The element snapped to in the inline direction will always be the same, therefore {{domxref("SnapEvent.snapTargetInline")}} will always contain a reference to the same element.
chrisdavidmills marked this conversation as resolved.
Show resolved Hide resolved

```js
scrollingElem.addEventListener("scrollsnapchanging", (event) => {
// remove previously-set "pending" classes
const pendingElems = document.querySelectorAll(".pending");
pendingElems.forEach((elem) => {
elem.className = "";
});

// Set current pending snap target class to "pending"
event.snapTargetBlock.className = "pending";

// Logs the id of the new block-direction snap target element
console.log(event.snapTargetBlock.id);

// Always logs the same ID; the inline-direction snap target
// element will always be the same
chrisdavidmills marked this conversation as resolved.
Show resolved Hide resolved
console.log(event.snapTargetInline.id);
});
```

At the start of the function, we select all elements that previously had the `pending` class applied and remove it, so that only the most recent pending snap target is styled.

### `scrollsnapchange` example

In the following `scrollsnapchange` handler function snippet (again, set on a scrolling container element), we set a `select-section` class on the {{domxref("SnapEvent.snapTargetBlock")}} element, which could be used to style a newly-selected snap target to look like it has been selected (for example, with an animation).

```js
scrollingElem.addEventListener("scrollsnapchange", (event) => {
if (document.querySelector(".select-section")) {
document.querySelector(".select-section").className = "deselect-section";
} else {
document.querySelector("section").className = "select-section";
}

event.snapTargetBlock.className = "select-section";
});
```

At the start of the function, we also include an `if...else` block to look for a previously-selected snap target. If one is found, it has a `deselect-section` class applied to it, which for example could be used to apply a deselection animation. If not, the first snap target in the page is given the `select-section` class, which means that it will be given the appropriate selected styles when the page first loads.

## Specifications

{{Specifications}}

## Browser compatibility

{{Compat}}

## See also

- The {{domxref("Element/scrollsnapchanging_event", "scrollsnapchanging")}} and {{domxref("Element/scrollsnapchange_event", "scrollsnapchange")}} events
- [CSS scroll snap module](/en-US/docs/Web/CSS/CSS_scroll_snap)
- [Scroll Snap Events](https://developer.chrome.com/blog/scroll-snap-events) on developer.chrome.com (2024)
60 changes: 60 additions & 0 deletions files/en-us/web/api/snapevent/snapevent/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
title: "SnapEvent: SnapEvent() constructor"
short-title: SnapEvent()
slug: Web/API/SnapEvent/SnapEvent
page-type: web-api-constructor
status:
- experimental
browser-compat: api.SnapEvent.SnapEvent
---

{{APIRef("Snap Events")}}{{SeeCompatTable}}

The **`SnapEvent()`** constructor creates a new
{{domxref("SnapEvent")}} object instance.

## Syntax

```js-nolint
new SnapEvent(type, init)
```

### Parameters

- `type`
- : A string representing the type of event. For {{domxref("Element/scrollsnapchanging_event", "scrollsnapchanging")}} events, this is `scrollsnapchanging`. For {{domxref("Element/scrollsnapchange_event", "scrollsnapchange")}} events, this is `scrollsnapchange`.
- `init`
- : An object containing the following properties:
- `snapTargetBlock` {{optional_inline}}
- : Returns a reference to the element snapped to in the block direction when the event fired.
- `snapTargetInline` {{optional_inline}}
- : Returns a reference to the element snapped to in the inline direction when the event fired.

## Examples

A developer would not use this constructor manually. A new `SnapEvent` object is constructed when a handler is invoked as a result of the {{domxref("Element/scrollsnapchanging_event", "scrollsnapchanging")}} or {{domxref("Element/scrollsnapchange_event", "scrollsnapchange")}} events firing.

For example:

```js
mainElem.addEventListener("scrollsnapchange", (event) => {
// ...

// Log a SnapEvent object instance to the console
console.log(event);
});
```

## Specifications

{{Specifications}}

## Browser compatibility

{{Compat}}

## See also

- The {{domxref("Element/scrollsnapchanging_event", "scrollsnapchanging")}} and {{domxref("Element/scrollsnapchange_event", "scrollsnapchange")}} events
chrisdavidmills marked this conversation as resolved.
Show resolved Hide resolved
- [CSS scroll snap module](/en-US/docs/Web/CSS/CSS_scroll_snap)
- [Scroll Snap Events](https://developer.chrome.com/blog/scroll-snap-events) on developer.chrome.com (2024)
43 changes: 43 additions & 0 deletions files/en-us/web/api/snapevent/snaptargetblock/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
title: "SnapEvent: snapTargetBlock property"
short-title: snapTargetBlock
slug: Web/API/SnapEvent/snapTargetBlock
page-type: web-api-instance-property
status:
- experimental
browser-compat: api.SnapEvent.snapTargetBlock
---

{{APIRef("Snap Events")}}{{SeeCompatTable}}

The **`snapTargetBlock`** read-only property of the
{{domxref("SnapEvent")}} interface returns a reference to the element snapped to in the block direction when the event fired.

Specifically:

- In the case of the {{domxref("Element/scrollsnapchanging_event", "scrollsnapchanging")}} event, this refers to a pending block-direction snap target (i.e. it will be selected when the current scroll gesture ends).
- In the case of the {{domxref("Element/scrollsnapchange_event", "scrollsnapchange")}} event, this refers to a newly-selected block-direction snap target.

## Value

A {{domxref("Node")}} representing the snapped element, or `null` if no block-direction element was snapped to.

If the snapped element was a pseudo-element, the returned `Node` will be the owning element of that pseudo-element.

## Examples

See the main {{domxref("SnapEvent")}} page for brief examples, and our [Using scroll snap events](/en-US/docs/Web/CSS/CSS_scroll_snap/Using_scroll_snap_events) guide for full examples and explanation.

## Specifications

{{Specifications}}

## Browser compatibility

{{Compat}}

## See also

- The {{domxref("Element/scrollsnapchanging_event", "scrollsnapchanging")}} and {{domxref("Element/scrollsnapchange_event", "scrollsnapchange")}} events
chrisdavidmills marked this conversation as resolved.
Show resolved Hide resolved
- [CSS scroll snap module](/en-US/docs/Web/CSS/CSS_scroll_snap)
- [Scroll Snap Events](https://developer.chrome.com/blog/scroll-snap-events) on developer.chrome.com (2024)
43 changes: 43 additions & 0 deletions files/en-us/web/api/snapevent/snaptargetinline/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
title: "SnapEvent: snapTargetInline property"
short-title: snapTargetInline
slug: Web/API/SnapEvent/snapTargetInline
page-type: web-api-instance-property
status:
- experimental
browser-compat: api.SnapEvent.snapTargetInline
---

{{APIRef("Snap Events")}}{{SeeCompatTable}}

The **`snapTargetInline`** read-only property of the
{{domxref("SnapEvent")}} interface returns a reference to the element snapped to in the inline direction when the event fired.

Specifically:

- In the case of the {{domxref("Element/scrollsnapchanging_event", "scrollsnapchanging")}} event, this refers to a pending inline-direction snap target (i.e. it will be selected when the current scroll gesture ends).
- In the case of the {{domxref("Element/scrollsnapchange_event", "scrollsnapchange")}} event, this refers to a newly-selected inline-direction snap target.

## Value

A {{domxref("Node")}} representing the snapped element, or `null` if no inline-direction element was snapped to.

If the snapped element was a pseudo-element, the returned `Node` will be the owning element of that pseudo-element.

## Examples

See the main {{domxref("SnapEvent")}} page for brief examples, and our [Using scroll snap events](/en-US/docs/Web/CSS/CSS_scroll_snap/Using_scroll_snap_events) guide for full examples and explanation.

## Specifications

{{Specifications}}

## Browser compatibility

{{Compat}}

## See also

- The {{domxref("Element/scrollsnapchanging_event", "scrollsnapchanging")}} and {{domxref("Element/scrollsnapchange_event", "scrollsnapchange")}} events
chrisdavidmills marked this conversation as resolved.
Show resolved Hide resolved
- [CSS scroll snap module](/en-US/docs/Web/CSS/CSS_scroll_snap)
- [Scroll Snap Events](https://developer.chrome.com/blog/scroll-snap-events) on developer.chrome.com (2024)
7 changes: 7 additions & 0 deletions files/en-us/web/api/window/index.md
Original file line number Diff line number Diff line change
@@ -392,6 +392,13 @@ Listen to these events using [`addEventListener()`](/en-US/docs/Web/API/EventTar
- {{domxref("Window/unhandledrejection_event", "unhandledrejection")}}
- : Sent when a JavaScript {{jsxref("Promise")}} is rejected but there is no handler in place to catch the rejection.

### Scroll events

- {{domxref("Window/scrollsnapchange_event", "scrollsnapchange")}} {{experimental_inline}}
- : Fired at the end of a scrolling operation when a new scroll snap target (as implemented using features of the [CSS scroll snap module](/en-US/docs/Web/CSS/CSS_scroll_snap)) is selected.
- {{domxref("Window/scrollsnapchanging_event", "scrollsnapchanging")}} {{experimental_inline}}
- : Fired when the browser determines that a new scroll snap target is pending (i.e., it will be selected when the current scroll gesture ends).

### Deprecated events

- {{domxref("Window/orientationchange_event", "orientationchange")}} {{Deprecated_Inline}}
30 changes: 30 additions & 0 deletions files/en-us/web/api/window/scrollsnapchange_event/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
title: "Window: scrollsnapchange event"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i can't get this event to happen on the window, document, or body. have you been able to?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hrm, this is a bit troubling. The spec definitely suggests that they are available in all three places, and I did a bit of brief testing to verify that the events exist on all three interfaces.

But you are right. I can't get them to fire in those places either.

I'm wondering whether Chrome just doesn't support them in those places yet, or whether I've misunderstood the spec. I've dropped @argyleink an email to ask for help on this one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I talked this through with @argyleink and he shared a test case and put me straight (cheers mate!)

Turns out that you have to set scroll-snap-type on the html element to get the events to fire on Document/Window. I've created a version of our one-dimensional scroller demo that does this and fires the events on Window: https://smiling-eager-asparagus.glitch.me/

This works fine just the same whether you have the event handlers hanging off on Document or Window. I'm going to add a small example section to the Document and Window event handler pages, and maybe a note or small section to the guide too, to explain this, as it was somewhat non-obvious.

The only question that still remains is about getting the events to fire on <body>, when <body> has scroll-snap-type set on it, and has the event handlers set directly on it. I'm thinking that https://veiled-imaginary-agreement.glitch.me/ should work, but it doesn't.

short-title: scrollsnapchange
slug: Web/API/Window/scrollsnapchange_event
page-type: web-api-event
status:
- experimental
browser-compat: api.Window.scrollsnapchange_event
---

{{APIRef}}{{SeeCompatTable}}

The **`scrollsnapchange`** event of the {{domxref("Window")}} interface is fired at the end of a scrolling operation when a new scroll snap target (as implemented using features of the [CSS scroll snap module](/en-US/docs/Web/CSS/CSS_scroll_snap)) is selected.

This event works in exactly the same way as its counterpart implemented on the {{domxref("Element")}} interface — see [`Element`: `scrollsnapchange` event](/en-US/docs/Web/API/Element/scrollsnapchange_event) for more information.

## Specifications

{{Specifications}}

## Browser compatibility

{{Compat}}

## See also

- The {{domxref("Window/scrollsnapchanging_event", "scrollsnapchanging")}} event
- {{domxref("SnapEvent")}}
- [CSS scroll snap module](/en-US/docs/Web/CSS/CSS_scroll_snap)
- [Scroll Snap Events](https://developer.chrome.com/blog/scroll-snap-events) on developer.chrome.com (2024)
30 changes: 30 additions & 0 deletions files/en-us/web/api/window/scrollsnapchanging_event/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
title: "Window: scrollsnapchanging event"
short-title: scrollsnapchanging
slug: Web/API/Window/scrollsnapchanging_event
page-type: web-api-event
status:
- experimental
browser-compat: api.Window.scrollsnapchanging_event
---

{{APIRef}}{{SeeCompatTable}}

The **`scrollsnapchanging`** event of the {{domxref("Window")}} interface is fired when the browser determines that a new scroll snap target (as implemented using features of the [CSS scroll snap module](/en-US/docs/Web/CSS/CSS_scroll_snap)) is pending (i.e., it will be selected when the current scroll gesture ends).

This event works in exactly the same way as its counterpart implemented on the {{domxref("Element")}} interface — see [`Element`: `scrollsnapchanging` event](/en-US/docs/Web/API/Element/scrollsnapchanging_event) for more information.

## Specifications

{{Specifications}}

## Browser compatibility

{{Compat}}

## See also

- The {{domxref("Window/scrollsnapchange_event", "scrollsnapchange")}} event
- {{domxref("SnapEvent")}}
- [CSS scroll snap module](/en-US/docs/Web/CSS/CSS_scroll_snap)
- [Scroll Snap Events](https://developer.chrome.com/blog/scroll-snap-events) on developer.chrome.com (2024)