> For the complete documentation index, see [llms.txt](https://docs.apryse.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.apryse.com/web/events/viewer-events.md).

# Interact with Viewer Events

Enhance user experience with WebViewer by leveraging various events triggered in response to interactions. Learn how to optimize behavior and update annotations as users navigate through pages. The Ap

WebViewer triggers numerous events in response to user interactions or processes. They might be helpful in adding additional behavior to how users use WebViewer or performing updates to annotations as users scroll to another page.

## Page events

Other than the lifecycle events mentioned in the [loading guide](/web/events/loading-events.md), you may also be interested when a user changes pages. The [`pageNumberUpdated`](https://sdk.apryse.com/api/web/Core.DocumentViewer.html#event:pageNumberUpdated) event can be triggered by scrolling through the document or jumping to a certain page.

Subscribe to this event via [`DocumentViewer`](/web/documentviewer/documentviewer.md).

{% tabs %}
{% tab title="JavaScript (SDK v8.0+)" %}
{% code lineNumbers="true" %}

```js
WebViewer({
  initialDoc: 'https://myserver.com/myfile.pdf'
}, document.getElementById('viewer'))
  .then(instance => {
    const { documentViewer, annotationManager } = instance.Core;

    documentViewer.addEventListener('pageNumberUpdated', pageNumber => {
      const annotsOnPage = annotationManager.getAnnotationList().filter(annot => annot.PageNumber === pageNumber);

      // Do something with annotations e.g. Focus on certain form fields
    });
  });
```

{% endcode %}

[AnnotationManager.getAnnotationsList](https://sdk.apryse.com/api/web/Core.AnnotationManager.html#getAnnotationsList)
{% endtab %}

{% tab title="JavaScript (SDK v6.0+)" %}
{% code lineNumbers="true" %}

```js
WebViewer({
  initialDoc: 'https://myserver.com/myfile.pdf'
}, document.getElementById('viewer'))
  .then(instance => {
    const { docViewer, annotManager } = instance;

    docViewer.on('pageNumberUpdated', pageNumber => {
      const annotsOnPage = annotManager.getAnnotationList().filter(annot => annot.PageNumber === pageNumber);

      // Do something with annotations e.g. Focus on certain form fields
    });
  });
```

{% endcode %}

[AnnotationManager.getAnnotationsList](https://sdk.apryse.com/api/web/Core.AnnotationManager.html#getAnnotationsList)
{% endtab %}
{% endtabs %}

## Display events

When users are viewing the document, they may change zoom levels or how pages are viewed (in ways that don't permanently affect the document). These will also trigger events that you could listen to.

* [zoomUpdated](https://sdk.apryse.com/api/web/Core.DocumentViewer.html#event:zoomUpdated__anchor)
* [rotationUpdated](https://sdk.apryse.com/api/web/Core.DocumentViewer.html#event:rotationUpdated__anchor)
* [layoutChanged](https://sdk.apryse.com/api/web/Core.DocumentViewer.html#event:layoutChanged__anchor)
* [fitModeUpdated](https://sdk.apryse.com/api/web/Core.DocumentViewer.html#event:fitModeUpdated__anchor)
* [displayModeUpdated](https://sdk.apryse.com/api/web/Core.DocumentViewer.html#event:displayModeUpdated__anchor)

{% tabs %}
{% tab title="JavaScript (SDK v8.0+)" %}
{% code lineNumbers="true" %}

```js
WebViewer({
  initialDoc: 'https://myserver.com/myfile.pdf'
}, document.getElementById('viewer'))
  .then(instance => {
    const { documentViewer, Tools } = instance.Core;

    documentViewer.addEventListener('zoomUpdated', zoom => {
      if (zoom > 3) {
        // Change tools when zoom level is above 300%
        documentViewer.setToolMode(documentViewer.getToolMode(Tools.ToolNames.RECTANGLE));
      }
    });
  });
```

{% endcode %}

[DocumentViewer.setToolMode](https://sdk.apryse.com/api/web/Core.DocumentViewer.html#setToolMode) [DocumentViewer.getToolMode](https://sdk.apryse.com/api/web/Core.DocumentViewer.html#getToolMode) [ToolNames](https://sdk.apryse.com/api/web/Core.Tools.html#.ToolNames__anchor)
{% endtab %}

{% tab title="JavaScript (SDK v6.0+)" %}
{% code lineNumbers="true" %}

```js
WebViewer({
  initialDoc: 'https://myserver.com/myfile.pdf'
}, document.getElementById('viewer'))
  .then(instance => {
    const { docViewer, Tools } = instance;

    docViewer.on('zoomUpdated', zoom => {
      if (zoom > 3) {
        // Change tools when zoom level is above 300%
        documentViewer.setToolMode(documentViewer.getToolMode(Tools.ToolNames.RECTANGLE));
      }
    });
  });
```

{% endcode %}

[DocumentViewer.setToolMode](https://sdk.apryse.com/api/web/Core.DocumentViewer.html#setToolMode) [DocumentViewer.getToolMode](https://sdk.apryse.com/api/web/Core.DocumentViewer.html#getToolMode) [ToolNames](https://sdk.apryse.com/api/web/Core.Tools.html#.ToolNames__anchor)
{% endtab %}
{% endtabs %}

## Search events

When searches are conducted with the `DocumentViewer`, whether this is done through the UI or directly through an API, you can get the results by listening to these events:

* [searchResultsChanged](https://sdk.apryse.com/api/web/Core.DocumentViewer.html#event:searchResultsChanged__anchor)
* [activeSearchResultChanged](https://sdk.apryse.com/api/web/Core.DocumentViewer.html#event:activeSearchResultChanged__anchor)
* [searchInProgress](https://sdk.apryse.com/api/web/Core.DocumentViewer.html#event:searchInProgress__anchor)

{% tabs %}
{% tab title="JavaScript (SDK v8.0+)" %}
{% code lineNumbers="true" %}

```js
WebViewer({
  initialDoc: 'https://myserver.com/myfile.pdf'
}, document.getElementById('viewer'))
  .then(instance => {
    const { documentViewer, Tools } = instance.Core;

    const prevSearchResults = []; // Rendered in a custom panel

    documentViewer.addEventListener('searchResultsChanged', results => {
      prevSearchResults.push(results);
    });
  });
```

{% endcode %}
{% endtab %}

{% tab title="JavaScript (SDK v6.0+)" %}
{% code lineNumbers="true" %}

```js
WebViewer({
  initialDoc: 'https://myserver.com/myfile.pdf'
}, document.getElementById('viewer'))
  .then(instance => {
    const { docViewer, Tools } = instance;

    const prevSearchResults = []; // Rendered in a custom panel

    docViewer.on('searchResultsChanged', results => {
      prevSearchResults.push(results);
    });
  });
```

{% endcode %}
{% endtab %}
{% endtabs %}

## Input events

These input events are fired when the mouse and keyboard are interacting with the document viewer.

* [keyDown](https://sdk.apryse.com/api/web/Core.DocumentViewer.html#event:keyDown__anchor)
* [keyUp](https://sdk.apryse.com/api/web/Core.DocumentViewer.html#event:keyUp__anchor)
* [mouseEnter](https://sdk.apryse.com/api/web/Core.DocumentViewer.html#event:mouseEnter__anchor)
* [mouseLeave](https://sdk.apryse.com/api/web/Core.DocumentViewer.html#event:mouseLeave__anchor)
* [mouseLeftDown](https://sdk.apryse.com/api/web/Core.DocumentViewer.html#event:mouseLeftDown__anchor)
* [mouseLeftUp](https://sdk.apryse.com/api/web/Core.DocumentViewer.html#event:mouseLeftUp__anchor)
* [mouseMove](https://sdk.apryse.com/api/web/Core.DocumentViewer.html#event:mouseMove__anchor)
* [mouseRightDown](https://sdk.apryse.com/api/web/Core.DocumentViewer.html#event:mouseRightDown__anchor)
* [mouseRightUp](https://sdk.apryse.com/api/web/Core.DocumentViewer.html#event:mouseRightUp__anchor)

Here is an example of an onHover for annotations using the [mouseMove](https://sdk.apryse.com/api/web/Core.DocumentViewer.html#event:mouseMove__anchor) event.

{% tabs %}
{% tab title="JavaScript (SDK v8.0+)" %}
{% code lineNumbers="true" %}

```js
WebViewer({
  initialDoc: 'https://myserver.com/myfile.pdf'
}, document.getElementById('viewer'))
  .then(instance => {
    const { documentViewer, annotationManager } = instance.Core;

    documentViewer.addEventListener('mouseMove', evt => {
      const annot = annotationManager.getAnnotationByMouseEvent(evt);
      if (annot) {
        console.log("onHover: " + annot.Id);
      }
    });
  });
```

{% endcode %}

[AnnotationManager.getAnnotationByMouseEvent](https://sdk.apryse.com/api/web/Core.AnnotationManager.html#getAnnotationByMouseEvent)
{% endtab %}

{% tab title="JavaScript (SDK v6.0+)" %}
{% code lineNumbers="true" %}

```js
WebViewer({
  initialDoc: 'https://myserver.com/myfile.pdf'
}, document.getElementById('viewer'))
  .then(instance => {
    const { docViewer, annotManager } = instance;

    docViewer.on('mouseMove', evt => {
      const annot = annotManager.getAnnotationByMouseEvent(evt);
      if (annot) {
        console.log("onHover: " + annot.Id);
      }
    });
  });
```

{% endcode %}

[AnnotationManager.getAnnotationByMouseEvent](https://sdk.apryse.com/api/web/Core.AnnotationManager.html#getAnnotationByMouseEvent)
{% endtab %}
{% endtabs %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.apryse.com/web/events/viewer-events.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
