click based on position rather than element - javascript

can I create a function that takes x and y coordinates, and will click the document at those coordinates?
by looking at this question I set up some sample code in a jsfiddle, here is that code (it does not work)
var e = new jQuery.Event("click");
e.pageX = 10;
e.pageY = 10;
$("button").click(function(){
$(document).trigger(e);
});
what I thought the above code would do is click in the document at position (10,10), and because that section of the document is where the item that needs to be clicked is, it should do the same as would clicking the item. But it does not...what am I doing wrong?
why
why would I do this when I could just simply do something like:
$("button").click(function(){
$('.box').click();
});
well in certain circumstances, that is not possible. for example, clicking a specific div inside an iframe outside of the domain. I cannot click what is inside it through code because I don't have access to it's body. But if I know the position of that div in my own document and force the viewer to click over it, then that would work!

Well, you used
$('button').click(function(){...});
Maybe, you meant,
var e = new jQuery.Event("click");
e.pageX = 10;
e.pageY = 10;
$(document).trigger(e);

var x=e.pageX;//get the current mouse coordinates
var y=e.pageY;
function between(val, min, max)//this fun specifies the range!!!
{
return val >= min && val <= max;
}
Just a sample code.
$('body').click(function(){
if(between(x,your_conditional_min_x,your_conditional_max_x) && between(y,your_conditional_min_y,your_conditional_max_y))
//execute some code if its in my region!!!
});
In the above code--
your_conditional_min_x and y & your_conditional_max_x and y are the custom x and y positions that you want enclose your click in.
let me know if you are not clear with the code!!!

Related

Create a child div accordingly if another child already exists at that location (x,y)

I am inserting a textarea to a side bar (exactly on the right to), wherever a click is made on the page. The code is:
$('#page_to_be_clicked').click(function(e){
var offset = $(this).offset();
var comment_box_y_coord = e.pageY - offset.top;
alert(comment_box_y_coord);
$("#sidebar").append('<textarea id="cmmnt" rows="4" cols="10" '+
'style="position:absolute;top:'+comment_box_y_coord +
'px;left:5px"></textarea>');
})
The problem with this is that, if a textarea is already present at the location, it will overlap the existing, i.e. if a click is made twice at the same point on the page, then two textareas are created on top of each other. Instead, it should be created one below the other.
Is there a way to check, if a child already exists at the required co-ordinates?
Any help will be appreciated. Thanks.
How exactly should the textareas appear on clicks in a sequence:
This needs to be tested properly, but I think you need to do this:
DEMO
In your function change this line:
var comment_box_y_coord = checkCoords(e.pageY - offset.top);
and then add this function:
function checkCoords(y) {
if ($("textarea").length>0) {
$ts = $("textarea");
for (var i = 0; i<$ts.length;i++) {
var $ti = $ts.eq(i),
tcoords = [$ti.offset().top, $ti.offset().top+$ti.height()]
if (y>=tcoords[0] && y <= tcoords[1]) {
y = tcoords[1]+3;
}
}
}
return y;
}

html canvas trap left click and allow right click to pass through (pointer-events)

The use case is that I have an html canvas on top of several html elements which listen for right click mouse events. I want to draw on the canvas using left mouse button, and at the same time interact with underlying html elements using right click.
I get that I can allow all mouse events to pass through the canvas by setting css property pointer-events to none. However I want to allow only right click to pass through it.
One way to achieve this may be to listen on the canvas for right click, set pointer-events to none in the callback, manually fire a right click event again and set pointer-events back to auto.
Btw I'm using KineticsJS and I have no idea how to manually fire mouse events using it.
Any suggestions would be appreciated.
Interesting subject that caught my attention. It was fun to come up with a solution to it based on this jQuery approach and some others. I'm not familiar with KineticsJS, but this is a plain javascript approach
In essence you can fake a pointer-events:none for just the right click by using the object's dimensions/positioning and onmousedown's event.which to determine if a right click was clicked on the background elements. The following is an example of that approach, hopefully the comments explain it well
// Get all overlaying canvases
var canvas = document.getElementsByTagName("canvas"),
// Get all elements that you want the click to fire on
background = document.getElementsByClassName("background");
// Use click location and dimensions/positioning to fake a click through
function passThrough(e) {
// Allow only right click to pass through
if(e.which == 2 || e.which == 3) {
// Check all background elements
for(var i = 0; i < background.length; i++) {
// check if clicked point (taken from event) is inside element
var mouseX = e.pageX;
var mouseY = e.pageY;
var obj = background[i];
var width = obj.clientWidth;
var height = obj.clientHeight;
if (mouseX > obj.offsetLeft && mouseX < obj.offsetLeft + width
&& mouseY > obj.offsetTop && mouseY < obj.offsetTop + height) {
// Force click event if within dimensions
background[i].onclick();
}
}
}
}
for(var i = 0; i < canvas.length; i++) {
// Force our function when clicked
canvas[i].onmousedown = passThrough;
// Prevent menu from appearing
canvas[i].oncontextmenu = function(event) { event.returnDefault; return false; }
}
for(var i = 0; i < background.length; i++) {
// Toggle background when clicked (to show it works)
background[i].onclick = function() {
if(this.style.background == "black") {
this.style.background = "red";
}
else {
this.style.background = "black";
}
}
}
I hope it suits your needs!

Check if an element has changed its position

So, this is my code:
<div onmousedown="draggable(this);"></div>
What is the best method to detect when the user has clicked on the div if it has changed its position?
This can easily be done with variables to track the last position of the div.
var x = divVar.pageX
, y = divVar.pageY;
//then during your mouseup
function checkPositionOnMouseup(div){
if(div.pageX !== x || div.pageY !== y){
console.log("MOVED!");
x = div.pageX; //update variables to new position
y = div.pageY;
}
}
dragStart event will fire when user begins to drag the element.

JavaScript, using a function to change the text displayed in a HTML <p> tag

I have a HTML5 canvas, which is displaying a number of images and a paragraph of text on the page underneath the canvas. I want the text in the paragraph to be updated to display a different element from a JS array depending on which image the user clicks on.
Currently, I have a 'mousedown' function that looks like this:
_mousedown: function(evt) {
this._setUserPosition(evt);
var obj = this.getIntersection(this.getUserPosition());
if(obj && obj.shape) {
var shape = obj.shape;
this.clickStart = true;
shape._handleEvent('mousedown', evt);
isClickOnImage(evt);
var id = shape.id;
selectTip(id);
}
//init stage drag and drop
if(Kinetic.DD && this.attrs.draggable) {
this._initDrag();
}
}
I tried using the line var id = shape.id to update the ID that's being passed to the function, so that it will get the correct element from my 'tips' array, but for some reason, when I view the page in the browser, and click on an image, the text beneath the canvas is not updated. It seems that this function is not updating the 'id' variable to the ID of whichever image has been clicked.
After looking into this, it seems to me that I will want to use a loop inside the 'mousedown' function, that will take the 'id' of the image on which the click has been detected, and loop through my 'sources' array (which is where all of the images have been loaded from the HTML into the JS), checking at each position whether the image stored at that location has the same ID as that of the image that has been clicked on. If it does, the loop should set the text to the text stored at that position of the array, and if not, it should continue looking through the array until it find it. Would this make sense? I tried adding the following code to the 'mousedown' function, but it doesn't change the text as I expected:
var imageCheckArray = 0;
while(imageCheckArray < sources.length){
if(shape.id == sources[imageCheckArray]){
selectTip(imageCheckArray);
} else {
imageCheckArray++;
}
}
Is there something I'm missing from the loop?
The code for the whole function currently looks like this:
_mousedown: function(evt) {
this._setUserPosition(evt);
var obj = this.getIntersection(this.getUserPosition());
if(obj && obj.shape) {
var shape = obj.shape;
this.clickStart = true;
shape._handleEvent('mousedown', evt);
isClickOnImage(evt);
/*This line needs to get the element of the sources array that has been selected,
and then select the element at the same position from the tips array.*/
//var id = null;
var imageCheckArray = 0;
while(imageCheckArray < sources.length){
if(shape.id == sources[imageCheckArray]){
selectTip(imageCheckArray);
} else {
imageCheckArray++;
}
}
//var id =
//selectTip(id);
}
//init stage drag and drop
if(Kinetic.DD && this.attrs.draggable) {
this._initDrag();
}
}
Edit 11/01/2013 # 16:10
The code for selectTip is:
function selectTip(id){
$("#tipsParagraph").text(tips[id]);
}
and I've put a jsFiddle up here: http://jsfiddle.net/cd8G7/ although the 'result' panel is not showing what I actually see when I view the page in my browser- I get the canvas with all of the images displayed, and the paragraph underneath the canvas shows the text from the first element of my 'tips' array.
Edit 23/01/2013 # 13:50
Here's my isClickOnImage function:
function isClickOnImage(event){
var clickX = event.clientX;
var clickY = event.clientY;
//var imageCheckIteration = 0;
while(imageCheckIteration < sources.length){
if((clickX > sources[imageCheckIteration].x && clickX < sources[imageCheckIteration].x + imageWidth) &&
(clickY > sources[imageCheckIteration].y && clickY < sources[imageCheckIteration].y + imageHeight)){
/*This is where I need to print the variable that holds the text I want to display, but I need to display its contents
outside the canvas, in the <p></p> tags below. */
console.log("Click on image detected");
document.getElementById("tipsParagraph").innerHTML = sources[imageCheckIteration].data-tip /*tips[imageCheckIteration]*/;
} else {
document.getElementById("tipsParagraph").innerHTML = "";
}
}
}
What I intended that this function do is, capture the X & Y coordinates of any click on the canvas, and store them in the variables "clickX" and "clickY". Then, I have a variable called "imageCheckIteration" that has been initialised to 0, and while this variable is less than the length of my "sources" array (which is the array where all of the images have been stored), the function should check whether the click was on an area of the canvas that is covered by one of the images in the array.
If it was, then a console log should display the message "click on image detected", and the line
document.getElementById("tipsParagraph").innerHTML = sources[imageCheckIteration].data-tip;
should set the value of the "tipsParagraph" to be the value of the 'data-tip' attribute of whichever image is at the 'imageCheckIteration' position of the 'sources' array. If the click was detected on an area of the canvas that does not have an image displayed, then the value of the "tipsParagraph" should be set to hold nothing.
However, for some reason, when I view the page in the browser, the 'tipsParagraph' displays the text "This is where the text will be displayed", which is its default value, so that's fine. But, when I click on an image, or click anywhere else on the canvas, the text displayed in the 'tipsParagraph' is not updated.
I can't figure out why this is- can someone point me in the right direction? Does it mean that my isClickOnImage(event) function is never being called?
I simplified the way you are getting a reference to an image through the canvas. The trick here is to swap the z-index of the canvas and the image container and grab the reference to the image on the mouse up event. I don't know of a clean way to get elements behind a canvas, hence the workaround.
$('canvas').bind('mousedown', function(e) {
$('section').css('z-index', 4);
});
$('img').bind('mouseup', function(e) {
$('#tipsParagraph').text($(this).attr('id') + ":" + $(this).attr('alt'));
$('section').css('z-index', 2);
});
The second portion here is grabbing some attributes from the image itself and updating the text inside your div.
You can see more of the solution here.

Mootools textarea scrollHeight

How can I access the scrollHeight using mootools or some other property that contains the height so I can resize it to make an autogrow textarea?
Mootools offers a variety of Element 'dimension' functions that give you information on the scrollable and absolute element sizes. Full docs available here: http://mootools.net/docs/core/Element/Element.Dimensions
What you want to do is compare the return values of your element's getScrollSize() function to your element's getSize() function - in particular the 'y' member, which represents element and scrollable area height, respectively. Something along the lines of this should work:
var myElement = $('myElement'); // get a reference to your element
var scrollSize = myElement.getScrollSize(); // MooTools-specific function.
var elementSize = myElement.getSize(); // MooTools-specific function.
if (scrollSize.y > elementSize.y) {
// determine whether the scrollable area is greater than the dimensions
// of the element. If so, resize the element to match the scrollable area.
myElement.setStyle('height', scrollSize.y + 'px');
}
David Walsh created an excellent plugin for just this purpose:
http://davidwalsh.name/flext-textrea
Here's a simple method I'm using that expands but also contracts the textarea.
The issue you're always going to have is styling on the textare (padding/border).
The first thing to know is that getSize() will get the size of the textarea from absolute top to the absolute bottom, taking into account padding and borders. However, the actual style height of the text area .getStyle('height').toInt(), is the inside of the text box without padding and border. This is the part you need to be interested in as, when you set your height, it sets that, it doesn't set the full height of the textarea from absolute top to bottom.
Here's a working example, with a textarea that's styled (See Demo)
This will also resize the element correctly if you ran it inside domReady.
function expBox(el){
var e = $(el.id);
if(typeof(e._expBox) == "undefined"){
var v = e.value;
e.value = "";
var ss = e.getScrollSize();
var s = e.getSize();
var h = e.getStyle("height").toInt();
e._expBox = (s.y-h)-(s.y-ss.y);
e.value = v;
}
var k = event.keyCode || event.charCode;
if(k == 8 || k == 46){
e.setStyle("height","auto");
}
var ss = e.getScrollSize();
e.setStyle("height",(ss.y-e._expBox));
}
Demo:
http://jsfiddle.net/greatbigmassive/M6X5j/

Categories