Vue - when and why using $el - javascript

I've found this answer here:
https://stackoverflow.com/a/50431015/11735826
and i wonder why .$el was used here, and also why does it not work without the el element?

when you use ref attribute on the html tag, the DOM-element is returned by this.$refs.modal.
when you use ref attribute on the template tag, the component instance is returned, so this.$refs.modal.$el returns directly the DOM element. See https://v2.vuejs.org/v2/api/#vm-el

$el returns the HTML element to which a given Vue instance (be it a main instance or a component) is bound. By using this.$refs.modal.$el the answer gets the underlying HTML element for the this.$refs.modal, and then encapsulates it in a jQuery object to call the modal method.

Related

GetElementById from within Shadow DOM

I have a custom-element with shadow DOM, which listens to attribute target change.
target is supposed to be the ID of the element which my component is supposed to be attached to.
I've tried using querySelector and getElementById to get the element of the outer DOM, but it always returns null.
console.log(document.getElementById(target));
console.log(document.querySelector('#' + target));
Both of the above return null.
Is there a way to get a reference to the element in the parent document from within shadow DOM?
You just have to call Shadow​Root.
this.shadowRoot.getElementById('target') should work.
Here's an example, the get syntax will bind an object property to a function.
get target() {
return this.shadowRoot.getElementById('target');
}
There are two use cases of shadow DOM as far as I can see:
You control the the shadow DOM solely through your hosting custom element (like in the answer of #Penny Liu). If you want make sure no other script should call and alter the nodes than this is your choice. Pretty sure some banking websites use this method. You give up on flexibility though.
You just want to scope some parts of your code for styling reasons but you like to control it via document.getElementById than you can use <slot>. After all, many libraries rely on the document object and will not work in shadow DOM.
Back to the problem, what you probably did was something like this:
shadowRoot.innerHTML = `...<script>document.getElementById('target')</script>`
// or shadowRoot.appendChild
This is NOT working! And this is not how shadow DOM was anticipated to work either.
Recalling method 2, you SHOULD fill your shadow DOM solely by <slot> tags. Most minimal example:
<!-- Custom Element -->
<scoped-playground>
<style>some scoped styling</style>
<div id="target"></div>
<script>const ☝☝☝☝ = document.getElementById('target')</script>
</scoped-playground>
<!-- Scoped playground has a shadowRoot with a default <slot> -->
...
this.shadowRoot.innerHTML = "<slot>Everything is rendered here</slot>";
...
More advanced <slot> examples can be found at:
https://developers.google.com/web/fundamentals/web-components/shadowdom#composition_slot

How to Create a Custom Element with a Shadow Root Already Attached

Having a simple custom element
document.registerElement('x-foo', {
prototype: HTMLElement.prototype;
});
I can create an HTML node
<x-foo></x-foo>
then select it in JavaScript, and attach a shadow root.
var xFoo = document.querySelector('x-foo')[0];
var root = xFoo.createShadowRoot();
root.textContent = 'I am a shadow root';
However, I would like the objects to be created with a predefined
shadow root, without any JavaScript manipulations afterwards, as it is with
<input> and other user-agent defined nodes.
How would I define a constructor or something for my element in order to achieve this?
Question is a bit old, but putting this answer here in case you haven't figured it out yet.
There are 4 lifecycle callback methods associated with custom elements. Copying from this nice tutorial on html5rocks.
So to answer you question, you can put your code to attach a shadow-root to custom element inside createdCallback and it will be executed every time your x-code element is initialized.
This is a sort of constructor for your custom element.
Hope it helps.

Jquery clone() doesn't clone new value set wit data()

Using jquery data() to set data attribute of an element, like so:
HTML:
<div id="some-el" data-number="0"></div>
JQ:
$("#some-el").data("number",1);
As we know, data changes variable internally. So inside inspector you cannot actually see that new value is 1. But this aside, if I do clone on the element with new data value, jquery clones original dom element without current data value!!!
$("#some-el").clone();
Results in <div id="some-el" data-number="0"></div> both internally and visibly!
I was thinking I could avoid this problem by simply using attr("data-number",1);
Anyways, I wanted to ask you if this is correct behaviour of dat()? Is what I'm seeing expected? and WHY?
I think clone can accept a boolean to indicate a Clone with data and events, so Clone(true) should work: http://api.jquery.com/clone/
Here's a fiddle that works: http://jsfiddle.net/2pdNL/
.data() is not setting the value in DOM.
The data- attributes are pulled in the first time the data property is
accessed and then are no longer accessed or mutated (all data values
are then stored internally in jQuery)
But here is a workaround, instead of using
$("#some-el").data("number",1);
Interact directly to DOM like
$("#some-el").attr("data-number",1);
JSFiddle
Also check this answer

jquery data do not match dom attribute

I have an weird issue with jquery data function. Here is the fiddle
As you can see I update the active data but I cannot see the dom data-active attribute value change, although I re-query the active data, It writes the changed value.
$.data() do not update the attribute on the dom when I inspect it.
jQuery data api does not depends on the element attribute although it uses data-<key> to fetch the initial value if it is available.
jQuery uses an internal javascript object to maintain the data value of objects
If you want to update the attribute then you will have to use .attr('data-<key>', '<value>')
You will need to use attr as .data will not update the actual DOM node attribute -
$($('li')[1]).attr('data-active', true);
http://api.jquery.com/data/

How to insert a HTML fragment and hold a reference to the outer element?

I've always wondered how this jQuery feature works: $('<span>Hello world</span>')[0]
That is supposed to return a reference to the newly created span element. How can I achieve the same result using the native DOM methods? insertAdjacentHTML? innerHTML? documentFragment?
I need to insert a HTML fragment and hold a reference to the outer element without the need of using createElement/appendChild.
Thanks.
It's possible to create an element, set its innerHTML, and return the first child. The container element is never added to the DOM:
var el = document.createElement('div');
el.innerHTML = '<span>Hello world</span>';
console.log(el.firstChild);
If that's wrapped in a function, I believe the original container will be eligible for garbage collection as soon as the child is appended somewhere else.
jQuery seems to be doing something more sophisticated, checking if the string contains a single tag or not, and creating a fragment for more complicated strings. See the parseHTML method on jQuery's source code.

Categories