I have four pictures when you hover over one of these pictures, certain content appears, for example, if you hover the mouse over the first picture, a green block appears when you hover over the second picture, a blue block appears, and so on, the problem is that the logic that I have implemented looks like nightmarish
Here is a link, you can see the logic on codesandbox, I want to know if it is possible to somehow optimize the logic to make it more readable and simple
<template>
<div>
<div id="girls_gallery">
<div class="girls_gallery_content">
<div>
<div class="g_gallery_title_container">
<h1>Hover Image</h1>
</div>
<div class="girls_list">
<div class="girls_container">
<img
style="width: 200px; height: 200px"
#mouseover="mouseOver1"
#mouseout="mouseout"
src="https://www.gettyimages.com/gi-resources/images/500px/983794168.jpg"
alt="Snow"
/>
</div>
<div class="girls_container">
<img
style="width: 200px; height: 200px"
#mouseover="mouseOver2"
#mouseout="mouseout"
src="https://www.gettyimages.com/gi-resources/images/500px/983794168.jpg"
alt="Snow"
/>
</div>
<div class="girls_container">
<img
style="width: 200px; height: 200px"
#mouseover="mouseOver3"
#mouseout="mouseout"
src="https://www.gettyimages.com/gi-resources/images/500px/983794168.jpg"
alt="Snow"
/>
</div>
<div class="girls_container">
<img
style="width: 200px; height: 200px"
#mouseover="mouseOver4"
#mouseout="mouseout"
src="https://www.gettyimages.com/gi-resources/images/500px/983794168.jpg"
alt="Snow"
/>
</div>
</div>
</div>
</div>
</div>
<div style="margin-top: 50px">
<div
style="width: 200px; height: 200px; background: red"
v-show="img1"
key="img1"
></div>
<div
style="width: 200px; height: 200px; background: green"
v-show="img2"
key="img1"
></div>
<div
style="width: 200px; height: 200px; background: blue"
v-show="img3"
key="img1"
></div>
<div
style="width: 200px; height: 200px; background: orange"
v-show="img4"
key="img1"
></div>
</div>
</div>
</template>
<script>
export default {
name: "HelloWorld",
data() {
return {
img1: false,
img2: false,
img3: false,
img4: false,
};
},
methods: {
mouseOver1: function () {
this.img1 = true;
},
mouseOver2: function () {
this.img2 = true;
},
mouseOver3: function () {
this.img3 = true;
},
mouseOver4: function () {
this.img4 = true;
},
mouseout: function () {
this.img1 = false;
this.img2 = false;
this.img3 = false;
this.img4 = false;
},
},
};
</script>
It seems that it hasn't "clicked" yet with regards on how vue is supposed to work. Check this as an example for reference:
https://codesandbox.io/s/wandering-dream-237l0?file=/src/components/HelloWorld.vue
Basically what you want to do is to render your component content based on component data. Thus you create a data object that holds the information required for your logic.
What I would do is add position: relative to girls_container. Then move your color block into the <div class="girls_container">.
Next, add the following to your color blocks
z-index: 9999;
position: absolute;
top: 0;
left: 0;
Move #mouseover and #mouseout to the girls_container.
<div class="girls_list">
<div
class="girls_container"
style="position: relative"
#mouseover="mouseOver1"
#mouseout="mouseout"
>
<img
ref="img1"
style="width: 200px; height: 200px"
src="https://www.gettyimages.com/gi-resources/images/500px/983794168.jpg"
alt="Snow"
/>
<div
style="
width: 200px;
height: 200px;
background: red;
z-index: 9999;
position: absolute;
top: 0;
left: 0;
"
v-show="img1"
key="img1"
ref="img-block1"
></div>
</div>
Example on Code SandBox
Related
I have a simple React component with two squares which are in the same absolute position. The blue square covers the red square.
function App() {
return (
<div className="App">
<div>
<div
style={{
position: "absolute",
backgroundColor: "red",
width: 100,
height: 100
}}
onMouseDown={() => console.log("Red!")}
/>
<div
style={{
position: "absolute",
backgroundColor: "blue",
width: 100,
height: 100
}}
onMouseDown={() => console.log("Blue!")}
/>
</div>
</div>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
When attaching event listeners to the react components, only the component on top catches the event and it does not reach the red square. Why is that the case? Is this default behavior? I thought event propagation is only stopped using event.stopPropagation()? When using vanilla javascript, both squares catch the event though.
function clickRed() {
console.log("Red!");
}
function clickBlue() {
console.log("Blue!");
}
<div id="root">
<div style="position: absolute; background-color: red; min-width: 100px; min-height: 100px;" onmousedown="clickRed();" />
<div style="position: absolute; background-color: blue; min-width: 100px; min-height: 100px;" onmousedown="clickBlue();"/>
</div>
This isn't a React thing, it's how events work in the DOM. The issue is that events propagate through the DOM tree, from innermost children to outermost ancestors of those children. But your elements are siblings, they don't have a parent/child relationship. So whichever one is above the other in the z-order will be the one that receives the event (which then propagates to that element's parent, not its siblings).
When using vanilla javascript, both squares catch the event though.
Not with the DOM structure you've defined in your question. Here it is with straight HTML and inline event handlers:
<div class="App">
<div>
<div
style="
position: absolute;
background-color: red;
width: 100px;
height: 100px;
"
onmousedown='console.log("Red!")'
></div>
<div
style="
position: absolute;
background-color: blue;
width: 100px;
height: 100px;
"
onmousedown='console.log("Blue!")'
></div>
</div>
</div>
Or with JavaScript using the DOM directly:
const app = document.createElement("div");
app.innerHTML = `
<div>
<div
style="
position: absolute;
background-color: red;
width: 100px;
height: 100px;
"
class="red"
></div>
<div
style="
position: absolute;
background-color: blue;
width: 100px;
height: 100px;
"
class="blue"
></div>
</div>
`;
app.querySelector(".red").addEventListener("mousedown", () => console.log("Red!"));
app.querySelector(".blue").addEventListener("mousedown", () => console.log("Blue!"));
document.getElementById("root").appendChild(app);
<div id="root"></div>
Re your edit adding this example:
function clickRed() {
console.log("Red!");
}
function clickBlue() {
console.log("Blue!");
}
<div id="root">
<div style="position: absolute; background-color: red; min-width: 100px; min-height: 100px;" onmousedown="clickRed();" />
<div style="position: absolute; background-color: blue; min-width: 100px; min-height: 100px;" onmousedown="clickBlue();"/>
</div>
The HTML there is incorrect. In HTML, <div/> is exactly the same thing as <div> — it's just a start tag. As a result, your div elements are nested (blue is inside red). The HTML equivalent to JSX <div/> is <div></div>:
function clickRed() {
console.log("Red!");
}
function clickBlue() {
console.log("Blue!");
}
<div id="root">
<!-- Scroll right in the stack snippet to see the difference at the end ⇒ ⇒ ⇩⇩⇩⇩⇩⇩⇩ -->
<div style="position: absolute; background-color: red; min-width: 100px; min-height: 100px;" onmousedown="clickRed();" ></div>
<div style="position: absolute; background-color: blue; min-width: 100px; min-height: 100px;" onmousedown="clickBlue();"></div>
</div>
i am trying to make a customized product, and the issue i am getting here is when i customize my product and try to save it or preview it my div position is not the same i set before! printArea is the div which i want as an image.
<style>
#printArea
{
z-index: 1;
height: 330px;
width: 330px;
border: 1px dashed black;
align-items: center;
position: relative;
left: 126;
top: 165;
margin: 20px;
padding: 10px;
overflow: hidden;
}
</style>
<div class="row">
<div class="col-md-2">
<input type="file" name="file">
</div>
<div class="col-md-8"></div>
<div class="col-md-2">
Preview
<a class="button btn btn-download" id="btn-Convert-Html2Image" href="#">Download</a>
</div>
</div>
<div class="row">
<div class="col-md-2">
</div>
<div class="col-md-8">
<div class="box">
<div id="printArea" class="print-area">
<div id="draggable4" class="ui-widget-content" style="width: 204px; height: 204px; overflow: hidden; z-index: 100; left: 69px; top: 69px;">
<div class="upload-image-preview">
</div>
</div>
</div>
<img src="<?php echo base_url(); ?>assets/user/img/customTshirt.jpg" class="" id="mirror" style="position: relative; width: 600px; height: 600px; left: 13px; top: -350px; "/>
</div>
</div>
<div class="col-md-2"></div>
</div>
</div>
<div id="previewImage">
</div>
<script type="text/javascript">
var element = $(".box"); // global variable
var getCanvas; // global variable
$("#btn-Preview-Image").on('click', function () {
html2canvas(element, {
onrendered: function (canvas) {
$("#previewImage").append(canvas);
getCanvas = canvas;
}
});
});
$("#btn-Convert-Html2Image").on('click', function () {
var imgageData = getCanvas.toDataURL("image/png");
// Now browser starts downloading it instead of just showing it
var newData = imgageData.replace(/^data:image\/png/, "data:application/octet-stream");
$("#btn-Convert-Html2Image").attr("download", "your_pic_name.png").attr("href", newData);
});
</script>
</body>
</html>
What i want
http://i.imgur.com/Y8vMf35.png
What i get
http://i.imgur.com/wZt9eDF.png
Flex can be used to center elements:
var element = $(".box"); // global variable
var getCanvas; // global variable
$("#btn-Preview-Image").on('click', function () {
html2canvas(element, {
onrendered: function (canvas) {
$("#previewImage").append(canvas);
getCanvas = canvas;
}
});
});
$("#btn-Convert-Html2Image").on('click', function () {
var imgageData = getCanvas.toDataURL("image/png");
// Now browser starts downloading it instead of just showing it
var newData = imgageData.replace(/^data:image\/png/, "data:application/octet-stream");
$("#btn-Convert-Html2Image").attr("download", "your_pic_name.png").attr("href", newData);
});
#printArea {
z-index: 1;
height: 330px;
width: 330px;
border: 1px dashed red;
padding: 10px;
overflow: hidden;
position: absolute;
}
.box{
display: inline-block;
}
.wrapper {
display: flex;
align-items: center;
justify-content: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
<div class="col-md-2">
<input type="file" name="file">
</div>
<div class="col-md-8"></div>
<div class="col-md-2">
Preview
<a class="button btn btn-download" id="btn-Convert-Html2Image" href="#">Download</a>
</div>
</div>
<div class="row">
<div class="col-md-2">
</div>
<div class="col-md-8">
<div class="box">
<div class="wrapper">
<div id="printArea" class="print-area">
<div id="draggable4" class="ui-widget-content"
style="width: 204px; height: 204px; overflow: hidden; z-index: 100; left: 69px; top: 69px;">
<div class="upload-image-preview">
</div>
</div>
</div>
<img src="https://via.placeholder.com/600" class="" id="mirror"
style="position: relative; width: 600px; height: 600px; left: 13px;"/>
</div>
</div>
</div>
<div class="col-md-2"></div>
</div>
</div>
<div id="previewImage">
</div>
var element = $(".box"); // global variable
var getCanvas; // global variable
$("#btn-Preview-Image").on('click', function () {
html2canvas(element, {
onrendered: function (canvas) {
$("#previewImage").append(canvas);
getCanvas = canvas;
}
});
});
$("#btn-Convert-Html2Image").on('click', function () {
var imgageData = getCanvas.toDataURL("image/png");
// Now browser starts downloading it instead of just showing it
var newData = imgageData.replace(/^data:image\/png/, "data:application/octet-stream");
$("#btn-Convert-Html2Image").attr("download", "your_pic_name.png").attr("href", newData);
});
.box {
height: 730px;
width: 100%;
border: 1px dashed black;
align-items: center;
float: none;
margin-top: 20px;
padding: 10px;
position: relative;
}
#mirror{
position: absolute;
width: 600px;
height: 600px;
left: 0;
top: 0;
right: 0;
margin: auto;
}
#printArea {
z-index: 1;
height: 330px;
width: 330px;
align-items: center;
position: absolute;
left: 0;
top: 26%;
margin: auto;
padding: 10px;
overflow: hidden;
right: 7px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
<div class="col-md-2">
<input type="file" name="file">
</div>
<div class="col-md-8"></div>
<div class="col-md-2">
Preview
<a class="button btn btn-download" id="btn-Convert-Html2Image" href="#">Download</a>
</div>
</div>
<div class="row">
<div class="col-md-2">
</div>
<div class="col-md-8">
<div class="box">
<div id="printArea" class="print-area">
<div id="draggable4" class="ui-widget-content"
style="width: 204px; height: 204px; overflow: hidden; z-index: 100; left: 69px; top: 69px;">
<div class="upload-image-preview">
</div>
</div>
<img src="https://via.placeholder.com/600" class="" id="mirror"
style="position: relative; width: 600px; height: 600px; left: 13px;"/>
</div>
</div>
</div>
<div class="col-md-2"></div>
</div>
</div>
<div id="previewImage">
</div>
I have two divs in my application that seperates the screen with the content and sidemenu.
<div class="splitter-left ">
<div class="close-left-btn">
<button class="btn btn-primary" id="toggle-menu">Click me</button>
</div>
<div class="container-fluid content-close">
<div class="row">
<div class="col-4">
<p>Home</p>
</div>
<div class="col-4">
<p>About</p>
</div>
<div class="col-4">
<p>Contact</p>
</div>
</div>
</div>
</div>
<div class="splitter-right">
<div class="container-fluid">
<div class="row">
<div class="col-12">
<strong>Header options</strong>
</div>
</div>
</div>
</div>
And this is my styling for splitter-left and splitter-right
.splitter-left {
display: inline-block;
width: 25%;
max-width: 300px;
min-width: 250px;
background-color: #fff;
margin-top: 10px;
margin-left: -35px;
vertical-align: top;
}
.splitter-right {
display: inline-block;
width: 85%;
margin-top: 10px;
position: relative;
left: 50px;
min-height: 400px;
}
I also made a JQuery function to activate the button to hide and show the splitter-left
This is my function in JQuery
$("#toggle-menu").click(function () {
if ($(".content-close").toggle()) {
$(".splitter-left").toggleClass('sidemenu-close')
$(".splitter-right").css({ width: '100%' });
else {
$(".splitter-right").css({ width: '75%' });
}
});
And this is the styling for the method toggleClass for sidemenu-close
.sidemenu-close {
width: 0% !important;
min-width: 0% !important;
}
When I click on the button Click me the splitter-right class gets a width of 100% (this is working). When I click on the button again the splitter-right doesn't go back to the default size of 75%.
How can I get the default size back when I click on the button?
I have fixed it with the following solution:
$("#toggle-menu").click(function() {
$(".content-close").toggle();
if ($(".splitter-left").hasClass('sidemenu-close')) {
$(".splitter-left").removeClass('sidemenu-close')
$(".splitter-left").css({
width: '25%'
});
$(".splitter-right").css({
width: '85%'
});
} else {
$(".splitter-left").addClass('sidemenu-close');
$(".splitter-right").css({
width: '100%'
});
}
});
I'm trying to get height of a parent div using React JS.
The html structure is as follows :
<div ref="sectionSlider">
<div class="detailsOutterDiv">
<div class="swiper" style="width: 100%;">
<div class="detailsInnerDiv">
<div class="slide">
<img src="someURl" style="background-color: black;">
</div>
<div class="slide">
<img src="someURl" style="background-color: black;">
</div>
<div class="slide">
<img src="someURl" style="background-color: black;">
</div>
</div>
</div>
</div>
<div class="slider-thumbnails">
<div class="thumb">
<img src="someURl">
</div>
</div>
</div>
And the css-scss structure is like this :
.detailsOutterDiv{
position: relative;
width: 100%;
overflow: hidden;
}
.detailsInnerDiv{
position: relative;
top: 0px;
left: 0px;
right: 0px;
width: 10000%;
transition: all 0.5s ease;
}
.slide{
display: inline-block;
margin-right: 15px;
}
.slide img{
width: 100%;
height: auto;
}
.slider-thumbnails{
width: 100%;
padding-top: $primary-margin-xs - 5;
text-align: center;
.thumb{
display: inline-block;
width: (100% / 12);
img{
width: 100%;
height: auto;
padding: 0 2px;
}
}
}
I'm trying to get the height of the div with ref="sectionSlider".
I tried to do this on a few ways in componentDidMount like this :
componentDidMount(){
//First way
let top = this.refs["sectionSlider"].offsetHeight;
//Second way
let top = this.refs["sectionSlider"].clientHeight;
//Third way
let top = this.refs["sectionSlider"].getBoundingClientRect().height;
//Fourth way
let node = this.refs["sectionSlider"];
let nodeStyle = window.getComputedStyle(node);
let top = parseInt(nodeStyle.getPropertyValue('height').replace(/\D/g,''));
}
And in every case top is 82 what is not true.
It looks like :
Thus, the div has height of 523.
Any idea how to solve it?
If the problem is (according to your guess) that the images aren't loaded you could do something like this:
const Example = React.createClass({
getInitialState () {
return {
imagesLoaded: 0,
};
},
printClientHeight() {
console.log(this.wrapper.clientHeight)
},
updateLoadedImages() {
this.setState({ imagesLoaded: this.state.imagesLoaded + 1 })
if (this.state.imagesLoaded = 4) {
printClientHeight();
}
},
setWrapperRef(el) {
this.wrapper = el;
},
render() {
return (
<div ref={this.setWrapperRef}>
<div className="detailsOutterDiv">
<div className="swiper" style="width: 100%;">
<div className="detailsInnerDiv">
<div className="slide">
<img src="someURl" style="background-color: black;" onLoad={updateLoadedImages}/ >
</div>
<div className="slide">
<img src="someURl" style="background-color: black;" onLoad={updateLoadedImages}/>
</div>
<div className="slide">
<img src="someURl" style="background-color: black;" onLoad={updateLoadedImages}/>
</div>
</div>
</div>
</div>
<div className="slider-thumbnails">
<div className="thumb">
<img src="someURl" onLoad={updateLoadedImages}/>
</div>
</div>
</div>
);
}
});
Obviously you could clean this up quite a bit by getting the image tag count dynamically but I think you get the point...
I've been playing around with my code, I have the Calendar set up to do what i want, now I am just trying to get the <p> and iframe lined up beside each other nicely, i have this code so far jsfiddle and here is an example of what the separation f the arrows and iframe looks like now
what i want to achieve:
200px----[ arrowLEFT ]---30px---[ Iframe ]---30px---[ arrowRIGHT
]
HTML:
<div id="miniFeed">
<p id="toggle">
<span> <a href="#" onMouseOut="MM_swapImgRestore()"
onMouseOver="MM_swapImage('LeftArrow','','WEBgraphics/arrowLeftROLL.png',1)">
<img src="WEBgraphics/arrowLeft.png" width="40" height="400" id="LeftArrow"></a></span>
<span> </span>
</p>
<div id="calender">
<div id="left"> <iframe src="calenderAPRIL.html" width="350px" height="400px"></iframe>
</div>
<div id="right"> <iframe src="calenderMAY.html" width="350px" height="400px"></iframe>
</div>
</div>
<p id="toggle">
<span> </span>
<span> <a href="#" onMouseOut="MM_swapImgRestore()"
onMouseOver="MM_swapImage('RightArrow','','WEBgraphics/arrowrightROLL.png',1)">
<img src="WEBgraphics/arrowright.png" width="40" height="400" id="RightArrow"></a></span>
</p>
</div>
JAVASCRIPT:
window.onload=function() {
$('#toggle > span').click(function() {
var ix = $(this).index();
$('#left').toggle( ix === 0 );
$('#right').toggle( ix === 1 );
});
};
CSS:
#miniFeed {
}
#right { display:none; }
#LeftArrow {
z-index: 100;
width: auto;
float: left;
margin-left: 200px;
display: block;
}
#calender {
float: left;
z-index: -1;
}
Try this
html:
<div id="miniFeed">
<div class="arrow leftArrow">
</div>
<div class="calendars">
<div class="carousel">
<div class="calendar-1">
</div>
<div class="calendar-2">
</div>
</div>
</div>
<div class="arrow rightArrow">
</div>
css:
#miniFeed {
width: 400px;
height: 250px;
}
#miniFeed > div {
float: left;
height: 100%;
}
.arrow {
width: 100px;
background: blue;
}
.calendars {
width: 200px;
overflow: hidden; /*the magic*/
}
.carousel {
width: 400px; /* the size is number of calendars * the width per calendar */
height: 100%;
}
.carousel > div {
width: 200px;
height: 100%;
float: left;
}
.calendar-1 {
background: red;
}
.calendar-2 {
background: green;
}
js:
$('.leftArrow').click(function() {
//we move the carousel negative
//the value 200 is the width of a calendar
$('.carousel').animate({marginLeft: -200}, 300);
});
$('.rightArrow').click(function() {
//we move the carousel negative
$('.carousel').animate({marginLeft: 0}, 300);
});
We create a wrapper with overflow hidden, so inside it we have our collections of calendars.
Result:
http://jsfiddle.net/renanvalentin/kzTRz/