Reputation: 1585
I am using React to get hold of a element using ref callback when rendered on the browser and then transform this in case the child exceeds the parent, the content is not parsed by React but comes a API call so the parsing has to be manually.
Note - currently i am getting element this via react ref callback and trying to modifying via plain Js will it effect in case re rendering happens to the react component (if yes how can we do it in React) or if we modify DOM using plain JS is it fine ?
(function (e) {
// how to add icon at the end of the image if the size of the image is greater then container
}})(window,document)
const parent = element.getBoundingClientRect();
const imgTags = element.querySelectorAll("img");
imgTags.forEach(imgTag => {
const imgBoundingRect = imgTag.getBoundingClientRect();
if (imgBoundingRect.width > parent.width) {
const parent = imgTag.parentNode;
const wrapper = document.createElement('div');
wrapper.classList.add(styles.horizontalScroll);
parent.replaceChild(wrapper, imgTag);
wrapper.appendChild(imgTag);
}
});
.horizontalScroll {
overflow-x: auto;
}
But i am not sure how to add icon instead of scroll bar
to the node and then clicking on the icon moves it instead of scroll
<html>
<body>
<script>
</script>
<div style="width: 10px;border: 1px solid red" >
<p>Mine MIne;GGGG;8 If <img height="84px" src="https://encrypted-tbn0.gstatic.com/images?q=tbn%3AANd9GcQGnVCSgGcosHQqtLDK2s8ZdOaZxNcntg8vk2kHgygqP--Rbtdd&usqp=CAU" style="vertical-align:middle" width="510px"> then the value of </p>
</div
</body>
</html>
Looking for output like this
using just Plain JS when image is loaded i am not able to create Nodes on the Fly for images > parent width . I have been able to capture width and add overflow but how to add button to a node with styling.
Update : React code for getting the Ref
<div dangerouslySetInnerHTML={createMarkup(myContent)} // this is a set of <p> tags which may or may not contain images inside which comes in via server. those images can sometime move out of view . due to no style prop attached
className={classNames(styles.data, externalStyle)}
ref={(input) => {
if (input) {
myJSFunction(input); // this is the Input
}
}}/>
Upvotes: 3
Views: 504
Reputation: 19640
We can try something like this add dynamic element in React context ..
export const overFlowIcon = (element) => {
const oldId = element.querySelectorAll(‘#myID’); // add someId inside to icon and check may Be in case content re renders in React
setTimeout(() => {
const pDiv = element.getBoundingClientRect();
const imgTags = element.querySelectorAll("img");
imgTags.forEach(imgTag => {
const imdDiv = imgTag.getBoundingClientRect();
if (imdDiv.width > pDiv.width) {
const parent = imgTag.parentNode;
parent.style.width = '100%';
const cont = document.createElement('div');
const wrap = document.createElement('div');
cont.classList.add(‘stickycontainer');
wrap.classList.add(‘horizontalScroll');
container.appendChild(wrap);
parent.replaceChild(container, imgTag);
wrap.appendChild(imgTag);
const newE = document.createElement('span'); // creating icon
newE.onclick = (event) => (element.scrollBy(100, 0); event.stopPropagation();)
newE.classList.add(‘arrow'); // styling a problem can fix
wrap.appendChild(newE);
}
});
}, 0);
};
.stickycontainer
position: relative;
}
.horizontalScroll {
overflow-x: auto;
display: flex;
}
.arrow {
position: absolute;
left: 80%;
top: 50%;
border: solid #000;
border-width: 0 3px 3px 0;
display: inline-block;
padding: 3px;
cursor: pointer;
transform: rotate(-45deg);
-webkit-transform: rotate(-45deg);
}
In this case we are making sure the element is in view and then do the transformation using JS, also to prevent the effect of Re render we can add id to any element and then if React Rerenders we can check the id if exists we prevent the whole method run altogether there by preventing the effect of re render / or can add a additional arg to the method.
Update Post adding of the React Ref, as the content comes in form of string you can may be use DOM parser to convert it to your format and back to string and then have the logic in React Context itself some thing like
export const horizontalOverflow = (content) => {
const parser = new DOMParser();
const doc = parser.parseFromString(content, 'text/html');
const element= doc.body;
if (element) {
const imgTags = element.querySelectorAll("img");
imgTags.forEach(imgTag => {
const parent = imgTag.parentNode;
const wrapper = document.createElement('span');
wrapper.classList.add(horizontalscrolling);
parent.replaceChild(wrapper, imgTag);
wrapper.appendChild(imgTag);
});
}
return element.outerHTML;
};
Now you can use it to create Markup.
Upvotes: 2