codex-team / editor.js

A block-style editor with clean JSON output
https://editorjs.io
Apache License 2.0
28.52k stars 2.08k forks source link

onChange event is triggered immediately on initialization #2559

Open collimarco opened 10 months ago

collimarco commented 10 months ago

We have implemented an alert for the users when they try to leave the editor with some unsaved changes.

Basically when editorjs onChange is triggered, we set a variable unsavedChanges = true.

The problem is that onChange is triggered also immediately when the editor is loading... This means that if a user opens an existing document, they will always receive a warning about unsaved changes when they leave, even if they only opened the document and did not make any changes.

This is because editorjs triggers onChange immediately.

Expected: editorjs triggers onChange only when the user makes some changes in the editor Actual: editorjs triggers onChange when the user makes some changes in the editor AND when it is initialized with new EditorJS

collimarco commented 10 months ago

Is there at least a way to read the onChange event param and differentiate between the initialization event and an actual change?

collimarco commented 10 months ago

This seems a related issue: https://github.com/codex-team/editor.js/discussions/1907

collimarco commented 10 months ago

After further investigation, it seems that this issue appears only when you have the @editorjs/image block.

I found this by inspecting the onChange:

      onChange: (api, event) => {
        console.log('onChange triggered')
        for (const e of event) {
          console.log(e.detail.target.holder)
        }
        this.unsavedChanges()
      }

Then I found this issue, which is probably the root cause:

https://github.com/editor-js/image/issues/163

neSpecc commented 10 months ago

Pls describe the editor version and browser you use

collimarco commented 10 months ago

@neSpecc I am using Chrome 120 on MacOS Sonoma. Editor.js version: 2.28.2

neSpecc commented 10 months ago

Could you try 2.29.0-rc.7 please?

collimarco commented 10 months ago

@neSpecc Thanks for the reply. I have tested with 2.29.0-rc.7, but unfortunately there is the exact same issue. Probably the problem is somewhere in the image block (https://github.com/editor-js/image/issues/163)

collimarco commented 10 months ago

The strange thing is that I can't find any dispatchChange or onChange inside the code of the image block... so maybe that image block changes some DOM during initialization with data and that is detected by Editor.js as a change.

collimarco commented 10 months ago

@neSpecc As a temporary workaround, is there any way to attach the onChange event to Editor.js later? (instead of adding it to new EditorJS)

Something like editorjs.addEventListener('change')... In this way we could first call new EditorJS with some data and then, after the init phase, attach the listener for the onChange

collimarco commented 10 months ago

This issue affects all browsers, including Chrome, Safari and Firefox. It's not something specific to a single browser.

collimarco commented 10 months ago

I have bad news, I have created a new image block that doesn't cause the persistent issue... but still, sometimes (not often as before), even on saved pages that don't have any images, I get a onChange.

I get the onChange on paragraph. It doesn't happen always. It happens sometimes, in particular if I open the editor, the visit another page and then reopen the editor... repeat this N times and you will get an anomalous onChange sometimes. It reminds me of a concurrency issue, because it is not always reproducible.

collimarco commented 10 months ago

Ok, I think that I found a solution:

qbabooba commented 9 months ago

I have found another plugin that is seems to be causing the same issue, to me it was the @editorjs/embed . Can anyone else confirm the same behavior?

dawidpstrak commented 6 months ago

I added logic in my code to block code running on initial on change to solve this problem

collimarco commented 6 months ago

@dawidpstrak Can you please share your workaround (code) here?

dawidpstrak commented 6 months ago

You need to have variable like isInitialOnChangeTriggered set to false and add if statemant in onCHange event handler to block on change logic. Set isInitialOnChangeTriggered to true after initial render. I did this workaround, but I found this text editor a bit buggy if it comes to trigger onChange events and with conjunctions with autosave logic in my application it make my autosave buggy. I switched to quill editor.