I will rendering a React component in to an existing website, an example of the root element might be:
<div id="root"></div>
What I would like to do is, access any html inside the root element to begin with for example:
<div id="root">Hello world</div>
The documentation seems to indicate you can do something along these lines:
ReactDOM.render() does not modify the container node (only modifies
the children of the container). It may be possible to insert a
component to an existing DOM node without overwriting the existing
children.
I have tried to access using refs but I can't access these child DOM elements, does anyone know how I can achieve this?
<div id="root" ref="root">Hello world</div>
Unfortunately this isn't possible in ReactDOM directly.
The "Hello world" string in your <div id="root"> is treated as a child of the container node, and is therefore overwritten.
Instead, you'll need to get the .innerHTML from the div with the ID of root before ReactDOM's render() method is called. You can then do whatever you want with this afterwards:
let root = document.getElementById("root");
let existingContent = root.innerHTML;
ReactDOM.render(yourReactComponent, root);
console.log(existingContent); // Do whatever you need to do with this
Related
I need the bounding client rect of an anchor element.
I mark that using bind:this={someVariable}
But when I add that code to a svelte component, I get some other object svelte uses to represent a component.
can I access the enclosed element or something like that from that binding?
Or do I have to wrap every component with a sacrificial <div /> and bind that?
Using bind:this does not give you a DOM Element because Svelte does not require that your component has a root element. This is a valid Svelte element:
<script>
...
</script>
<div>...</div>
<div>...</div>
And so is a component that does not have any markup at all:
<script>
...
</script>
In both those cases, it would be impossible to return a bounding client rect for these components because there is no 'root' element.
That said, what you can do is add a bind:this in your component and export that one:
<script>
export let anchor
</script>
<svelte:options accessors></svelte:options>
<a bind:this={anchor}>...</a>
And in your parent you can now get the anchor element using child.anchor (note that by default the props are not accessible this way, that's why you need the svelte:options)
One of the reason this is not so straightforward though is that it is a very 'unsvelte' way of working, you would normally not direcly interact with the markup generated by another component (that is the domain of that component).
Alternatives could be
expose the client rectangle directly instead of the element
move what you are trying to do to the anchor component itself
In jquery , I can use $(this) reference to access an element without using any class or id. What is the way to achieve similar result in vue.js?
I assume you want to get an element which triggered event. Then it should be event.target.
For example:
<div #click="sayHi"></div>
methods: {
sayHi(event) {
console.log(event.target)
}
}
The prior answer refers to this.$el which grabs the root element of a given Vue component (Vue documentation on .el), however, if you want to grab an arbitrary element within a given component, you can use this.$refs (Vue documentation on .refs):
<template>
<div>
<h1 ref="myHeader">Hello</h1>
<div>
<template>
this.$el within a Vue component
If i have a presentational (child) component with the following line:
<small id="parameters"> some parameters text </small>
I noticed that if i go to its parent container component and try to get that element by:
const textElem = document.getElementById('parameters').value;
It is not going to get its value.
Why is that? If i use document in a component, is it only "local" to that component?
You can use document inside a component, to reference the global document object, it's not local to that component, however, at the point you're referencing document.getElementById('parameters') this element might not have been rendered yet to the dom, so make sure to call it after the child element has rendered.
On the other hand, maybe you meant to use: document.getElementById('parameters').innerHTML
to get the text inside that element, instead of .value
I have a container who have inside many elements like h1, p etc.
This container have a background, and I want create method to move him by mouse coordinates. I have a problem with access to this element, because e.target show me elements inside container, not container who is binded element.
Alive any solution to share all functions between main component and child components? Because when i want get this method in anyone place now i must add :moveHero="moveHero" to every component and get this in prop array, so i want create this more globally in one place and share this to all childs. Now i think one solution for this is create .js file and import that to Vue.
You can add $ref to the container element like this: <div ref="container-ref">.
Then to access the container element in vue methods, just do this.$refs["container-ref"].
Explanation:
You can add ref attribute to any tag, even child components. It is parsed by vue only, browser ignores it.
If the ref is attached to a HTML tag, this.$refs[key] will return the corresponding DOM element.
If the ref is attached to a child component, this.$refs[key] will return the corresponding vue instance.
I'm using the webcomponentsjs polyfill. No x-tag, polymer, etc. preferably vanilla JS.
After cloning a template and appending it to the document I'm not able to remove it again since it's missing a parentNode.
var tmpl = document.getElementById('tmpl');
var clone = document.importNode(tmpl.content, true);
document.body.appendChild(clone);
console.log(clone.parentNode); // parentNode is null (not undefined!)
clone.parentNode.removeChild(clone); // fails!
You may see yourself in this jsbin
My Question is: How do I remove the element again. Am I missing something?
You are mixing up DocumentFragment vs. Node. The content of template is apparently an instance of DocumentFragment:
<template>
<div>node 1</div>
<p>node 2</p>
etc
</template>
According to the documentation, Node#appendChild accepts document fragments:
Various other methods can take a document fragment as an argument (e.g., any Node interface methods such as Node.appendChild and Node.insertBefore), in which case the children of the fragment are appended or inserted, not the fragment itself.
So, what do you expect to be a parent of document fragment? It’s obviously null, since the entity “document fragment” is virtual in this context. So, to achieve what you want you are to create a container at first, and then append nodes to it / clean it’s content up.
<body>
...
<div id='container'></div>
...
</body>
There is common approach to add template content involving ShadowDOM:
var shadow = document.querySelector('#container').createShadowRoot();
shadow.appendChild(document.querySelector('#tmpl').content, true);
or not using ShadowDOM, inserting as is:
document.querySelector('#container').appendChild(
document.querySelector('#tmpl').content, true
);
Hope it helps.