- Sponsor
-
Notifications
You must be signed in to change notification settings - Fork 177
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
[Questions] - later added elements into the DOM: to be or not to be #102
Comments
I am not sure if bootstrap native uses event delegation but I seem to remember it does not, I think that could be enough. If I have to work with really dynamic pages I prefer using more robust frameworks.
Both is out of topic but I would suggest to implement a modular es6 structure to the project (if I'll have time I'll try to work on that) |
We will work on The future BSN release will feature bootstrap original events, 24Kb minimized, a ton of improvements and new features. It would be something to consider, especially if I manage to get it done with the new features I have in mind. |
I would like a way to add one or more BSN component at "runtime" (after the
page load time upgrading process has already initialized the elements
originally on the page.) So, yes to question no1.
I noticed that Bootstrap 4 is apparently dropping IE8 and IE9 support. From
https://v4-alpha.getbootstrap.com/migration/#browser-support:
- Dropped IE8, IE9, and iOS 6 support. v4 is now only IE10+ and iOS 7+. For sites needing either of those, use v3.
So, one way we could support dynamic BSN initialization would be to make
optional custom elements which know how to initialize automatically when
they get attached to the DOM.
If you ignore the very cool "Shadow DOM" (see below), webcomponentsjs
(https://github.com/WebComponents/webcomponentsjs) has a nice polyfill for
custom elements that works nicely on IE10+. Chrome supports custom
elements natively, and I believe Firefox and Safari do too.
The polyfill only needs to be loaded on browsers like IE10+ that don't
support custom elements. The polyfill uses MutationObserver to notice new
custom elements and upgrade them. Chrome notices via a built-in process,
so you don't have the overhead of instrumenting the DOM with a
MutationObserver, which makes this idea probably more performant and in the
spirit of ditching jQuery and going native as much as possible.
We'd have to create custom elements, e.g. `<bootstrap-modal>` or whatever you
want to call it, which would come with implementation in its "attached"
callback that runs the right initialization JavaScript that would have
happened at page loadtime had the element been present then. When I say
"attached" callback, I'm referring to the webcomponents V0 spec. The spec
has moved to V1 this article
https://component.kitchen/blog/posts/our-experience-upgrading-web-components-from-shadow-domcustom-elements-v0-to-v1
discusses the changes.
But the polyfill for V1 isn't quite ready, but I'm imagining we could
target (V1)[developer.mozilla.org/en-US/docs/Web/Web_Components/Custom_Elements],
in which case the "attached" callback has been renamed to the
"connectedCallback", a function on your custom element which gets called
when you element is added to the DOM. Roughly the same idea with a new
name. In that function, we'd initialize the modal. Any cleanup could
happen in the "disconnectedCallback" (like removing event listeners.)
By publishing custom elements, we would make things like "modal" much more
modular and object-oriented. By optionally using a polyfill on IE10+. we'd
be clean on browsers supporting the V1 spec, and only take the
MutationObserver hit on non-conformant browsers.
Note on ShadowDOM -- ShadowDOM is very cool because it creates a DOM island
for your custom element that is essentially private, so that you can style
it with your own CSS and not have to worry about other CSS rules bleeding
through onto it. I don't think we need a ShadowDOM in our custom elements,
because we want them to be styled by global Bootstrap and its theme. It is
easier to create a custom element without ShadowDOM, and we can always add
it later if we need to. But ShadowDOM is dicey in the polyfill, and
there's been lots of churn around it in projects like Polymer, so I think
we could ignore it for the time being.
…-Jeff
|
I am working on an document.addEventListener('update.bs.dom', function(e){
// e.target is document
// e.relatedTarget is the new/removed element
// OR
// e.boundElements [Array] IE8 with a newly added/removed element and it's children
// this event is only triggered when appendChild/removeChild methods are used
}, false) When the event fires, there could be a handler to apply a proper BSN component via DATA API or something. This is probably suitable for BSN for BS3, but what do you think? Indeed the |
I have been building a modified version of bootstrap.native that works even if you modify the DOM (without calling extra functions), but it is missing some elements. Would it help if I published it on GitHub? |
@Aspie96 I believe it's an IE9+ solution? |
I made it a while ago, but it should be IE8+. |
@Aspie96 please go for a fork of the current master and start applying your changes, I am curious if there could be something better than my current development. Again, the BSN 1.5 series coming soon will have major code changes, for sure your version will not be mergeable with that, but at least we can all have an idea. @Jeff17Robbins reading more into your input I can now say that everything you talk about is likely doable for the BSN for BS4, in combination with what @kuus was talking about. I am also interested in how you would want this to be implemented. |
Forking is exactly what I did, but I cannot publish the project right now since I am not at home. It is actuallyn quite a bit different from yours, but it is fully based on yours. As I said, some controls are missing. Maybe, before pushing on GitHub, I will paste the code on PasteBin (to fix a few things before pushing, like… the manual XD). Thank you for using a free license such as MIT. |
Here's a very crude, but working, example of packaging BSN Modal as a custom element. You need Chrome to see it run, because I didn't load the webcomponents polyfill. https://jsfiddle.net/w1cmLc0g/ I call it 'crude' because it doesn't encapsulate everything about Modal, and it hasn't hidden the Modal's dialog contents in Shadow DOM, but it does define the toplevel aria and other attributes for you, showing how encapsulation can reduce user boilerplate.
It takes care of that boilerplate plus instancing the BSN object in its
A fancier version would place the Modal's template in a |
As much as I like your example, it's too outer space for me, maybe you can shed some light for me: do the NO NO, let me ask you this: is there anything you can explain to me who I just heard of Thanks :) |
I don't understand your question, sorry. The beauty of a custom element is
that it is a first class citizen of the browser. Rather than hijacking div
s to make them be a modal, you can have a true bsn-modal element. Why is
that outer space?
…On Tue, Jan 17, 2017, 11:16 AM thednp ***@***.***> wrote:
As much as I like your example, it's too outer space for me, maybe you can
shed some light for me: do the customElements behave like they are under
MutationObserver, or something to enable dynamic content...
NO NO, let me ask you this: is there anything you can explain to me who I
just heard of customElements and MutationObserver what is BEST to do,
WHERE is BEST to go forth?
Thanks :)
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#102 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ACAWhz0H1Qm-XtC4sRBtIScgmIvXmX7iks5rTOk_gaJpZM4Lj-Tp>
.
|
It's a bit unusual for me, I still try to figure out ways to make components work in IE8+ and your examples blow me away so high... I never done this before, even if I knew there are some ways I can create custom elements, just I didn't investigate into that yet. Anyways, we expect more people share their opinion in this topic, eventually we're getting somewhere. |
Got it! Yeah, we've dropped everything below IE11, but I understand that
not everyone can do that.
…On Tue, Jan 17, 2017, 11:27 AM thednp ***@***.***> wrote:
Why is that outer space?
It's a bit unusual for me, I still try to figure out way to make
components work in IE8+ and your examples blow me away so high...
Anyways, we expect more people share their opinion in this topic,
eventually we're getting somewhere.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#102 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ACAWh-HOwXItzRET11r0lxpwNuA_9fwuks5rTOwAgaJpZM4Lj-Tp>
.
|
@Jeff17Robbins I improved your code bit, for multiple modals: http://codepen.io/dgt41/pen/LxbzQG |
So using custom elements for our library's components would make this library |
@thednp as I mentioned before, if I get some free time, I'm willing to create a Custom Elements fork of your library, @Jeff17Robbins is right CE are first class citizens for browsers and also the polyfill https://github.com/WebComponents/webcomponentsjs makes it compatible up to IE9(*) Implementing your library as custom elements should be on your radar for BS4... |
Yes, because you get a life cycle callback ("connected callback") which
gets called when the element is attached to the DOM. That is your hook to
do whatever you need to make the element useful.
There is also a "disconnectedCallback" when the element is removed from the
DOM. Useful for cleanup.
…On Tue, Jan 17, 2017, 11:37 AM thednp ***@***.***> wrote:
@Jeff17Robbins <https://github.com/Jeff17Robbins>
So using custom elements for our library's components would make this
library dynamic content enabled?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#102 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ACAWhyFCI_AeU2oEfw9gSUpBKJLdV4EMks5rTO4tgaJpZM4Lj-Tp>
.
|
In my current code, I changed the way components get initialized via DATA API, I have a new utility for that. Additionally, I've setup a |
@DGT41 I moved the dialog markup to templates. http://codepen.io/anon/pen/PWbXwr?editors=1010 Not necessarily better, but illustrates using the |
@Jeff17Robbins, @DGT41 Instead, our way, we attach event handlers to each element on initialization, and if a modern browser detects you have deleted an element from the DOM, it will also clear the event handlers attached, which is a major plus. Right now I have in mind a global click,scroll, etc handler attached to I am super curious about your ideas on that. |
I just commited a new version, please do some testing everyone ;) |
I updated my custom element Modal example to the latest cdn version. It still works. I haven't dug in to see how the new event code works, but thought I'd post the example if it helps. |
CDNjs is a bit behind, probably stuck in some semver related issue, here's the latest CDN I changed your pen with this one and it's not working, you must check the updated documentation on Modal. I made some changes, I hope you get the point of the changes |
I'm confused. What is not working in http://codepen.io/anon/pen/GrOYoO? |
That isn't the latest CDN. Should be 2.0.1. |
This is the line from http://codepen.io/anon/pen/GrOYoO? that pulls in BSN: Screenshot below. What isn't "2.0.1" about this? I'm confused because it says "2.0.1" in its path! |
@quantix-studio : Perhaps it is way beyond the topic here but here's a small example for a dropdown which doesn't include the click outside behavior but it's easy to add but slightly too overwhelming (like a
This way you can also directly manage the persistent behavior if you need to with |
Hi, Is it an expected behaviour ? |
@mathieuleclaire this is my last reply on this regard: our library here is not jQuery powered and doesn't initialize on the fly for later added objects and also doesn't destroy instances for removed objects. In short it does nothing about any kind of DOM tree changes. In this thread I am asking other developers for a better approach (better than original jQuery plugins for Bootstrap), as we haven't implemented anything here yet, we are still at the research phase. I would suggest to create a constructor with a callback, and the callback should initialize your newly added elements or destroy removed elements. |
@thednp check my approach for v4: https://dgt41.github.io/bs4-custom-elements/ |
I was about to ask if anyone has done anything on this, so yea, lookin good. |
Nice work @DGT41 |
Just in case someone wants to check it out too: https://github.com/Aspie96/bootstrap.native.dynamic It's in no way intended to be better than bootstrap.native or antyhing like that. |
Thanks for the heads up @Aspie96 |
@jsdelivrbot npm bootstrap.native |
Browse the CDN files https://cdn.jsdelivr.net/npm/bootstrap.native/ Load the main file https://cdn.jsdelivr.net/npm/[email protected] Version aliasing to latest major release https://cdn.jsdelivr.net/npm/bootstrap.native@2 Add .min. to files to auto-minify. |
Out of curiosity, was any reason given for initialization via delegated events being bad? Isn't event delegation considered a good thing? I'm also a little leery of the custom element approach, if only because this is, as far as I can tell, intended to be a drop-in replacement of existing Bootstrap behavioral code. Requiring that people now use custom elements would break that and have pretty major impacts on anyone trying to switch from regular Bootstrap to bsn. |
@Ixonal I cannot find the forum post where people talk about poor performance of delegated events, it's basically a way jQuery does (did) in dealing with everything you throw at it at the cost of performance. Don't get me wrong, jQuery does a ton of things right, in a very elegant and uniform manner, just that the demand for better performance always wins in the end. Custom elements seems to be the next generation content delivery dynamics, I have no doubt about it now, my code should work just fine with it regardless, as shown here. (I updated the fiddle). It's a matter of taste and application, it's pointless arguing which way is best, any library can be very suitable for many use cases. |
@thednp I could see there being delegation performance issues if there are a great deal of handlers (and I mean an absurd amount) that are tied to selectors (instead of specific elements), as that would run the Sizzle selector engine a great many times, which would be horribly inefficient. Adding one delegated handler per component type (to init the component), however, should not add any appreciable overhead. In the way of custom elements, I'm not arguing their usefulness or that they're the way web development is moving. My argument is that Bootstrap presented a certain interface. Your library purports to adhere to that interface, but moving to using custom elements breaks that contract. Were Bootstrap to use custom elements, and your library moved to match, I would have no issue. |
what is the status of this issue? |
@Ruffio the issue is still open. |
Hello :) My view is this:
Someone mentioned moving to es6 - I also agree. That would add one little step to the build process (babel) and also allow having multiple builds ( I'm adding this repo to my favorites and I'll try to observe its development just in case I have time to help - you are doing a good job that should have been incorporated into official TWBS IMO, I don't know why it hasn't, such a great initiative (I've been dreaming about it for a long time). Cheers, Pawel |
Yes = to be. |
I am not in favor of this. If we add more components to the DOM we should be responsible for wiring up their javascript. |
Personnaly my answered would have been quite simple: " As it's working dynamically in the original twitter bootstrap, this should be also implemented here. " If not, using this library is simply awfull in a SPA. At least, it should exist an option, to have let the library being dynamic. |
@TwanoO67 if you would be so kind as to come with an idea on how to implement it would make a better world, instead you come with a "your library is awfull in SPA". |
Sorry @thednp it wasnt meant to be hurtfull. The idea was the library is good and it's nice to not depend on jQuery and so ever. As I understand there was plenty of implementation proposal in the previous messages. So I don't think that mine would be of any help ( as it is based on mutation observer as previously proposed). The point was just that, as lot of people is needing it, the implementation you thing the most "proper" one should be proposed in the lib |
Hello, firstly thank you for a great lib! It's really helpful for me. Regarding the issue, imho basically the best (and easiest) solution to make it fully compatible with BS4 without any troubles would be doing exactly what they currently do - event delegation. It's currently simplest solution to this problem. |
I know a little late for the party, but I've been following this issue for a little over a year and with no news for now. In version 3.0.0 I made modifications to meet my dynamic loading needs and add ES6 export see link: https://github.com/subversivo58/misc/blob/master/js/bootstrap.native.mjs Now I am migrating to Bootstrapv5 and I have returned to the question of support for dynamic elements. In the current version (3.0.14c) I added only two auxiliary functions and use The use of The modification itself: // before `export`
// helpers
function isUndefined(arg) {
return arg === void 0;
}
function isElement(obj) {
try {
return (obj.constructor.__proto__.prototype.constructor.name) ? true : false;
} catch(_) {
return false;
}
}
// Options for the observer (which mutations to observe)
let config = { childList: true, subtree: true };
// Callback function to execute when mutations are observed
let callback = function(mutationsList) {
for(let mutation of mutationsList) {
if (mutation.type === 'childList') {
;[...mutation.addedNodes].forEach(async addedNode => {
if ( isElement(addedNode) && !isUndefined(addedNode.querySelectorAll) ) {
await initCallback(addedNode, true);
}
})
}
}
};
// Create an observer instance linked to the callback function
let observer = new MutationObserver(callback);
// Start observing the target node for configured mutations
observer.observe(document, config); I would like to hear some thought about the usefulness of this in this library since See: https://caniuse.com/async-functions and https://caniuse.com/mdn-javascript_operators_await PS: |
Well this is part of the init of our library, I think it's open to any and each developer to create his/her own implementation. If As other people mentioned above, I'm still not considering delegating All in all, I'm more in favor of having the issue open and allow devs like yourself to contribute, share ideas and implement something beneficial to everyone. In my mind we could have several versions of
In the end every solution is suitable for a specific case. What's on your mind? |
I have no experience with |
@subversivo58 you can actually do that already, if you check some wiki of this project you can figure out for yourself. I think it's time to put this issue to rest, I've seen Thanks to everyone contributing. |
For those who work with DOM manipulations and use the library or have any experience with JavaScript driven dynamic content, please reply:
Do you think we would need some tools and/or polyfills to enable our library to go LIVE (initialize proper BSN component for every new element added to the DOM) ?
If yes, what would you suggest? (I am currently experimenting with
CustomEvent
,MutationEvent
andMutationObserver
, working on a kind of polyfill for IE8)About an IE8 polyfill, do you (or your scripts and tools) use mostly
Element.prototype.appendChild
,Element.prototype.innerHTML
, both, or other methods?To the most frequent contributors (please forgive me for tagging you)
@mathieuleclaire, @troyk, @mgiulio, @janpanschab, @RyanZim, @HelloGravity, @Jeff17Robbins, @DGT41, @oliseviche, @thewisenerd, @alzalabany, @kuus, @malexdev, @crcastle, @Aspie96, @CamWiseOwl, @antoligy, @zandaqo
AND anybody reading this page, please share your opinion.
The text was updated successfully, but these errors were encountered: