uzairfarooq / arrive

Watch for DOM elements creation and removal
MIT License
869 stars 99 forks source link

Can't get it to work in pure JS #73

Closed ninopetrovic closed 4 years ago

ninopetrovic commented 4 years ago

import * as arrive from 'arrive/src/arrive.js';

$(document).arrive('.smthing', () => { console.log('bla'); }); works document.arrive('.smthing', () => { console.log('bla'); }); doesn't work

uzairfarooq commented 4 years ago

Hmm...never had an issue like that. Can you try to removing jQuery from your project and try again?

narcolepticinsomniac commented 4 years ago

I'm pretty sure there's an issue with using arrow functions. I have a script where using a traditional function() works, but an arrow function does not. No jQuery either.

ninopetrovic commented 4 years ago

It says that "document.arrive" => arrive is not a property of document. I also think that there is a problem because I have jQuery in my application... which I cannot remove YET. But I want my new code to be without it.

I guess I'll just go with native MutationObserver

narcolepticinsomniac commented 4 years ago

Works:

// ==UserScript==
// @name         Test arrow function
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        https://github.com/*
// @require      https://raw.githubusercontent.com/narcolepticinsomniac/arrive/master/minified/arrive.min.js
// @grant        none
// ==/UserScript==

document.arrive('body', {fireOnAttributesModification: true, existing: true}, function() {
  if (this.hasAttribute('class')) alert('executed');
});

Does not work:

// ==UserScript==
// @name         Test arrow function
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        https://github.com/*
// @require      https://raw.githubusercontent.com/narcolepticinsomniac/arrive/master/minified/arrive.min.js
// @grant        none
// ==/UserScript==

document.arrive('body', {fireOnAttributesModification: true, existing: true}, () => {
  if (this.hasAttribute('class')) alert('executed');
});
ninopetrovic commented 4 years ago

document.arrive('body', {fireOnAttributesModification: true, existing: true}, function() { if (this.hasAttribute('class')) alert('executed'); });

globalErrorHandler.ts:122 Error: Uncaught (in promise): TypeError: document.arrive is not a function TypeError: document.arrive is not a function at new TestComponent (test.component.ts:32) at createClass (core.js:21150) at createDirectiveInstance (core.js:21027) at createViewNodes (core.js:29387) at createRootView (core.js:29301) at callWithDebugContext (core.js:30309) at Object.debugCreateRootView [as createRootView] (core.js:29819) at ...

uzairfarooq commented 4 years ago

What environment you are working in? Browser?

Created this simple fiddle https://jsfiddle.net/38rhsnbg/ and seems to be working fine in chrome 80.

narcolepticinsomniac commented 4 years ago

Fiddle works fine. Cent 4.2.7.116 (Official Build) (64-bit) (portable) (Chromium 80.0.3987.132) and TamperMonkey Beta. function() works fine, but arrow function throws this error:

error

ninopetrovic commented 4 years ago

Angular 2+, TS, Chrome 80+.

Idk what I'm missing here

uzairfarooq commented 4 years ago

@ninopetrovic can you try this:

document.body.arrive('div', {fireOnAttributesModification: true, existing: true, onceOnly: true}, function() {
  alert('executed');
});
uzairfarooq commented 4 years ago

@narcolepticinsomniac yours seems like a different issue. Are you trying to access element using this?

narcolepticinsomniac commented 4 years ago

Sorry, I wasn't trying to hijack the issue. Thought it might be related.

Are you trying to access element using this?

Obviously, yeah.

narcolepticinsomniac commented 4 years ago

Oh, you didn't in the fiddle. I assumed you copied mine.

ninopetrovic commented 4 years ago

umm I created an angular project on stackblitz and it work fine... but still "TSLint" or what ever throws an syntax error https://stackblitz.com/edit/angular-h64zft

I really don't know what would be wrong with my app.. never had an issue like this with node modules

ninopetrovic commented 4 years ago

Can I any how try to manually "expose the api" on my elements?

uzairfarooq commented 4 years ago

Oh, you didn't in the fiddle. I assumed you copied mine.

@narcolepticinsomniac when you are using arrow function you cannot use this because arrow functions does not allow binding this. You can use the passed param as in the js fiddle.

ninopetrovic commented 4 years ago

Guys tnx for the help but can we just stay in bounds of issue title? I'm pretty sure he know that there is no this arrow function.. like he said he just copied the text in it.

ninopetrovic commented 4 years ago

@uzairfarooq since you know alot about "MutationObserver" can I just ask you this... if I pass in the parent element in like this.

const observer = new MutationObserver(mutations => {
      mutations.forEach(mutation => {
        console.log(mutation);
        if (mutation.addedNodes && mutation.addedNodes.length > 0) {
          const inputElement = cell.querySelector('input');
          if (inputElement) {
            inputElement.select();
            observer.disconnect();
          }
        }
      });
    });
  observer.observe(cell, {childList: true, attributes: true, characterData: true});

how would I disconect from observer if the element that I'm checking for is never generated?

uzairfarooq commented 4 years ago

@ninopetrovic you need to declare the arrive property on document object. Add this to your project:

declare global {
  interface Document { arrive: any; }
}
ninopetrovic commented 4 years ago

can I just do it on HTMLElement?

uzairfarooq commented 4 years ago

@ninopetrovic you will still need to declare the arrive property on HTMLElement first.

ninopetrovic commented 4 years ago

nah.. still logs "document.arrive is not a function"

uzairfarooq commented 4 years ago

This seems like an issue with typescirpt type declaration so closing it.