I have a web application containing an image on which a mousewheel event is caught in order to zoom the image precisely on the point where the cursor is.
On top of this image, I display a custom tooltip which is just a div containing text. When I mousewheel on the tooltip, the image is not zoomed.
I tried to bind the image mousewheel event on the tooltip but then, the offsetX and offsetY of the event correspond to the cursor position relative to the tooltip and not relative to the image.
How can I:
either get the image offsetX and offsetY, even when the cursor is over the tooltip? or
prevent the tooltip to catch the mousewheel event before the image?
EDIT:
Actually, Before, I could select the tooltip by clicking on it; but by adding the CSS style 'pointer-events:none' (suggested by Aramil Rey), the click event has no effects (obviously).
Therefore, how can I:
prevent the tooltip to catch the mousewheel event before the image?
and still let the tooltip catch the click event?
Did you try using CSS: pointer-events:none; on the tooltip?
JS Fiddle
Try hovering on the red div, and you will notice that it won't trigger its attached event, and intead it will trigger yellow div on mouseeenter event if you enter that div, even if your cursor is over the red div.
$('.asd').on('mouseenter', function() {
alert('asd');
});
$('.ddaa').on('mouseenter', function() {
alert('ddaa');
});
.ddaa {
padding-top: 15px;
background-color: yellow;
}
.asd {
position: absolute;
width: 100%;
pointer-events:none;
padding-top: 10px;
top: 5px;
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="ddaa">
</div>
<div class="asd">
</div>
I assume currently you are getting offsetX and offsetY from event.target. Set an ID to the image and replace event.target with $("#imageID")[0]. Better yet, jquery provides an offset function.
var image = $('#image');
image.add('.tooltip').bind('mousewheel', function (event) {
event.preventDefault();
var offset = image.offset();
var mouseX = event.pageX - offset.left;
var mouseY = event.pageY - offset.top;
// zoom stuff
});
Related
I am trying to find a way to prevent the text cursor/caret in an editable element from changing position when I right-click on text in the element.
I have an example implementation here:
https://jsfiddle.net/pv20xLsf/52/
This is the HTML
<p id="editable-content" contenteditable=true>
editable text for testing
</p>
<div id="context-menu" style="display: none; position: absolute; height: 100px; width: 50px; border: 1px solid gray; border-radius: 5px; background-color: white;">
context menu.
</div>
and this is the JS code:
const editableElement = document.getElementById('editable-content');
const contextMenu = document.getElementById('context-menu');
// hide the context menu on clicking outside the editable element.
window.addEventListener('mousedown', (event) => {
contextMenu.style.display = 'none';
contextMenu.top = 0;
contextMenu.left = 0;
});
// prevent the default context menu from showing.
window.addEventListener('contextmenu', (event) => {
event.preventDefault();
});
// show a custom context menu when I right-click on the editable element.
editableElement.addEventListener('contextmenu', (event) => {
event.preventDefault();
event.stopPropagation();
contextMenu.style.display = 'block';
contextMenu.style.left = event.clientX + 'px';
contextMenu.style.top = event.clientY + 10 + 'px';
});
My goal is to create a custom context menu which is triggered when a user right-clicks on text in an editable element. When the context menu is displayed, right clicks should not change the location of the text cursor, but when it is hidden, then the location of the cursor should change on right-click.
I noticed that the behaviour is different on different browsers and I would like to get consistent behaviour. Tested on chrome, firefox and safari.
<div
v-for="day in week.days"
:key="day.timestamp"
#mouseover="selectDate($event,day)">
</div>
<div v-show="displayEvents.length!=0" ref='eventList'
style= "
background:red;
height:min-content;
width:200px;
position:absolute; "
>
{{displayEvents}}
</div>
<script>
selectDate: function(event, day) {
this.$refs.eventList.style.top = event.clientY + "px";
this.$refs.eventList.style.left = event.clientX + "px";
},
</script>
For some reason whenever I hover on the date selected the box only displays on the top left of the page, however what I am trying to achieve is to actually display the box precisely where the cursor pointer is, so in my case will be on top of the date highlighted in green (12th), as a normal tooltip would work.
clientX and clientY are not css-rules. You must use left and top, respectively.
Like this:
<div
v-show="displayEvents.length!=0"
ref="eventList"
style="
background:red;
height:50px;
width:200px;
position:absolute;"
>
</div>
<script>
document.addEventListener('mouseover', event => {
this.$refs.eventList.style.top = event.clientY + "px";
this.$refs.eventList.style.left = event.clientX + "px";
})
</script>
Note that the position of the div will be relative to the first ancestor element with position: relative, or, if no such ancestor is found, to the body element.
EDIT: I see that you edited your code to use top and left. Provided your code is executed by the correct event, it should work.
I have solved this issue by using pageY and pageX instead of clientY and clientX.
I have a div containing three buttons. The div needs to be draggable, so that you can drag all three buttons around the screen together. That works fine, but the problem is that when I click on of the individual buttons it inherits the draggable id and it is draggable on it's own. I do not want that to happen. So my question is: how do I make my buttons draggable, but make them always stay together and keep them clickable. I added the code below, but here is a JSFiddle: http://jsfiddle.net/2ga50vvt/
So to be clear: the div also needs to be draggable through dragging one of the individual buttons, but then the rest of the div needs to stick with it. Now dragging an individual button only moves the button.
P.S. I do not want to use JQuery UI
HTML:
<div id="draggable" class="ui-widget-content">
<button ng-click="menu.shown = !menu.shown">MENU</button>
<br>
<button ng-click="disconnect()">CLOSE</button>
<br>
<button ng-click="">KEYS</button>
</div>
JS
$(document).ready(function() {
var $dragging = null;
$('body').on("mousedown", "#draggable", function(e) {
$(this).attr('unselectable', 'on').addClass('dragged');
var el_w = $('.dragged').outerWidth(),
el_h = $('.dragged').outerHeight();
$('body').on("mousemove", function(e) {
if ($dragging) {
$dragging.offset({
top: e.pageY - el_h / 2,
left: e.pageX - el_w / 2
});
}
});
$dragging = $(e.target);
}).on("mouseup", ".dragged", function(e) {
$dragging = null;
$(this).removeAttr('unselectable').removeClass('dragged');
});
});
CSS:
body {
padding: 50px;
}
.dragged {
background-color: yellow;
}
#draggable {
position: fixed;
width: 150px;
height 150px;
padding: 0.5em;
background: red;
background-color: black;
z-index: 1000;
cursor: move;
float: left;
}
Update 1
This is a working solution: http://jsfiddle.net/2ga50vvt/3/
However when I click on the div and start dragging the center of the div jumps to my cursor. It works great, but it looks a bit wonky. Is there a way to prevent the div from moving to my cursor?
Your help is most welcome.
You can read the target property of the event and return false to avoid all not #draggable to be draggable.
if(e.target.id !== "draggable") {
return false;
}
The edited fiddle:
http://jsfiddle.net/2ga50vvt/1/
It works perfectly, but one suggestion: don't target with ids because with this code you can't drag more of one element (ids must be unique), so the workaround is to write an attribute or a classname and play with it.
Good luck.
Use $dragging = $('#draggable'); instead of $dragging = $('e.target');
It will drag div if you try to drag using cursor on button. It will drag #draggable instead of target.
Working Fiddle
Presuming you're opposed to JQueryUI for it's file size, I'd still recommend a prebuilt solution because why reinvent the wheel?
Draggabilly is a really nifty library that I've used when resource size has been an issue. It's 20k minified (obviously even smaller gzipped) and available on a CDN - which in itself has lots of benefits e.g. caching.
$(function() {
$( "#draggable" ).draggabilly();
});
There's a few CSS hooks, different options, events etc.
JSFiddle here
Also please view the attached image for clarification. I have a div container what I want to to find a position somewhere in that div container using jquery or javascript or both. The attached image shows everything. Please help.
Update
The reason I want to find this position is that I want to animate container towards that point and eventually disappear. Secondly I would like to find position on the opposite side too so that I could animate container from that position.
Second update
In other words how can we find the point of intersection of two lines?
Given you need to find the intersection between two lines inside a div, your markup could look like this:
<div id="container" style="position:absolute; width: 100%; height: 200px;">
<div style="width: 2px; height: 100%; left: 20%; position:absolute; background-color: red; top: 0;"></div>
<div style="height: 2px; width: 100%; left: 0; position:absolute; background-color: blue; top: 25%;"></div>
</div>
Using jQuery, you can find the coordinates for the intersection like this:
var x = $('#container div:first').position().left;
var y = $('#container div:last').position().top;
console.log(x,y);
x and y would be the coordinates in pixels relative to the container element.
http://jsfiddle.net/sAsmj/
I dont see the image, however if you are looking at getting the position, which is ideally caret position, you can use the jquery plugin http://plugins.jquery.com/project/jCaret
You can find the poiter position by using this, try it
$(document).ready(function(){
$("div#container").on("mousemove", function(e){
var self = $(this);
var dx = e.pageX;
var dy = e.pageY;
var x = dx - self.offset().left ;
var y = dy - self.offset().top ;
console.log(x);
console.log(y);
});
});
If you want the X, Y of the mouse you can read this question:
getting the X/Y coordinates of a mouse click on an image with jQuery
Here is an excerpt from the question which is based upon an img but you can change it for your container:
$(document).ready(function() {
$('img').click(function(e) {
var offset = $(this).offset();
alert(e.clientX - offset.left);
alert(e.clientY - offset.top);
});
});
I want to make the drag drop to the element,and I dot not want the parent of this element capture the click or drag event, so I use the bubble model, however the element which I want to drag contain a child who own the same size (width, height, left...) of this element.
For example:
<div id="div_con" style="left: 20px; top: 50px; width: 181px; height: 357px; position: absolute; z-index: 10; cursor: pointer;" class="drag">
<img src="test.PNG" id="Over_Label_1912694_Img" style="left: 0px; top: 0px; width: 181px; height: 357px; position: relative;">
</div>
div#div_con is the element I want to drag, but since the div#div_con and the img have the same size, so user can never click the div#div_con. Since the img is above it.
So I bind the mouseDown, mouseMove, mouseUp events to the whole document:
document.onmousedown = OnMouseDown;
document.onmouseup = OnMouseUp;
In my opinion,when user click the img under the div#div_con, the mouseDown event will bubble to div#div_con.
Since I just want to drag the div#div_con,so I make a check in the mouseDown handler:
if ((e.button == 1 && window.event != null || e.button == 0) && target.className == 'drag')
{ //do the start the move}
But it does not work.
This is the complete example:
http://jsfiddle.net/5SCwG/
But it is bubbling. That's why document is receiving the event to begin with. The problem you're experiencing is that event.target refers to the object clicked, and event.currentTarget refers to the object listening and neither one of those are your div.
You will either need to use an event listener on the div directly, or you'll need to get target.parentElement and then use that as _dragElement.
Check it out.
If you specify the image as background-image of the DIV and remove the IMG drag & drop works: http://jsfiddle.net/HxaJ4/