var box=document.getElementById("box");
var display=document.getElementById("display");/*to display clientX result*/
var x=box.clientX;
box.addEventListener("click", show);
function show(){
display.innerHTML=x;
}
I feek like there is something simple going over my head that I just cant see
If you want to get the x-position of the mouse-click inside the box-element, you can achieve this with the help of the properties provided by the click-event.
let box = document.getElementById("box");
let display = document.getElementById("display");
function showMouseX(event){
display.innerHTML = event.clientX;
}
box.addEventListener("click", showMouseX);
The properties are clientLeft and clientTop, not clientX and clientY. See the Element interface. So
var x=box.clientLeft;
// -------------^^^^
Separately, and this may or may not be a problem depending on what you're doing, the line
var x=box.clientX;
gets the value of clientX from box as of when it runs, and then stores that value. There's no ongoing connection between x and box.clientX. So when the click occurs later and show is called, it shows the value as of earlier, when var x=box.clientX; ran. Depending on when that is, even if you make it clientLeft, you may get 0 instead of a valid value (if you're reading it during the initial loading of the page, and so the page may not have been laid out yet). Again, depending on what you're doing, you may want to wait and look up box.clientLeft when the click occurs. E.g.:
var box = document.getElementById("box");
var display = document.getElementById("display");
box.addEventListener("click", show);
function show(){
display.innerHTML = box.clientLeft;
}
Related
So I am using svg-pan-zoom to display a dynamically loaded SVG element. The code for loading the element is similar to the example here: https://ariutta.github.io/svg-pan-zoom/demo/dynamic-load.html (to see what I mean, view the source).
What I am trying to do is search the SVG document for text tags that match a specific query. I found an example here which seems like the solution to that part, but I can't find anything on how to access the SVG content inside svg-pan-zoom.
I'm afraid I don't have any code... I've been doing trial-and-error for quite a while now. Basically I'm just trying to figure out how to access the SVG content so I can search it.
Thanks!
I think this answer can be useful: Pan to specific X and Y coordinates and center image svg-pan-zoom
For example, let's suppose you want to look for a string that is contained inside a tspan (since you are not giving more details), then you can have a search box, and when it changes, the following function is called:
function searchTerm() {
let term = this.value;
var tspans = document.getElementsByTagName("tspan");
var found;
for (var i = 0; i < tspans.length; i++) {
if (tspans[i].innerHTML.includes(term)) {
found = tspans[i];
break;
}
}
let position = found.parentNode.parentNode.getAttribute("transform").split("translate(")[1].split(")")[0];
let posX = position.split(",")[0];
let posY = position.split(",")[1];
panZoom.zoom(1);
panZoom.pan({x:0,y:0});
var realZoom= panZoom.getSizes().realZoom;
panZoom.pan
({
x: -(posX*realZoom)+(panZoom.getSizes().width/2),
y: -(posY*realZoom)+(panZoom.getSizes().height/2)
});
}
As you can see, this code has been prepared for a specific situation, but you can get the position depending on your needs.
For hand trackers, their patch has info X, Y, and Z and when a hand is tracked there are values that appear. How do i get those value via script? is it possible? There aren't any hand tracking script examples.
I have the following so far to determine if a hand is detected, still not sure about getting the position:
//im assuming this is the correct module
const HandTracking = require('HandTracking');
const Scene = require('Scene');
//this is to check if a hand is detected
HandTracking.count.monitor().subscribe(function(e){
if(e.newValue){
Debug.log("hand found");
}
})
UPDATE
So im assuming it has something like this :
var thehand = HandTracking.hand(0);
var posx = thehand.cameraTransform.x.lastValue;
Debug.log(posx);
But this way is deprecated? need to use subscribeWithSnapshot but I'm not sure how to implement this.
Also it needs to be dynamic(?) because the value changes with every movement.
You are on the right track, what you need is simply:
var posx = thehand.cameraTransform.x;
This will give you a signal for the hand x position. To debug this value you can use:
Diagnostics.watch("hand x",posx);
A signal is a value that changes over time, and it can be bound to another object property, for example:
mySceneObject.transform.x = thehand.cameraTransform.x;
This will bind the hand x position signal to the object x position, so that the object will move with the hand.
Read more about signals here: https://developers.facebook.com/docs/ar-studio/scripting/reactive
They are a very powerful tool and essential knowledge for scripting in AR Studio.
Hope this helps!
I want to set an elements position equal to the position of the cursor every one second. But as soon as i include the setTimout attribute in the function it stops working and prints the following error in the log: "Uncaught RangeError: Maximum call stack size exceeded".
I have tried to run the code without a timeout but then the page freeze.
Here is the code that i can't get to work:
function moveElement() {
while (true) {
x = event.clientX;
y = event.clientY;
document.getElementById("status").innerHTML = x + " " + y; //This line is not important
setTimeout(moveElement(), 1000);
document.getElementById("test").style.color = "blue";
document.getElementById("test").style.left = x + "px";
document.getElementById("test").style.top = y + "px";
}
};
Also i get this error when i try to run event.clientX outside a function: "Uncaught TypeError: Cannot read property 'clientX' of undefined"
Can somebody see what is wrong with my code or just tell me another method to get it to work (no jQuery please)? Thank you.
/HamMan4Ever
This example waits until the mouse has stopped moving and then waits a second, then applies the new position.
I can create another example that just updates the position every second although it might be a good idea to wait for the mouse to stop moving.
This code waits for a mousemove and then clears any existing timers that are running and then sets up a new one. It also captures and stores the information about the mouse move to be used later.
Since the mousemove event is a recurring event (it fires like a thousand times whenever you move the mouse) which is why whenever the mouse is moved, all timers are cleared to avoid having multiple timers set at the same time.
The end result of this code is that when you move the mouse, it will wait until you have stopped moving the mouse, waits one second, and then sets the divs coord.
Please let me know in the comments if there is anything else I can do for you.
window.addEventListener('load',function(){//when the page loads
//initialize all variables.
var timer = false;
var updateTracking = false;
var x = 0;
var y = 0;
window.addEventListener('mousemove',function(e){//when the mouse is moved.
clearTimer();//clear the existing timer
updateTracking = true;//set the flag so that the if statement knows the mouse has been moved.
x = e.x;//get the X coord of the mouse move
y = e.y;//get the Y coord of the mouse move
setTimer();//set a timer for 1 second.
});
//the function that sets the timer.
function setTimer(){
//set the "timer" variable to a timer function
timer = window.setTimeout(function(){
if(updateTracking == true){//if the mouse has been moved
var elem = document.getElementById('theDiv');//get the element
updateTracking = false;//reset the flag since the element has been updated
elem.style.top = y+'px';//set the Y coord of the element
elem.style.left = x+'px';//set the X coord of the element
}
},1000);
}
function clearTimer(){//cleat timer function; clears any existing timers
window.clearTimeout(timer);//clear the timer
}
});
#theDiv{
width:30px;
height:30px;
background:red;
position:absolute;
}
<div id="theDiv"></div>
Here is another code snippet that shows you how the mousemove event functions. Just open your console and move the mouse...
window.onload = function(){
window.onmousemove = function(){
console.log('the mouse was moved');
};
};
The first parameter to setTimeout must be a function. When you use code like moveElement() you are calling the function (again) instead of just providing a reference to it. So I think you would be better of doing something like this:
setTimeout(moveElement, 1000);
The while (true) loop is causing your page to freeze because it is an eternal loop; It will run your code repeatedly, forever and doesn't give your browser time to breathe. The poor thing.
You have this line:
setTimeout(moveElement(), 1000);
Which should be:
setTimeout(moveElement, 1000);
Parentheses at the end of a function calls it immediately. So this function was just calling itself over and over. You want to pass a reference to the function that timeout should call after the specified time.
Uncaught RangeError: Maximum call stack size exceeded
You also should remove while(true) which will just loop forever. This is most likely why you received the above error. If you want to call this function every second just use setTimeout which will wait the amount of time specified and then call the function reference you passed it.
Uncaught TypeError: Cannot read property 'clientX' of undefined
This happens because there is no event variable that exists. Usually an event is passed to a function that has been attached as a handler to some event.
Here is an example of attaching an event and using clientX/clientY in some way. Perhaps it will help you understand and expand on it to do whatever it is you are trying to do:
Fiddle: http://jsfiddle.net/tqpvkjd9/
HTML:
<div id="test">some text</div>
JS:
function moveElement (event) {
var x = event.clientX;
var y = event.clientY;
var test = document.getElementById("test");
test.style.color = "blue";
test.style.left = x + "px";
test.style.top = y + "px";
};
document.addEventListener('mousemove', moveElement);
CSS:
div {
height: 100px;
width: 100px;
background: red;
position: absolute;
top: 0;
left: 0;
}
And lastly you should really declare x and y using var as I did above. Without var they are assumed to be global variables which is usually not good.
I would like to know if there is any specific way to get javaScript code to stop executing at some point so as to allow another called function to execute, for example in a sorting algorithm using Div's you call a function which annimates the swapping of the two Div's so you can visually see the sort taking place. I have tried using the setTimeout(c,t); however it does not seem to be be waiting and the Divs do not seem to be moving, if I however place an alert(""); within the moving code it seems to allow the move to take place with thousands to alerts popping up.
The code I have is as follows:
var q;
var w;
function move(x,y)
{
q = x.style.top; // Keep a reference to the Top divs top element
w = y.style.top; // Keep a reference to the Top divs top element
doMove(x,y);
}
function doMove(topDiv, bottomDiv)
{
//alert("in doMove " + topDiv);
topDiv.style.top = parseInt(topDiv.style.top)+2+'px';
bottomDiv.style.top = parseInt(bottomDiv.style.top)-2+'px';
//alert("hi");
if(bottomDiv.style.top != q && topDiv.style.top != w) // Check if the Top and Bottom divs have finally swapped
{
setTimeout(doMove(topDiv,bottomDiv),20); // call doMove in 20msec
}
}
One problem with your code is that in this line:
setTimeout(doMove(topDiv,bottomDiv),20);
You are calling doMove immediately and passing the value undefined as the first parameter to setTimeout. Not entirely sure that the following will solve your problem, but I would recommend trying this:
setTimeout(function() { doMove(topDiv,bottomDiv); }, 20);
I'm looking for an effecient way to constantly select the last element within the visible window/viewport.
So far, this is my code:
$(window).scroll(function () {
$('.post-content p').removeClass("temp last")
$('.post-content p').filter(":onScreen").addClass("temp")
$(".temp").eq(-1).addClass("last")
});
As you could probably imagine, this hauls up a lot of resources and doesn't perform very well. Can somebody please suggest from more elegant code?
My knowledge of Javascript is very basic, so please be patient with me. Thank you.
PS: I am using the onScreen plugin for the :onScreen selector: http://benpickles.github.com/onScreen/
Binding the scroll handler
Binding functions to the scroll Event can lead to serious performance problems. The scroll event fires really vigorously on page scroll, so binding functions with resource-heavy code to it is a bad idea.
What John suggests is setting up the interval and thereby having the code only execute some time after a scroll event.
Have a look at this jsfiddle to see difference between the implementations
The indirect handler solution comes at the cost of a noticeable lag between scrolling and executing the code, and it is your decision if you can trade in performance for snappier execution. Be sure to test performance on every browser you support.
Speeding up code execution
There are a lot of different concepts you can use to speed up your code. Regarding your code, it comes down to:
Caching selectors. You reselect elements every time the scroll handler fires, which is unnecessary
Not using jQuery plugins without knowing what they do. In your case, the plugin code is nice and quite straightforward, but for your goal you can have even snappier code.
preventing any unnecessary calculation. With your and the plugin's code, the offset of every element is calculated every time the scroll handler fires.
So what I've come up with is a Jsfiddle with an example how you could do you scroll handler. It's not exactly matched to your DOM because I don't know your html, but it should be easy to match it to your implementation.
I managed to reduce the time used by 95% compared to your code. You can see for yourself by profiling the two samples in chrome.
I assumed you just want to select the last element and you do not need the temp class
So, here's the code with explanations
// Store the offsets in an array
var offsets = [];
// Cache the elements to select
var elements = $('.elem');
// Cache the window jQuery Object
var jWindow = $(window);
// Cache the calculation of the window height
var jWindowHeight = jWindow.height();
// set up the variable for the current selected offset
var currentOffset;
// set up the variable for the current scrollOffset
var scrollOffset;
// set up the variable for scrolled, set it to true to be able to assign at
// the beginning
var scrolled = true;
// function to assign the different elements offsets,
// they don't change on scroll
var assignOffsets = function() {
elements.each(function() {
offsets.push({
offsetTop: $(this).offset().top,
height: $(this).height(),
element: $(this)
});
});
};
// execute the function once. Exectue it again if you added
// or removed elements
assignOffsets();
// function to assign a class to the last element
var assignLast = function() {
// only execute it if the user scrolled
if (scrolled) {
// assigning false to scrolled to prevent execution until the user
// scrolled again
scrolled = false;
// assign the scrolloffset
scrollOffset = jWindowHeight + jWindow.scrollTop();
// only execute the function if no current offset is set,
// or the user scrolled down or up enough for another element to be
// the last
if (!currentOffset || currentOffset.offsetTop < scrollOffset || currentOffset.offsetTop + currentOffset.height > scrollOffset) {
// Iterate starting from the bottom
// change this to positive iteration if the elements count below
// the fold is higher than above the fold
for (var i = offsets.length - 1; i >= 0; i--) {
// if the element is above the fold, reassign the current
// element
if (offsets[i].offsetTop + offsets[i].height < (scrollOffset)) {
currentOffset && (currentOffset.element.removeClass('last'));
currentOffset = offsets[i];
currentOffset.element.addClass('last');
// no further iteration needed and we can break;
break;
}
}
return true;
} else {
return false;
}
}
}
assignLast();
// reassign the window height on resize;
jWindow.on('resize', function() {
jWindowHeight = jWindow.height();
});
// scroll handler only doing assignment of scrolled variable to true
jWindow.scroll(function() {
scrolled = true;
});
// set the interval for the handler
setInterval(assignLast, 250);
// assigning the classes for the first time
assignLast();