I have a html block that is consist of many <div>s.
I use these <div>s to create modal windows by altering their opacity upon target (done in CSS).
These <div>s are distinguished by id and all have the same class name.
The <div>s have a border of 10px. Upon mouse hover, the border is changed to 38px for right and left border only (done in css).
Upon mouse hover I want to show back and next arrow to appear exactly middle of the left and right hand border. Different 'div's have different heights.
My approach:
I have use the event.target.id to get the id of the <div> that calls the function.
Then I used the getBoundingClientRect() to get a rectangle representation of that element on the screen.
I used the .top .bottom .left .right to get the x and y coordinates of each four points. From these points I find the height and then set the <div>s .left and .right to be equal to it.
I have used alert() to return the result and it sometime returns the correct value and sometimes no values at all. The return result is either of these two. And the arrows don't get placed where they are suppose to. I am quite new to Javascript and I am still learning so I'd appreciate if you also explain your answers.
The HTML codes is below:
<html>
<head>
<script src="jquery-1.11.1.js"></script>
<script type="text/javascript" src="midpointHeight.js"></script>
<script type="text/javascript" src="modalDialogHover.js"></script>
</head>
<!--first modal-->
<a href="#X">
<image src="X.gif" id="X" class="Gif" />
</a>
<div id="h" class="modalDialog">
<div id="miniModal_h" class="miniModal" onmouseover="getMidPointHeight(event)">
<div class="close_btn"></div>
<div class="next_btn"></div>
<p>
<!--some text here-->
</p>
</div>
</div>
<!--second modal-->
<a href="#p">
<image src="p.gif" id="p" class="Gif" />
</a>
<div id="p" class="modalDialog">
<div id="miniModal_p" class="miniModal" onmouseover="getMidPointHeight(event)">
<div class="close_btn"></div>
<div class="back_btn"></div>
<div class="next_btn"></div>
<p>
<!--some text here-->
</p>
</div>
</div>
</html>
in CSS:
.modalDialog {
position: fixed;
font-family: Arial, Helvetica, sans-serif;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 99999;
opacity: 0;
}
.modalDialog > div {
width: 704px;
position: relative;
margin: 10% auto;
background: white;
border-image: url("grey_flat_tile.png");
border-image-repeat: repeat;
border-image-slice: 30%;
border-width: 10px;
}
.modalDialog:target{
opacity:1;
}
.next_btn {
display: none;
background-image: url("arrow_right.png");
position: absolute;
right: -30px;
width: 20px;
height: 22px;
}
.back_btn{
display: none;
background-image: url("arrow_left.png");
position: absolute;
left: -30px;
width: 20px;
height: 22px;
}
.visible {
display: block;
}
In jQuery to hid/show the left and right buttons on the panels:
jQuery(document).ready(function(){
jQuery(".miniModal").hover(
function(){
jQuery(".close_btn").addClass("visible"),
jQuery(".next_btn").addClass("visible"),
jQuery(".back_btn").addClass("visible")
},
function(){
jQuery(".close_btn").removeClass("visible"),
jQuery(".next_btn").removeClass("visible"),
jQuery(".back_btn").removeClass("visible")
}
)
});
In javascript to find the midpoint height and show the arrow at the right position:
function getMidPointHeight(event){
var miniModal= event.target.id;
//alert(miniModal);
var smallRect = document.getElementById(event.target.id).getBoundingClientRect();
var sX = smallRect.left;
var sY = smallRect.top;
var sW = smallRect.right;
var sH = smallRect.bottom;
//alert(sX + "," + sY + "," + sW + "," + sH);
var sHeight = (sH - sY);
var smidHeight = (sHeight / 2);
var arrow_loc = (smidHeight)+"px";
alert(arrow_loc);
var next_btn = document.getElementById("next_btn");
next_btn.style.top = arrow_loc;
var back_btn = document.getElementById("back_btn");
back_btn.style.top = arrow_loc;
}
Related
I have been trying to build a video player, when I came across this problem. The controls of my video player are inside a element and I translated them to be right at the bottom part of my video. I then made a progress bar which when the user clicks, it fills upto the click and then the user can move his mouse (while holding down the click), and the bar sort of follows the user's cursor. I connect this in the background to the video and as the user drags the red bar, the video seeks to the point in time. Just like you would expect in a progress bar of a video player. The user can hold down his click and move his mouse anywhere on the screen and still the red bar will only propagate along the the x-axis only.
Until, while holding down the mouse click, you bring your mouse over the controls and then the bar sort of gives wrong values.
I have coded a replica of the problem below. Notice that, if you run the snippet below, you can click on the green box and drag, and a red bar follows the cursor, even after you bring the cursor out of the green box. But bring your cursor over the controls (represented by the blue and maroon box) and watch what happens to the red bar. it move backwards. This is a problem because the bar is associated with the user seeking the video. and if the bar messes up while the user is seeking, it can be really frustrating.
Give it a try!
This is somewhat a direct copy of my program, and I have no idea how to solve it. The video player is meant to be a plugin, so it should work perfectly no matter what the size is. I used pixels as a unit instead of %, just for demonstration. Both the controls (blue and maroon box in this case) are inside a div tag and that div tag and that div tag is set to "position: absolute;", and that div is inside another div having class="video-player" and "position: relative;" In this case I have made the body tag have position: relative; just to decrease the lines of code here .
Note: I made these divs just to exactly replicate my codes that are misbehaving.
<!DOCTYPE html>
<html>
<body style="position: relative;">
<div class= "header" style="width: 100%; height: 30px; cursor: default; background: #00aa00; display: block;">
<div class="fill" style="background: #ff0000; width: 0%; height: 100%;"><div>
</div>
<div style="width: 50%; position: absolute; display: block; transform: translate(0, 30px);">
<div style="width: 25%; height: 20px; display: inline-block; background: #0000aa;"></div>
<div style="width: 25%; height: 20px;display: inline-block; background: #aa0000; margin: 0 20px;"></div>
</div>
<br><br><br>
<p id="demo"></p>
<script>
var a = document.querySelector('.header');
var b = document.querySelector('.fill');
a.addEventListener('mousedown', function(event) {
test(event);
document.addEventListener('mousemove', test);
document.addEventListener('mouseup', function() {
document.removeEventListener('mousemove',test);
});
});
function test(event) {
var x = event.offsetX;
var y = event.offsetY;
var wid = a.offsetWidth;
var s = (x/wid)*100;
b.style.width = s+'%';
var coords = "X coords: " + x + ", Y coords: " + y;
document.getElementById("demo").innerHTML = coords;
}
</script>
</body>
</html>
Is there any way I can fix this problem?
Use pageX and pageY instead:
<!DOCTYPE html>
<html>
<body style="position: relative;">
<div class= "header" style="width: 50%; margin:auto; height: 30px; cursor: default; background: #00aa00; display: block;">
<div class="fill" style="background: #ff0000; width: 0%; height: 100%;"><div>
</div>
<div style="width: 50%; position: absolute; display: block; transform: translate(0, 30px);">
<div style="width: 25%; height: 20px; display: inline-block; background: #0000aa;"></div>
<div style="width: 25%; height: 20px;display: inline-block; background: #aa0000; margin: 0 20px;"></div>
</div>
<br><br><br>
<p id="demo"></p>
<script>
var a = document.querySelector('.header');
var b = document.querySelector('.fill');
a.addEventListener('mousedown', function(event) {
test(event);
document.addEventListener('mousemove', test);
document.addEventListener('mouseup', function() {
document.removeEventListener('mousemove',test);
});
});
function test(event) {
var x = event.pageX - a.offsetLeft;
var y = event.pageY - a.offsetTop;
var wid = a.offsetWidth;
var s = Math.min((x/wid)*100, 100);
b.style.width = s+'%';
var coords = "X coords: " + x + ", Y coords: " + y;
document.getElementById("demo").innerHTML = coords;
}
</script>
</body>
</html>
I have a website which has a page layout and style something like mentioned in this JsFiddle
Now Using JQuery when I click on the button, content is being displayed properly as shown below:
But when I first scroll the page and then click the button, content is not displaying properly as shown:
Can you please guide me to handle this situation ?
I have used below jQuery for this. But it seems offset or position is not working
$('#btn').click(function(){
var t = $(this).offset();
console.log(t);
$('.control-container').css('top', t.top + 20 + 'px');
$('.control-container').css('display', 'block');
});
$(document).on('scroll', function(){
$('.control-container').css('display', 'none');
});
You don't need to use offset to achieve that... And if you need to keep CSS with position:fixed, you need to switch it in javascript to static.
The thing you are looking for is simply display:table ...
$('#btn').click(function(){
$('.control-container').css({'display': 'table','position': 'static'});
});
$(document).on('scroll', function(){
$('.control-container').css({'display': 'none','position': 'fixed'});
});
Check out this JSFiddle
But if you really need a solution with position:fixed based on button position, you should try this way:
$('#btn').click(function(){
var button_fixed_position = $('#btn').get(0).getBoundingClientRect();
$('.control-container').css({'display': 'block','left' : button_fixed_position.left, 'top' : button_fixed_position.bottom});
});
$(document).on('scroll', function(){
$('.control-container').css({'display': 'none'});
});
Check out second JSFiddle
There is no need to specifically mention position property here.
Also remove the closing a tag and replace it with </button>
Currently container is occupying full width ,but that can also be set
$('#btn').click(function() {
var t = $(this).offset();
console.log(t);
$('.control-container').css('top', t.top + 30 + 'px');
$('.control-container').css('display', 'block');
});
$(document).on('scroll', function() {
$('.control-container').css('display', 'none');
});
.header {
background-color: maroon;
color: #fafafa;
height: 60px;
position: fixed;
width: 100%;
text-align: center;
line-height: 19px;
font-size: 25px;
z-index: 2;
padding: 0px;
margin: 0px;
top: 0;
}
.content {
background-color: #fff;
border: 1px solid #999;
padding: 5px;
height: 100%;
width: 100%;
position: absolute;
z-index: 1;
top: 60px;
}
.control-container {
width: auto;
background-color: red;
#position: fixed;
color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="header">
Header
</div>
<div style="clear:both">
</div>
<div class="content">
<br/>
<br/>
<br/>
<br/>
<br/>
<button id="btn">Click Me</button>
<div class="control-container" style="display:none;">
Keep me exactly underneath 'Click Me' when Page is scrolled.
</div>
</div>
</div>
CSS position fixed property positions an element referencing view's/body's dimension.
If you have access of modifying CSS, then just remove the position: fixed; property from .control-container.
If you don't have access, then using script add position: static !important property to .control-container.
$('.control-container').css('cssText', 'position: static !important');
Modified JSFiddle
I'm trying to create an online image cropper where the user uploads a photo and it is displayed with a box (frame) that is changeable via buttons. Crops the photo and sends it back to the user.
I have a basic template of form uploader in php (working). It then displays the image in a div with another transparent div above it with a border marking the cropping area.
The initial values for the divs are set in the css section via php as the page is sent to the user. I'm trying to adjust the size of the frame div, as the width given is the image width +2 px for the frame (same for height) and it should just be the images width (-2 px).
This code should be working, but when the alerts pop up, they show that the frame width/height has not changed the original values, and it appears as though the frame does not change.
<!DOCTYPE html>
<head>
<style type="text/css">
html, body {
width: 500px;
height: 334px;
background-color: black;
}
.top {
margin-top: 0px;
margin-bottom: 0px;
margin-left: 0px;
margin-right: 0px;
width: 500px;
height: 334px;
position: absolute;
background-color: transparent;
border-width: 1px;
border-style: solid;
border-color: white;
z-index: 999;
}
.bottom {
top: 0px;
left: 0px;
position absolute;
width: 500px;
height: 334px;
background-color: green;
// background-image: url(uploads/1505002267.jpg);
z-index: 998;
}
</style>
<script type="text/javascript">
function myOnLoad() {
var w = 500;
var h = 334;
var frame = document.getElementsByClassName('top')[0];
w = w - 2;
h = h - 2;
//frame.setAttribute("style", "width: " + w + "px;");
//frame.setAttribute("style", "height: " + h + "px;");
frame.style.width = w + "px;";
frame.style.height = h + "px;";
alert(frame.offsetWidth);
alert(frame.offsetHeight);
}
</script>
<title>Test Website</title>
</head>
<body onload="myOnLoad()">
<div class="wrapper">
<div class="bottom" id="image">
<div class="top" id="frame">
</div>
</div>
</div>
</body>
</html>
I am aware that I can change the value php gives to the css section, but I'm going to need to change the crop ratio in the next step anyway, so I need this way to work. Please help, I've been looking at this code for way too long.
Remove the semicolon in the quotes.
frame.style.width = w + "px";
frame.style.height = h + "px";
Also, offsetHeight and offsetWidth takes border into consideration. Since your border width is 1px, it adds 2px to both height and width of the image canceling out the subtraction with 2.
Read more about offset width and height on MDN.
I was referring to the following link to blur background on mouse scroll.
http://codepen.io/sotayamashita/pen/pqLcv
The code is shown as below:
HTML:
<div id="blurred-image-container">
<div class="img-src" style="background-image:url('https://d262ilb51hltx0.cloudfront.net/fit/c/1600/1280/gradv/29/81/60/darken/25/0*I7mXgSon9oco-rim.jpeg')"></div>
<div class="img-src blurred-img" style="background-image:url('https://d262ilb51hltx0.cloudfront.net/fit/c/1600/1280/gradv/29/81/40/darken/50/blur/50/0*I7mXgSon9oco-rim.jpeg')"></div>
</div>
<div class="article">
<h1>Medium</h1>
</div>
CSS:
.img-src {
position: fixed;
background-position: center;
-webkit-background-size: cover;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: -1;
}
.blurred-img { opacity: 0; }
.article {
width:500px;
height: 2000px;
}
h1 {
color: #fff;
position: fixed;
z-index: 9999;
font-size: 50px;
top: 50%;
margin-top: -25px;
left: 50%;
margin-left: -103px;
}
jQuery
$(window).scroll(function() {
// Get scroll position
var s = $(window).scrollTop(),
// scroll value and opacity
opacityVal = (s / 150.0);
// opacity value 0% to 100%
$('.blurred-img').css('opacity', opacityVal);
});
Then, the background picture that needs to be blurred is not at the very top of the page. My webpage is quite long and the background needs to be blurred is at the very bottom of the page.
I think the following code is trying to set the point where bluring starts to occur at the top of the page. I think there are more than 2000px to scroll down before reaching to the section I want to blur the background.
var s = $(window).scrollTop(), opacityVal = (s / 150.0);
Lets say my html document looks like this:
<div id="firstdiv">
<p>long text goes here....</p>
</div>
<div id="seconddiv">
<p>long text goes here....</p>
</div>
<div id="thirddiv">
<p>long text goes here....</p>
</div>
<div id="blurred-image-container">
<div class="img-src" style="background-image:url('https://d262ilb51hltx0.cloudfront.net/fit/c/1600/1280/gradv/29/81/60/darken/25/0*I7mXgSon9oco-rim.jpeg')"></div>
<div class="img-src blurred-img" style="background-image:url('https://d262ilb51hltx0.cloudfront.net/fit/c/1600/1280/gradv/29/81/40/darken/50/blur/50/0*I7mXgSon9oco-rim.jpeg')"></div>
</div>
<div class="article">
<h1>Medium</h1>
</div>
I want the background page to blur when the page is scroll down to #blurred-image-container section.
How can I modify the jQuery to work that?
<div class="out">
</div>
<div class="in">
</div>
out {
width: 100%;
height: 800px;
background: url('background') no-repeat;
}
.in {
width: 100%;
height: 200px;
background-color:olive;
}
$(window).on('scroll', function () {
var pixs = $(document).scrollTop()
pixs = pixs / 100;
var scroll;
$(window).scroll(function (event) {
scroll = $(window).scrollTop();
console.log(scroll);
*if(scroll>606)
{
$(".out").css({"-webkit-filter": "blur("+pixs+"px)","filter": "blur("+pixs+"px)" })
}*
});
});
This solution will require a separate element for the background but uses SVG filter to allow emulating motion blur in vertical direction.
It calculates the difference between last and current scroll position and uses that for a blur value. It debounces as well via using requestAnimationFrame(). It's easy to adopt to support a separate value for horizontal blurring as well.
You may want to tweak scale and max values for the blur, below some initial values only.
var blur = document.getElementById("fltBlur");
var prevY = 0;
var reqId;
window.onscroll = function() {
cancelAnimationFrame(reqId);
reqId = requestAnimationFrame(motionBlur)
};
function motionBlur() {
var y = window.scrollY;
var n = Math.min(32, Math.abs(y - prevY));
blur.setAttribute("stdDeviation" ,"0 " + n);
prevY = y;
}
html, body {width:100%; height:300%}
#cont {
width:100%;
height:300%;
background:url(//i.imgur.com/47zcWet.jpg);
-webkit-filter: url(#svgBlur);
filter: url("#svgBlur");
}
<svg style="position: absolute; top: -99999px" xmlns="http://www.w3.org/2000/svg">
<filter id="svgBlur" x="-5%" y="-5%" width="110%" height="110%">
<feGaussianBlur id="fltBlur" in="SourceGraphic" stdDeviation="0 0" />
</filter>
</svg>
<div id=cont></div>
My HTML basically looks like this:
<div id="#container">
<div id="left_col">
left stuff
</div>
<div id="middle_col">
middle stuff
</div>
<div id="right_col">
<div id="anchor"></div>
<div id="floater>
The problem div
</div>
</div>
</div>
The container div is pushed 82px to the left, because I don't want the rightmost column to be used as part of the centering (there is a header navigation bar above that is the size of left_col and middle_col):
#container {
width: 1124px;
margin-left: auto;
margin-right: auto;
text-align: left;
color: #656f79;
position: relative;
left: 82px;
}
#left_col {
float:left;
width: 410px;
background-color: #fff;
padding-bottom: 10px;
}
#middle_col {
width: 545px;
float: left;
}
#right_col {
float: left;
width: 154px;
margin-left: 5px;
position:relative;
}
#floater {
width: 154px;
}
I'm using the following javascript to keep the #floater div in position as you scroll down the page:
var a = function() {
var b = $(window).scrollTop();
var d = $("#anchor").offset().top;
var c = $("#floater");
if (b > d) {
c.css({position:"fixed",top:"10px"});
} else {
c.css({position:"absolute",top:""});
}
};
$(window).scroll(a);
a();
The problem I'm having is that in WebKit based browsers, once jQuery makes the floater div's positioning fixed so it will stay 10px from the top, that "left: 82px" from #container goes out the window, causing #floater to jump 82px to the left. This doesn't happen in FF or IE. Does anybody know a solution to this?
Update: Solved
I've solved this problem by not using fixed positioning, but instead using absolute positioning. I changed the javascript to set the top CSS property of div#floater to be based on the value $(window).scrollTop() if div#anchor's top offset is greater than $(window).scrollTop(). Pretty simple.
So the a() function now looks like this:
var a = function() {
var b = $(window).scrollTop();
var d = $("#anchor").offset().top;
var c = $("#floater");
if (b > d) {
var t = b-200; //200px is the height of the header, I subtract to make it float near the top
c.css({top:t+"px"});
} else {
c.css({top:""});
}
};