Topic: Side-nav, Card expendent and others JS Stuff not working afer DOM update

Colinet free asked 3 years ago


Expected behavior I load HTML and generate HTML content and add it to the DOM. Thinks are working as espected on CHROME, but I have to reload mdb.js every time.

Actual behavior On Firefox and Safari, added content not working as expected. CSS is OK, but javascript not. SO, for example, Side Nav not collapse, and not expendant/collapse menu links Or, an extended Card display the extend content on to the top of the card, buy juxtapose the 2 elements instead off grow.

Resources (screenshots, code snippets etc.) I try to find how restart/reload mdb.js after html injection, but noway. Just find that we have to insert mdb.js after every dom change Trys with and jquery ajax getScript I try to do this action on document ready, on ajaxcomplete, ... Everything is working on CHROME as espected, but not on others browser. Anf if I create a static page, it's work on chrome and safari as expected. The problem defenitly comes with AJAX call/+DOM Update

Can anybody tell me the correct way/practice to make it works on every browser ? Thanks LauCo

Problm display on safari

Expected result on Chrome


Colinet free answered 3 years ago


var el = document.getElementById('body'),
                    elClone = el.cloneNode(true);
                el.parentNode.replaceChild(elClone, el);

For that, you need id='body' in your body. This clone the Dom, and replace it. By doing this, you remove ALL event created before, attached to the old Dom. So calling that before appending the Dom and re calling load prevent creating event in double or more.

That is not possible without intercepting addEventListener calls and keep track of the listeners or use a library that allows such features unfortunately. It would have been if the listeners collection was accessible but the feature wasn't implemented.

The closest thing you can do is to remove all listeners by cloning the element, which will not clone the listeners collection.

Note: This will also remove listeners on element's children.

https://www.codegrepper.com/code-examples/javascript/javascript+remove+all+event+listeners

If anybody have better. but it's work fine.


Krzysztof Wilk staff commented 3 years ago

Hi!

I'm glad it helped :) If you have more questions - feel free to ask.

Best regards


Colinet free commented 3 years ago

Just hope help some one else. just one would be great : - ) But we should change the subject to something like

how make MDB JQUERY to work after a Dom change

Best regards


Colinet free answered 3 years ago


Finaly here is the complete solution : And so, for those look for MDB 4 JQUERY not working after Dom change solution is probably

First: Place your init script about your needs in $(document.ready). this event is fired once and only once, even when load is recall or on ajaxcomplete But, every eventual $(document).ready placed on the document DOM changes are goins to be fired just one at the end off ajaxcall.

Second: place at the end of html document

<script>$(document).ajaxComplete(function(){
            dispatchEvent(new Event('DOMContentLoaded'));
            dispatchEvent(new Event('load'));
        });</script>

And finaly, on every Ajax call, on success do

 var el = document.getElementById('body'),
                    elClone = el.cloneNode(true);

                el.parentNode.replaceChild(elClone, el);
$("#MDB_JS").remove();         
$("body").append("<script id=\"MDB_JS\" src=\"/js/MDB/js/mdb.min.js\" type=\"text/javascript\"></script>");

Why on success instead off onajaxcomplete ? Because I t's not work on complete, we have to do something before append so before complete

this solution work for me Lauco


Colinet free answered 3 years ago


Hi, Thanks,

Hi!

New events don't replace old ones with the same name. When you add two event listeners for the same event, both callbacks will call when an event occurs.

Best regards

So to be really proper, my solution need to kill all event before recreate it.Can you provide me a way for that ?I'm looking for, without success at this time.


Colinet free answered 3 years ago


Hi, Now it's seems to be perfect, thanks, but this :

Remember that when you are reloading our scripts - you are adding many event listeners and instances that will cause even more problems.

What about that ? if event have the same name, no problem, new event replace old one. But if event have no name or dynamic name, it should be more annoying

Can you inform me about that ? Thanks

Lauco


Krzysztof Wilk staff commented 3 years ago

Hi!

New events don't replace old ones with the same name. When you add two event listeners for the same event, both callbacks will call when an event occurs.

Best regards


Krzysztof Wilk staff answered 3 years ago


Hi!

Is that solution resolved your problem? Do you need some more help?

Best regards


Colinet free answered 3 years ago


PRETTY GOOD

For JS height calculation, this is OK now with all browser by including MDB.JS once. I suppose it's juste include once, not on all load event as I suppose, because some other stuff is not working. like the rotation of cards, or the display and the functionality of side-nav. the menu is not display correctly and not working.

Because I began with that trouble first with CHROME, I know IT's because I have to re include MDB.JS.

SO now, if I fired load event and reload MDB.js script everything seems to be working good and as expected on every browser.

So finaly, what's the problem to to something like :

$("#MDB_JS").remove();         
$("body").append("<script id=\"MDB_JS\" src=\"/js/MDB/js/mdb.min.js\" type=\"text/javascript\"></script>");

Or

function reload_js(src) {
    $('script[src="' + src + '"]').remove();
    $('<script>').attr('src', src).appendTo('head');
}
reload_js('mdb.js.js');

who is exactly the same as I undestand. And As I found in the form as good answer.

you have to include mdb.js on every Dom change

What about the events ? finaly not a problem ?

And so, for those look for MDB 4 JQUERY not working after Dom change solution is probably

First: Place your init script about your needs in $(document.ready). this event is fired once and only once, even when load is recall or on ajaxcomplete But, every eventual $(document).ready placed on the document DOM changes are goins to be fired just one at the end off ajaxcall.

Second: place at the end of html document

    <script>$(document).ajaxComplete(function(){
                dispatchEvent(new Event('DOMContentLoaded'));
                dispatchEvent(new Event('load'));
            });</script>

And finaly, on every Ajax call, on success do

$("#MDB_JS").remove();         
$("body").append("<script id=\"MDB_JS\" src=\"/js/MDB/js/mdb.min.js\" type=\"text/javascript\"></script>");

Why on success instead off onajaxcomplete ? Because I do it as, probably you can place all in onajaxcomplete. try it : - ) For me, and it's not really a real reason as I understand now, it's because I modify the Dom between and this modification is not the same every Ajax call.

for example

 $("#MDB_JS").remove();

$("#pinaas").html(data.html); $("body").addClass("home_body").removeClass("black-skin fixed-sn"); $("body").append("");

But I will try

 <script>$(document).ajaxComplete(function(){
$("#MDB_JS").remove();
 $("body").append("<script id=\"MDB_JS\" src=\"/js/MDB/js/mdb.min.js\" type=\"text/javascript\"></script>");
dispatchEvent(new Event('DOMContentLoaded'));});</script>

And just keep on Ajax call success

$("#pinaas").html(data.html);
$("body").addClass("home_body").removeClass("black-skin fixed-sn");

Hope save someone somewhere sometimes LauCo


Colinet free commented 3 years ago

Try not work, work on success perfectly. Not work onajaxcomplete

And I prefer append the text for include script like get script because get script by default really load script each call. The other way use cache. U can use Ajax cache true if you want, but I prefer like this because now it's work perfectly as expected


Colinet free answered 3 years ago


Difference between CHROM and OTHERS

Like lots of times, supposition are probably not correct. For work around, I just include MDB.JS one time. When cache is empty, CHROME is like others. When cache is active, CHROME is doing the java calculation.

SO, there is a difference with CHROM if cache is present. If not, it's like others.

I très to find a way to log events but those I trie not working for me, or I'm not able to make its work.

I continue to look for a way to log event creation and event firering.

Best Lauco


Colinet free commented 3 years ago

So, chrome is fired event as this : DOMContentLoaded Ajaxcomplete(because of my Ajax call) message load message

And for safari and firefox this is : DOMContentLoaded load ajaxcomplete

do not seen any message for those

So I suppose the problem come from the load call who is made before ajaxcomplete

Nut now, if I fired load again, I suppose this is the moment where javascript loaded is launched. So when call load again, it's recall ALL loaded javascript. It's pretty the same as reload the MDB.js script. It' should cause bug due to event creation more than once ?


Colinet free answered 3 years ago


Hi Staff Wilk,

Thanks for your precise reply. I will work around as you suggested.

If I Understand you, when I include mob.js, it's create many event. So, if I include 3 time the file, I should have 3 times event created ? Is that correct ? So if it's, the only approches is to remove all event before include or, just include once. Is that correct ?

The reload function you présent are not solving event issue ?

And the best approach is to have all container pre formatted but display:none for getting a correct aspect for the calculation. It's a good approach I think, but it's not possible on everything. For example, side-nav. I want the it can be customizable by the user by adding a link for example. And without reloading all the page content. In that case, I suppose I just can re-apply the script.

Buy the way, Ready or others js framework are doing that for me. But, I've bought theJQUERY version, and I try to get a more simple js framework.

It's done now, perfect for my needs, but the init() function off MDB pro is not exist. Why you do not write the MDB.js with an init() function who destroy all event listener created before by itsef, and re do the all script.

Its so simple, and cas save times for many I suppose. If I can have a event list or something, I can do it my self. I can do it buy reverse engineering to, but to many times for that problem.

So, enough speaking, I'm going to work around with your advices. I'll apréciate if you can answer me again : - )

Best gregards, And, but the init problem, I really love your work. I'm feeling like a designer now. I just have to copy/paste your examples, modify css really what's I was looking for. Thanks also for that to the team


Colinet free commented 3 years ago

Also, is MBD.js init static event ? (alias the same with the same name) ? or dynamicly ?


Colinet free commented 3 years ago

And, is those event have something like an identifier ? like, always begin the name with MDB_


Colinet free commented 3 years ago

And finaly, who/when those event are created ?I suppose it's not directly on the load script when include, because I re-include it and it's work for some, but not for others, like the js height calculation.So I hope, this wait and eventand we can fire this event like dispatchEvent(new Event('load'));And so, with that event, fire the js height calculation again : - )


Colinet free commented 3 years ago

For those loving this subject$(element).on("click mousedown mouseup focus blur keydown change",function(e){ console.log(e);});log all event with that and try find what you need

ADD: $(element).on is not exist JQUERY 3 ? I replace it by $(document).on


Colinet free commented 3 years ago

AND YES, remembre, thinks works correctly on CHROME, So CHROME is doing something others not. And what is it ? probably a common event like load (but it's not that) and not document.ready too, I was logging those event for debug this before


Krzysztof Wilk staff answered 3 years ago


Hi!

Height is calculated by our JavaScript, so that's no problem with CSS. I'm afraid you won't achieve what you want with jQuery. When you load your page - some scripts are activated, but it will never (for example) initialize your components after DOM is loaded. Of course, you can try to fix it but it always won't work properly on every browser.

The solution I can recommend you for now is to generate the whole DOM and work with the display CSS property (show element when an event occurs or hide if it is not needed).

You can also try this reloading function:

function reload_js(src) {
    $('script[src="' + src + '"]').remove();
    $('<script>').attr('src', src).appendTo('head');
}
reload_js('source_file.js');

Remember that when you are reloading our scripts - you are adding many event listeners and instances that will cause even more problems.

Developers are using React / Angular / Vue frameworks to make Single Page Applications like your one, so I highly recommend you to use one of them.

Best regards


Colinet free answered 3 years ago


Hmm, found about rthe problem. In Chrome after load :

<div class="card-wrapper" style="height: 366.875px;">

In Safari or Mozzilla :

<div class="card-wrapper">

Fore some reason, the height calculation not working but for chrome. who is responsible of this height calculation ? this is not from me, so I suspect the framework. How cas I force initialisation of this calculation ? Buy removing and adding a css file ?

Thanks


Colinet free answered 3 years ago


Definitly, this is not the problème I suspect.Buy the way, I must include mdb.js in all end off ajax call,as I found.Fort that you can

$.getScript("/js/MDB/js/mdb.min.js", function() { $('script:last').attr('id', 'MDB\_JS'); });

Or simply

  $("body").append("<script id=\"MDB_JS\" src=\"/js/MDB/js/mdb.min.js\" type=\"text/javascript\"></script>");

I'm not sure if it's realy important, but more clean, so before append html and append script here

$("#MDB\_JS").remove();

So, my trouble was 2ble.First, the script for calling validation is from load() javascript event.But load is just call at the end of the load, not on dom update.For that, jquery.document.ready()function is OK, but if INCLUDED in the NEW HTML code.document.ready is just call ones.There is alse jquery.onajaxcomplete who is called on EACH enn of ajax call.

So, this is why my form not working, and others.Now I'm just still. have a CSS trouble (I suppose). You can see it on the picture.I suppose this is just a CSS tuning trick ? (like display block or position relative)

But, remember the display trouble is on the dynamique page.If I use it as fixed HTML, in this case, and with the same css files, the form are expended normaly.The display trouble only on a loaded/Générated FORM

Is some one have an idea ? or a work arround.Thanks



Please insert min. 20 characters.

FREE CONSULTATION

Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.

Status

Resolved

Specification of the issue

  • ForumUser: Free
  • Premium support: No
  • Technology: MDB jQuery
  • MDB Version: 4.19.1
  • Device: ALL
  • Browser: Safari - Firefox
  • OS: Mac Catalina
  • Provided sample code: No
  • Provided link: No