Any idea how does one remove an element from the dom in nextjs on componentwillunmount?
I'm using the Head component to load a JS script that generates an element on a page.
When I navigate to another page, that element still stays so I need to remove it.
I thought of using componentwillunmount and document.getelementbyclassname, but it doesn't work in nextjs for some reason.
Any thoughts on how to solve it?
This doesn't do anything, even though the button is being picked up:
componentDidMount() {
oldButton2 = document.getElementsByClassName("button");
}
componentWillUnmount() {
if (oldButton2.parentNode) {
oldButton2.parentNode.removeChild(oldButton2);
}
}
Related
So a little disclaimer: I am completely and utterly self taught. Bear over with me if I'm being a clown.
Anyways, I am currently working on a some platform and in need for a dropdown functionality. That's simple right? Just use HTML5 select tag. However option tags can't be styled :>
So onwards to build my own. The HTML5 select tag uses keyboard input (up/down/enter) for those with disabilities, and I thought I would implement that too. That did present a problem though: The :hover selector collided with my custom attribute, which I use to style keyboard selected items (&[data-selected=true] to be precise).
So onwards to implement my own :hover. And this is where my bewilderment starts.
const handleChildMouseOver = () => {
const items = Array.from(listItem.current?.children!); // The wonders of typescript XD
for (const item of items) {
if (item === event.target) {
item.setAttribute("data-selected", "true");
} else {
item.removeAttribute("data-selected"); // I'm removing the attribute, rather than toggling it, because I got components with 3 states: On, off, and default.
}
}
}
(...)
<ul css={css.list} /*emotion prop*/ data-toggled={toggled} /*parent state*/ onMouseOver={handleChildMouseOver}>
{children} // parent prop
</ul>
So it works as intended, which is fine. But I recall from my pre-react days that you should never manipulate the DOM in loops, as it causes repaints on every iteration. However when I look at the Dev Tools performance profiler, I barely see any "Paints", 8 or so, even when I'm switching hover targets like a madman. What I do see is one million "Composite layer". Oh, and as a bonus React doesn't re-render. Which is fine right? 'Cause I'm not really changing the state of anything, just adding some CSS.
So my question boils down to: Am I being bonkers or smart?
N.B.: I would love to share the actual component, but seeing as this is my first post on stackoverflow, I've got no clue how you do those fancy script tag. Well github is involved somehow, I know that much 🤔
In short, I am trying to trigger a change detection loop between renderer.removeStyle and renderer.addStyle.
The style I am adding is an css animation. When it's removed and added in the same change detection loop Angular won't detect that something changed (for the same animation name).
More Details
Let's say I have a button event (click)="addAnimation('animation1')" that should add existing animation and add the new animation named animation1, animation2 ....
Of course the following code won't work:
addAnimation(animationName: string): void {
this.renderer.removeStyle(this.animate.nativeElement, 'animation');
// setTimeout(() => {
this.renderer.setStyle(this.animate.nativeElement, 'animation', animationName)
// }, 0);
}
since removing and adding a style under angular nose won't trigger any change.
One possible solution is adding a timeout (like the commented code above, but it has side effects that I am not interested in, and also the code is a little wired.
I was hoping to solve it by adding something like this.appRef.tick(); in between to force angular create another change detection loop.
That doesn't work, what am I missing? any suggestions how to do that correctly?
Thanks!
Try following way.
isClick=false;
onClick(){
isClick=true;
}
<div [ngClass]="{'yourCSSClass': isClick}">
Is there a way to apply a style to all elements in Cypress? Like one would do with the star selector:
* {
overflow-x: hidden;
}
I need this for visual regression snapshots, because of scrollbars that appear, and haven't been able to find something simple and elegant in Cypress. Currently doing something like this:
cy.get('[data-cy="some-tag"]').invoke('css', 'overflow-x', 'hidden');
But of course this isn't great, because every element that has scrollbars has to be targetted and set.
You can change the DOM just before any screenshot is taken by using onBeforeScreenshot and onAfterScreenshot callbacks. This will hide the scrollbar on the element the screenshot command was called on, and restore it afterwards:
Cypress.Screenshot.defaults({
onBeforeScreenshot($el) {
$el.css('overflow', 'hidden');
},
onAfterScreenshot($el, props) {
$el.css('overflow', 'auto');
},
});
You can put this function in support/index.js file since it is loaded before any test files.
Note: if you just call cy.screenshot() then the $el will be the document and you can use .find(<selector>) command to get any child elements within the page.
Works great with cypress-visual-regression plugin.
Reference: https://docs.cypress.io/api/cypress-api/screenshot-api#Change-the-DOM-using-onBeforeScreenshot-and-onAfterScreenshot
I am trying to use paper-dialog within my custom component.
I want to be able to open the dialog from outside the component. What is the best way to do this? (all the examples work directly on the component)
Also the dialog requires me to call "open()" on it to open it.
In the examples I found I found:
this.$.dialog.open();
But this doesn't seem to work with lit-element
I got it to work using shadowRoot, not sure this is the best option:
render() {
return html`
<style>
</style>
<paper-dialog id="dialog">
<h2>Content</h2>
</paper-dialog>
`;
}
firstUpdated(changedProperties) {
console.log("firstUpdated called")
if (this.shown == "true")
{
// this.$.dialog.open();
this.shadowRoot.getElementById("dialog").open()
}
}
I added a property to my element called "shown"
static get properties() {
return {
shown: Boolean,
Thinking I could pass this from the outside into my component, but it doesnt seem to do the trick either (I can set it once with the custom element propery, but changes to it from the out side dont seem to work.
Generally, if you are aggregating a dialog within an element that has other UI elements then you shouldn't be showing/hiding the dialog from outside the element - the event that triggers the dialog should be raised and handled with the containing element.
That said, if it's absolutely necessary, then I prefer a "showDialog" method (not a property). Closing the dialog should be triggered by a dialog button or loss of focus, so you don't need to expose a close method.
I've built a table with react-table and want to use the react-select component as as filtering component. All is up and running except that the dropdown from the react-select component gets hidden by the table.
I've been working quite a long time on this issue. With styling the react-select to look nice within the filter row.
The issue is that I cannot find any other way to override the CSS rules for
.ReactTable .rt-th,.ReactTable .rt-td
which appears to control the row with all filter. This css has the rule of overflow:hidden; and changing it to overflow:visible; resolves my issue.
Hardcoding the changes in this file is of course not the "right way to do it" since I might get trouble elsewhere.
Things I've tried:
Passing styles={{overflow:visible}} to my filterComponent. This results in a strange style='Object object' and my style is not read.
Passing getProps:()=>{style:{overflow:'visible'}}. Have tried some other methods then getProps but with no luck.
Any other ideas or suggestions?
Solution
The prop getTheadFilterThProps was missing in the documentation. The property was found by searching within the react-table folder and check if there where any props that were missing in the documentation.
<ReactTable
getTheadFilterThProps={(state, rowInfo, column) => {
return {
style: {
overflow: 'visible',
}
};
}}
Ok, the answare was quite simple when finding the right props. I ended up searchin for getTheadFilterTrProps in the installation folder of react-table. Then I found that there were some more Props available.
I endend up adding
<React
getTheadFilterThProps={(state, rowInfo, column) => {
return {
style: {
overflow: 'visible',
}
};
}}