Get Outermost Div - html

In case of a nested div, without any ids whatsoever, is there any way to get the outermost <div>?
<div>
Outermost div
<span>
<img />
<div>
Second level div
<div>
Third level div
</div>
</div>
</span>
</div>
I wouldn't be able to add ids or classes or any of those.
Long story:
I will be creating a Vue component that will be used multiple times on a single page (imagine a quadrant with all 4 sections are actually the same component):
This component will need to append text to a div. And this div must be created dynamically. Ideally, I shouldn't add an id to the outermost div since there will be conflict if I do something like this:
<div id="logs">
</div>
const logsDiv = document.getElementById('logs')
function appendLog (log) {
logsDiv.innerHTML += log
}
Since there will be multiple instances of the same component, it will all write to the div with the id "logs". Another option is if I accept a prop and I can append that to the id (like 'logs' + id = 'logs1'). But this feels a bit hacky. I prefer just getting the outermost div if that is possible.
So my thought is just get the outermost div and create a child div there. Something like:
<div>
<!-- some other elements -->
</div>
const outermostDiv = codeToGetOuterMostDiv()
const logsDiv = document.createElement('div')
outermostDiv.appendChild(logsDiv)
function appendLog (log) {
logsDiv.innerHTML += log
}
.

Related

Jquery change css class from variable

For my site, I code a button allowing to change the css of a class present in a div card. My button is located in the card-footer. Having several cards, I can't / don't think to retrieve the element with an id (as there will be X times the same ID)
In order to circumvent this system, I therefore use a parentElement which goes up to the div card
<div class="card">
<div class="card-body">
<p class="change">Change one</p>
<p class="change">Change two</p>
<p class="change">Change three</p>
</div>
<div class="card-footer">
<i id="updateData">change</i>
</div>
</div>
jQuery($ => {
$('#updateData').click(e => {
var element = e.target.parentElement.parentElement;
$('.change').css('display','none');
});
});
I would like to indicate that only the class "changes" present in my element variable and not all the classes in the page.
I don't know how to add a variable to my ".css" command, do you know how ?
Thanks in advance !
First of all since you will have multiple elements with same id that means that you should not use ID and use class instead. Id is meant to be unique. So yours id="updateData" should become class="updateData". Now you can grab all of those buttons and assign event to all of them instead of just first like you were by using id selector.
$('.updateData').click(e=> {});
Next in order to be able to use clicked element in jQuery way convert from arrow function to regular anonymous function since arrow function overrides this keyword. And now you can use jQuery to hide like
$('.updateData').click(function() {
element = $(this).parent().parent();
element.hide();
});
If you want more precise selection to hide only .change elements use
$('.updateData').click(function() {
element = $(this).parent().parent();
element.find(".change").hide();
});
Not bad, but more efficient, when you have multiple click targets, is delegation:
$(document).on("click", ".updateData", function() { ... });
Also .hide() is convenient, but rather then "change the css of a class" add a class "hidden" or something! In best case the class further describes what the element is. CSS is just on top.

How to get a copy of text inside a div which is not wrapped inside any HTML tag?

I am trying to grab the text inside a div container and perform some logic based upon the text content instead of changing it. I tried to use Node.childNodes but it returns a live Nodelist instead of a copy.
Here is the DOM structure, I am trying to grab text without a container from it only.
<div class="container" >
<span >text inside span</span>
text without a container
<button>text inside button new</button>
<button>text inside button</button>
</div>
Any ideas?
EDIT:
Desired Output:
'text without a container' as a string
You can use this:
const parent = document.getElementById('parent');
const nodes = parent.childNodes;
let text = "";
for (let node of nodes) {
if (node.nodeName === '#text') {
text += node.textContent.trim();
}
}
console.log('Final result: ', text);
<div id="parent">
<span>Inside span</span>
I'm free! as a bird!
<span>I wish I was</span>
</div>
This will loop through all of the child nodes and will only extract text that is not within another element.

How to trigger click event on a div element and show its neighbour element JQUERY

I have a lot of divs, they are the same but the data are differen(I use variable(array of objs) and for loop) but these details aren't important
<div class="item_wrapper">
<div class="item_wrapper_info">
<div class="left-line"></div>
<div class="subject">1</div> <== click here
</div>
<div class="additional_info"> <== display this block
some text
</div>
</div>
I want to achieve this:
If I click .item_wrapper_info div then I want to show .additional_info div
It should be probably done using this keyword.
If I click . item_wrapper_info block I want to find a div with the class name of . additional_info and make display = flex but I don't know how to trigger exactly its . additional_info div.
Probably I can click on .item_wrapper_info > . subject and then show its next neighbour
SOLUTION:
$(document).ready(() => {
$(".item_wrapper").click(function(){
var index = $(".item_wrapper").index(this); get index of a certain clicked .item_wrapper element on my page
$('.additional_info').eq(index).toggle(); using .eq toggle that certain element
});
})
It works for me
I haven't tested this code. Feel free to test it in a runnable snippet.
$(document).ready(() => {
$(".item_wrapper").click(function () {
var index = $(".item_wrapper").index(this)
$('.additional_info').eq(index).css("display","flex");
});
});

Identify if there is more space below or above an element in the DOM

Basically I have an input field and want to display a div containing a list below OR above it depending where there is more space. since in some cases this input field could be at the bottom of the page or maybe at the middle or top. So i thought of using the view port to identify if there is more space below or above the input field and then display the div accordingly. Trying to this purely with some CSS and html. any recommendations will be helpful.
My basic html structure :
<input/>
<div id="container">
<ul>
<li ngFor>
<span> field1 </span>
<span> field2 </span>
<span> field3 </span>
</li>
</ul>
</div>
It's hard to give a complete answer without knowing how your components are set up, but there are a couple of HTML features that might help you, depending on whether you want to choose based on space above/below within the viewport, or above/below within the parent component.
If you want to do it based on space within the viewport, you can use Element.getBoundingClientRect() to find distance between the input and the top/bottom of the viewport:
const element = document.querySelector('input');
const elementRect = element.getBoundingClientRect();
const spaceAbove = elementRect.top;
const spaceBelow = window.innerHeight - elementRect.bottom;
if (spaceBelow < spaceAbove) {
// logic to render with more space above input
} else {
// logic to render with more (or equal) space on bottom
}
<input />
If you want to do it based on space within the parent component, you can use Element.offsetTop and Element.offsetHeight to calculate space between the input and the top/bottom of its closest positioned ancestor:
const element = document.querySelector('input');
const spaceAbove = element.offsetTop
const spaceBelow = element.parentNode.offsetHeight - (element.offsetTop + element.offsetHeight)
if (spaceAbove > spaceBelow) {
// do something
} else {
// do something else
}
<div style="padding: 200px 0 100px 0; position:relative">
<input />
</div>

How to replace one child react/html component with another based up on event using react?

I am new to react and I have a react component structure like:
<MainComponent>
<Button />
<Content />
</MainComponent>
Now when I click on the Button, I need to replace the existing div (say div1) of the Content component with another div (div2). Can you please tell me how to do it. Thank you.
Note: Till now, on click event I have been changing the data of the single div using state and prop. Now I got to replace the whole div with another one.
Like this.
render() {
var returnIt;
if (useDivOne) returnIt = (<div id='one'></div>);
else returnIt = (<div id='two'></div>);
return (returnItj);
}
If this is your structure:
<MainComponent>
<Button />
<Content />
</MainComponent>
and Content renders something like:
<div>
this is div 1
</div>
I would think you would need to pass a prop to Content that would tell you which div to render, then in Content's Render you manipulate the properties of Boolean logic to present a different component:
class Content extends Component {
render() {
return(
{
!this.props.RenderDiv2Bool &&
<div>
This is Div1 and it will be rendered
because RednerDiv2Bool is false.
</div>
}
{
this.props.renderDiv2Bool &&
<div>
This is Div2 and it will be rendered
because RednerDiv2Bool is true.
</div>
}
)
};
}
Not necessarily better but just another way to do it.