I have two overlapping boxes. Structurally, they are residing side by side in the DOM. The blue one is absolutely positioned and overlaps the red box. I attached two click handlers on each of the boxes with jQuery.
Now, what I want to achieve is that as soon as I click on the intersection of the blue and red boxes, both the click handler of red and blue should be triggered. Now at the moment, only the blue mouse click callback is executed since it is lying on top of red.
I know that I can set pointer-events: none on the blue box but then I only get the event for the red div.
Here is a fiddle for clarification:
https://jsfiddle.net/nas2jg7t/1/
This is as simple as this, check to see if the click occurred within the bounds of the red div and whether the click was fired by the blue div, if so, fire the red div click event:
jQuery(document).ready(function(){
jQuery("body").on("click","#red,#blue", function(elem){
//Get the bottom y coordinate of the red div
const bottomRed = $('#red')[0].getBoundingClientRect().bottom;
//logging test for id of element
console.log(elem.target.id);
//check to see if the click event fell within the red div's boundary
//and if the blue div fired the event, if so, fire red div event
if(elem.pageY <= bottomRed && elem.target.id === "blue"){
$('#red').trigger('click');
}
});
});
Working fiddle: (https://jsfiddle.net/vd0wfspk/1/)
Try having the two elements nested in the DOM and calling event.stopPropagation();
In your case elem.stopPropagation();
You don't have many solution as I know, you need to calculate if the pointer click is inside or not the other div :
jQuery(document).ready(function () {
jQuery("body").on("click", "#red,#blue", function (event) {
console.log(event.target.id);
jQuery("#result").text("Clicked on " + event.target.id);
var otherDiv = jQuery("#red, #blue").not(this);
if (otherDiv.offset().top <= event.pageY &&
otherDiv.offset().top + otherDiv.height() >= event.pageY &&
otherDiv.offset().left <= event.pageX &&
otherDiv.offset().left + otherDiv.width() >= event.pageX) {
otherDiv.trigger('click');
}
});
});
You can use event clientX and clientY in order to get mouse position:
jQuery("body").on("click","#red, #blue", function(e) {
var x = e.clientX;
var y = e.clientY;
var bluPosminX = $('#blue').position().left;
var bluPosmaxX = bluPosminX + $('#blue').width();
var bluPosminY = $('#blue').position().top;
var bluPosmaxY = bluPosminY + $('#blue').height();
var redPosminX = $('#red').position().left;
var redPosmaxX = redPosminX + $('#red').width();
var redPosminY = $('#red').position().top;
var redPosmaxY = redPosminY + $('#red').height();
var clickedto = ""
if (x >= bluPosminX && x <= bluPosmaxX && y >= bluPosminY && y <= bluPosmaxY) {
clickedto += ' blue';
}
if (x >= redPosminX && x <= redPosmaxX && y >= redPosminY && y <= redPosmaxY) {
clickedto += ' red';
}
jQuery("#result").text("Clicked on " + clickedto);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="red" style="width:200px; height: 200px; background: red"></div>
<!-- Box blue -->
<div id="blue" style="width:200px; height: 200px; background: blue;position:absolute;top:80px; opacity: 0.7"></div>
<div id="result" style="position: relative; top: 100px;"></div>
Related
I have an audio player on a page. I have a custom progress bar that I created. When users click on that progress bar, I want to tell the audio player to start playing at that position. How do I detect the position of where the person clicked in the div and translate that to a position to play the song?
var aud = $('audio')[0];
var index = 0;
$('.play').on('click', function() {
aud.src = $(this).attr('data-url');
index = $(this).index('.play');
if (aud.paused) {
aud.play();
} else {
aud.pause();
}
});
aud.ontimeupdate = function() {
$('.progress-bar-wrapper').hide();
$('.progress-bar-wrapper:eq(' + index + ')').show();
$('.progress:eq(' + index + ')').css('width', aud.currentTime / aud.duration * 100 + '%')
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<audio src="" style="display: none"></audio>
<div class="play" data-url="{{url}}"><img src="/images/play_course.png" /></div>
<div class="progress-bar-wrapper">
<div class="progress"></div>
</div>
You can get the position of the mouse inside the click event.
I have added two variables inside the click event with both the position of the mouse relative to the element itself and the percentage that the click position represent, use them as you see fit.
Note: I added width and height for the progress bar so I can test your code so keep in mind that the progress wrapper needs to be visible and have a width value.
var aud = $('audio')[0];
var index = 0;
$('.play').on('click', function() {
aud.src = $(this).attr('data-url');
index = $(this).index('.play');
if (aud.paused) {
aud.play();
} else {
aud.pause();
}
});
$(".progress-bar-wrapper").on("click", function (e) {
var posX = e.pageX - $(this).offset().left;
var percentage = parseInt((posX / $(this).width()) * 100);
});
aud.ontimeupdate = function() {
$('.progress-bar-wrapper').hide();
$('.progress-bar-wrapper:eq(' + index + ')').show();
$('.progress:eq(' + index + ')').css('width', aud.currentTime / aud.duration * 100 + '%')
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<audio src="" style="display: none"></audio>
<div class="play" data-url="{{url}}"><img src="https://cdn.iconscout.com/icon/premium/png-512-thumb/play-button-1516951-1285078.png" /></div>
<div class="progress-bar-wrapper">
<div class="progress"></div>
</div>
Sorry guys, I am very new to Javascript. I have searched for similar solutions before posting here.
I want to change the background colour, every time that multiple div tags, with specific ids, come 150 pixels before they reach the browser top. I want it to work in different devices correctly. I tried different things in javascript but none gave me the responsiveness I want. When I reduce the browser's width, the text is folding and the div/ids positions change. So, my logic is... if, for example, a div with id="One" is 150px from top, change the background colour.
var one = document.getElementById("one");
var two = document.getElementById("two");
var three = document.getElementById("three");
window.addEventListener('scroll', () => {
if(one.getBoundingClientRect().top < 150){
document.body.addClass = "bg-one";
}
});
.site-main{
background-color: white;
}
.bg-one{
background-color: red;
}
.bg-two{
background-color: blue;
}
.bg-three{
background-color: yellow;
}
<body class="site-main" id="main">
<div id="one" class="">Text</div>
<div id="two" class="">Text</div>
<div id="three" class="">Text</div
</body>
I was thinking about that, but it doesn't work.
My solution would be to add an event listener on window scroll
window.onscroll = function(){ft_onscroll()};
in this function, you get the current scroll position. Compare it to your element position to do what you want.
one_y = one.getBoundingClientRect().top;
function ft_onscroll(){
y = window.scrollY;
if(one_y > y){
//change background color
}
}
I made it. My final code is this. Maybe I will make it shorter.
window.onscroll = function(){
fromTop_onscroll();
};
function fromTop_onscroll(){
var main = document.getElementById("main");
var one = document.getElementById("one");
one_distance = one.getBoundingClientRect().top; // distance from top
var two = document.getElementById("two");
two_distance = two.getBoundingClientRect().top; // distance from top
if(one_distance < 150 && two_distance > 150){
main.classList.add("bg-one");
main.classList.remove("site-main");
main.classList.remove("bg-two");
} else if (two_distance < 150 && one_distance < 0) {
main.classList.add("bg-two");
main.classList.remove("bg-one");
} else if (one_distance > 150 && two_distance > 150){
main.classList.add("site-main");
main.classList.remove("bg-two");
main.classList.remove("bg-one");
}
}
I have a site with top nav menu:
<nav id="menu">
<ul id="menu-nav">
<li class="current">Home</li>
<li>Cakes</li>
<li>Candy</li>
<li>Marshmellow</li>
<li>Honey</li>
</ul>
</nav>
And all my sections are:
<div id="Cakes" class="page">
<div class="container">
This is sweet
</div>
</div>
How can I use the mouse wheel to jump directly to the next or previous section?
Currently the mouse wheel will scroll the page like normal. But I want it to jump to every section with one wheel rotation without scrolling all the entire page.
Without plugins, all we need to do is to capture the mousewheel using mousewheel event -on Firefox we use DOMMouseScroll instead- and depending on the value of the event's originalEvent.wheelDelta -again in Firefox it is originalEvent.detail, thanks Firefox- if this value is positive then the user is scrolling upward, if it's negative then the direction is down.
JS Fiddle 1
jQuery (1) :
//initialize
var winHeight = $(window).height(),
pages = $('.page'),
navLinks = $('#menu-nav a'),
currentPage = 0;
$('html, body').animate({ scrollTop: 0}, 0);
// listen to the mousewheel scroll
$(window).on('mousewheel DOMMouseScroll', function(e){
//by default set the direction to DOWN
var direction = 'down',
$th = $(this),
// depending on the currentPage value we determine the page offset
currentPageOffset = currentPage * winHeight;
// if the value of these properties of the even is positive then the direction is UP
if (e.originalEvent.wheelDelta > 0 || e.originalEvent.detail < 0) {
direction = 'up';
}
// if the direction is DOWN and the currentPage increasing won't exceed
// the number of PAGES divs, then we scroll downward and increase the value
// of currentPage for further calculations.
if(direction == 'down' && currentPage <= pages.length - 2){
$th.scrollTop(currentPageOffset + winHeight);
currentPage++;
} else if(direction == 'up' && currentPage >= 0) {
// else scroll up and decrease the value of currentPage IF the direction
// is UP and we're not on the very first slide
$th.scrollTop(currentPageOffset - winHeight);
currentPage--;
}
});
// as final step we need to update the value of currenPage upon the clicking of the
// navbar links to insure having correct value of currentPage
navLinks.each(function(index){
$(this).on('click', function(){
navLinks.parent().removeClass('current');
$(this).parent().addClass('current');
currentPage = index;
});
});
(1) UPDATE
If you don't want to use jQuery, below is pure javascript code doing the same as above, this won't work in IE8 and below though:
JS Fiddle 2
Pure Javascript:
//initialize
var winHeight = window.innerHeight,
pages = document.getElementsByClassName('page'),
navLinks = document.querySelectorAll('#menu-nav a'),
currentPage = 0;
window.addEventListener('mousewheel', function(e) {
scrollPages(e.wheelDelta);
});
window.addEventListener('DOMMouseScroll', function(e) {
scrollPages(-1 * e.detail);
});
function scrollPages(delta) {
var direction = (delta > 0) ? 'up' : 'down',
currentPageOffset = currentPage * winHeight;
if (direction == 'down' && currentPage <= pages.length - 2) {
window.scrollTo(0, currentPageOffset + winHeight);
currentPage++;
} else if (direction == 'up' && currentPage > 0) {
window.scrollTo(0, currentPageOffset - winHeight);
currentPage--;
}
}
for (var i = 0; i < navLinks.length; i++) {
navLinks[i].addEventListener('click', updateNav(i));
}
function updateNav(i) {
return function() {
for (var j = 0; j < navLinks.length; j++) {
navLinks[j].parentNode.classList.remove('current');
}
navLinks[i].parentNode.classList.add('current');
currentPage = i;
}
}
You'll need to get a plug-in to add the mousewheel event.
Maybe try this one this.
it's got pretty good examples.
I am trying to make an image move on my command (the arrow keys), using CSS.
I thought about this:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<script>
function a() {
// k is a global variable but i dont know how to declare it
document.getElementById("img1").style.top = k + "px";
k++;
// and also i dont know how to trigger the function using the arrow keys
}
</script>
<body>
<form id="form1" runat="server">
<div>
<img id="img1" src="IMAGES/logo.jpg" height="100" width="100"
style="position:absolute; left:100px; top:100px; z-index:1" />
</div>
</form>
</body>
</html>
You could use onkeypress event using JavaScript to capture the keypress events of your keyboard.
for eg:
<input type="text" onkeypress="myFunction()">
Here is a demo: http://jsfiddle.net/nhYN3/36/
$("body").keydown(function(e) {
var max = $('body').width();
var min = 0;
var move_amt = 10;
var position = $("#my_image").offset();
if(e.which == 37) { // left
var new_left = ((position.left-move_amt < min) ? min : position.left-move_amt);
$("#my_image").offset({ left: new_left})
}
else if(e.which == 39) { // right
var new_left = ((position.left+move_amt > max) ? max : position.left+move_amt);
$("#my_image").offset({ left: new_left})
}
});
Source
In JavaScript only (without jQuery), it would look like this:
document.addEventListener("keydown", moveImage, false);
var img = document.getElementById('img1');
//The amount of pixels to move the image by with each keypress.
var moveJump = 10;
function moveImage(e) {
var kc = e.keyCode;
//Gets the current "top" value minus the "px" as an int.
var top = parseInt(img.style.top.substr(0, img.style.top.length - 2));
//Gets the current "left" value minus the "px" as an int.
var left = parseInt(img.style.left.substr(0, img.style.left.length - 2));
switch (kc) {
case 37:
//Pressed left.
img.style.left = (left - moveJump) + 'px';
break;
case 38:
//Pressed up.
img.style.top = (top - moveJump) + 'px';
break;
case 39:
//Pressed right.
img.style.left = (left + moveJump) + 'px';
break;
case 40:
//Pressed down.
img.style.top = (top + moveJump) + 'px';
break;
}
}
Fiddle: http://jsfiddle.net/auwchLdn/2/
<textarea></textarea>
This is the code i just need an output in which whenever tab is placed it indent to right.. but pressing tab do something else
Please see the following example: http://www.jqversion.com/#!/liDxmDg
you can use a jQuery code to accomplish that:
$(document).delegate('textarea', 'keydown', function(e) {
var keyCode = e.keyCode || e.which;
if (keyCode == 9) {
e.preventDefault();
var start = $(this).get(0).selectionStart;
var end = $(this).get(0).selectionEnd;
// set textarea value to: text before caret + tab + text after caret
$(this).val($(this).val().substring(0, start)
+ "\t"
+ $(this).val().substring(end));
// put caret at right position again
$(this).get(0).selectionStart =
$(this).get(0).selectionEnd = start + 1;
}
});