elementFromPoint() full document alternative - javascript

I am trying to recover a value from a cookie, which is somewhere on the Y-axis where the user clicked. I then want to find the parent <h2> from that click (if it helps, all the <h2>s are the first child of a <div class="_bdnable_">). Here is what I have so far:
var bookmarkLocation;
function getBookmarkPos() {
if ($.cookie("bookmark-position") !== null) {
$(".bdnable").each(function(i) {
var scrollTopTop = $(this).offset.top;
var scrollTopBottom = $(this).offset.top + $(this).height();
// var screenWidth = parseInt(screen.width/2);
// alert(screenWidth);
// var bookmarkPosition = parseInt($.cookie("bookmark-position"));
// alert(bookmarkPosition);
// var query = document.elementFromPoint(screenWidth, 50).nodeName;
// alert(query);
if ($.cookie("bookmark-position")>=scrollTopTop && $.cookie("bookmark-position")<=scrollTopBottom) {
bookmarkLocation = $(this).closest("div").children(":nth-child(1)").text();
}
});
if (bookmarkLocation == null) {
bookmarkLocation = "Unknown";
}
} else {
bookmarkLocation = "No bookmark set";
}
$("#bookmarklocationspan").html(bookmarkLocation);
}
In the commented out section is where I tried to use getElementFromPoint and then realized that it only checks the visible area. Not good, because the scrollable Y-axis on the page is 1000s of pixels tall.
Any ideas are greatly appreciated!!!

If you already have the y-coordinate of the click from the cookie, why not simply compare all H2's y-position and pick the one which is the next "higher" one? Your approach looks like it's compares whether the user has clicked directly on the H2 instead of the article/button below it?
Just an idea - don't rate it's style, think its prettey messy:
var $myH2 = $('h2');
var clickY = <COOKIE_VALUE>;
var currentY = 0;
var foundH2ID = '';
for (var i = 0; i < $myH2.length; i++) {
var h2Y = $($myH2[i]).position().top;
if (h2Y <= clickY && h2Y > currentY) {
currentY = h2Y;
foundH2ID = $myH2[i].id;
}
}
Or maybe I got you wrong?

Related

Javascript code not running, how can I fix?

My code is supposed to add 1 to the counter when I hit space and then change the magnifying glass to tilt the other direction. It just doesn't do anything when I hit space.
I've fixed every problem I saw, nothing worked. Maybe somebody else knows, I'm really not that good at js.
var hits = 0;
var hitElement = document.querySelector( '.hits' );
document.body.onkeydown = function(e) {
if( e.keyCode == 32 ) {
addHit();
}
}
var mag = "🔎";
var hitElement2 = document.querySelector( '.mag' );
document.body.onkeydown = function(f) {
if( f.keyCode == 32 ) {
if( mag.text == "🔎") {
mag = "🔍";
renderMag();
else
mag = "🔎";
renderMag();
}
}
}
var addHit = function() {
hits++;
renderHits();
}
var renderMag = function() {
hitElement2.innerHTML = mag;
}
var renderHits = function() {
hitElement.innerHTML = hits;
}
var resetHits = function() {
hits = 0;
renderHits();
}
Console says absolutely nothing too.
I fixed a few things and changed a few things that didn't need fixing. The three key points:
As mentioned, if a bit harshly, by Randy, your second event listener was overwriting your first, so hits was not increasing
The brackets in the if statement of your second event listener had some issues
Though checking the mag icon might work, using icons in the code feels like asking for something to break, so I changed that to a modulo check, to see whether hits was odd or even.
You were on the right track. When you have issues like this in the future, try putting console log statements in various places in the code. Make predictions about what variables should have what values at what points, then check if they do, then, if they don't, try to figure out why not.
var hits = 0;
var hitElement = document.querySelector('.hits');
var mag = "🔎";
var hitElement2 = document.querySelector('.mag');
document.body.onkeydown = function(f) {
if (f.key == ' ') {
addHit();
if (hits % 2 === 0) {
mag = "🔍";
renderMag();
} else {
mag = "🔎";
renderMag();
}
}
}
function addHit() {
hits++;
renderHits();
}
function renderMag() {
hitElement2.innerHTML = mag;
}
function renderHits() {
hitElement.innerHTML = hits;
}
function resetHits() {
hits = 0;
renderHits();
}
<div class="hits"></div>
<div class="mag"></div>

Angular $window.scrollTo() isn't working

I'm trying to scroll to a particular element after finding it on a page in my Angular app.
angular.element(document).ready(function () {
var foundDone = 0;
var currOver = 0;
for (var prog in $scope.programs){
var big = $scope.programs[prog];
if(!big.over && foundDone === 0){
foundDone++;
var e = document.getElementsByClassName('programThumbs')[currOver];
var theTop = e.getBoundingClientRect().top;
$window.scrollTo(0, theTop)
console.log("Scrolled to " + theTop)
}
currOver++;
}
});
I've tried $window.scrollTo() as well as window.scrollTo(), but neither are doing anything here. My console logs: Scrolled to 565, which is the correct y-position.
Any ideas on what I'm doing wrong here?
I'm not sure about scrollTo() but have you tried scrollTop property?
// Set the number of pixels scrolled
element.scrollTop = intValue;

Illustrator JavaScript only works once - won't toggle

I'm writing a script which changes the colours of a stick-man's arms and legs. Once "he" is selected, it effectively just mirrors the colours:
//Declare and initialize variables
var msgType = "";
var app;
var docRef = app.activeDocument;
var testColor = docRef.swatches.getByName("CMYK Green");
var leftColor = docRef.swatches.getByName("LeftColor");
var rightColor = docRef.swatches.getByName("RightColor");
function sameColor(CMYKColor1, CMYKColor2) {
"use strict";
var isTheSameColor;
if ((CMYKColor1.cyan === CMYKColor2.cyan) && (CMYKColor1.magenta === CMYKColor2.magenta) && (CMYKColor1.yellow === CMYKColor2.yellow) && (CMYKColor1.black === CMYKColor2.black)) {
isTheSameColor = true;
} else {
isTheSameColor = false;
}
return isTheSameColor;
}
// check if a document is open in Illustrator.
if (app.documents.length > 0) {
var mySelection = app.activeDocument.selection;
var index;
// Loop through all selected objects
for (index = 0; index < mySelection.length; index += 1) {
// Switch left and right colours
if (sameColor(mySelection[index].strokeColor, leftColor.color)) {
mySelection[index].strokeColor = rightColor.color;
}
if (sameColor(mySelection[index].strokeColor, rightColor.color)) {
mySelection[index].strokeColor = leftColor.color;
}
if (sameColor(mySelection[index].fillColor, leftColor.color)) {
mySelection[index].fillColor = rightColor.color;
}
if (sameColor(mySelection[index].fillColor, rightColor.color)) {
mySelection[index].fillColor = leftColor.color;
}
}
}
It works, but it only works once (i.e. I can't toggle the change again). If I undo the change and try again it works again. Why is this?
After a lot of head-scratching / debugging it turns out that it was changing the CMYK values to be not quite the same (by a tiny fraction).
Changed the following:
if ((CMYKColor1.cyan === CMYKColor2.cyan) ...
to:
if ((Math.round(CMYKColor1.cyan) === Math.round(CMYKColor2.cyan)) ...
and it works fine now.

javascript not working when page is loaded qtip2

I wrote a nice heatmap in javascript, and that worked pretty nice so far. The heatmap is basically a table with a coloring variation, based on the threshold of the value displayed in the table. I used JavaScript to create the table, and to set up the colors. However, I wanted to show a nice pop up window, so when the user hover over the table's cell, some additional information is displayed. I found this library qTip2
$(document).ready(function(){
$('#mytable td').qtip({
overwrite : false, // make sure it can't be overwritten
content : {
text : function(api){
return "Time spent: " + $(this).html();
}
},
position : {
my : 'top left',
target : 'mouse',
viewport : $(window), //keep it on-screen at all time if possible
adjust : {
x : 10, y : 10
}
},
hide : {
fixed : true // Helps to prevent the tooltip from hiding occassionaly when tracking!
},
style : 'ui-tooltip-tipsy ui-tooltip-shadow'
});
});
This function creates the heatmap:
function makeTable(data)
{
var row = new Array();
var cell = new Array();
var row_num = 26;
var cell_num = 44;
var tab = document.createElement('table');
tab.setAttribute('id', 'mytable');
tab.border = '1px';
var tbo = document.createElement('tbody');
for(var i = 0; i < row_num; i++){
row[i] = document.createElement('tr');
var upper = (i+1)*44;
var lower = i*44;
for(var j = lower; j < upper; j++){
cell[j] = document.createElement('td');
//cell[j].setAttribute('class', 'selector');
if(data[j] != undefined){
var count = document.createTextNode(data[j].diff);
cell[j].appendChild(count);
var index = parseInt(data[j].diff);
/* specify which color better suits the heatmap */
if(index >= 0 && index <= 100){
cell[j].style.backgroundColor = '#00BFFF';
}
else if(index > 100 && index <= 1000){
cell[j].style.backgroundColor = "#6495ED";
}
else if(index > 1000 && index <= 4000){
cell[j].style.backgroundColor = "#4682B4";
}
else if(index > 4000 && index <= 6000){
cell[j].style.backgroundColor = "#0000FF";
}
else{
cell[j].style.backgroundColor = "#00008B";
}
row[i].appendChild(cell[j]);
}
}
tbo.appendChild(row[i]);
}
tab.appendChild(tbo);
document.getElementById('mytable').appendChild(tab);
}
Inside of my <body> tag I have:
<div id="body">
<div id="mytable"></div>
</div>
However, when I load the page, I expect to see the pop up box when I hover the mouse over the table's cell, however something happens. Also, when I execute that $(document).ready part from firebug's terminal, then the program starts to execute as suppose to. I also made sure the library is being loaded into my page before I used it. I also don't see any errors in the firebug's terminal.
<script src="http://localhost/heatmap/javascript/jquery.qtip.js">
Could someone please give me a clue why is this happening?
The main function of my javascript is
function OnLoad() {
$.post('index.php/heatmap/getDatalines',
function(answer){
var data = eval('(' + answer + ')');
var list = [];
makeTable(data);
});
}
Thanks
whis is called on load: google.setOnLoadCallback(OnLoad);
You need to create the qtip after you have loaded the table like this:
function OnLoad() {
$.post('index.php/heatmap/getDatalines',
function(answer){
var data = eval('(' + answer + ')');
var list = [];
makeTable(data);
$('#mytable td').qtip({
overwrite : false, // make sure it can't be overwritten
content : {
text : function(api){
return "Time spent: " + $(this).html();
}
},
position : {
my : 'top left',
target : 'mouse',
viewport : $(window), // keep it on-screen at all time if possible
adjust : {
x : 10, y : 10
}
},
hide : {
fixed : true // Helps to prevent the tooltip from hiding occassionaly when tracking!
},
style : 'ui-tooltip-tipsy ui-tooltip-shadow'
});
});
}

Trouble with onclick attribute for img when used in combination with setInterval

I am trying to make images that move around the screen that do something when they are clicked. I am using setInterval to call a function to move the images. Each image has the onclick attribute set. The problem is that the clicks are not registering.
If I take out the setInterval and just keep the images still, then the clicks do register.
My code is here (html, css, JavaScript): https://jsfiddle.net/contini/nLc404x7/4/
The JavaScript is copied here:
var smiley_screen_params = {
smiley_size : 100, // needs to agree with width/height from css file
num_smilies: 20
}
var smiley = {
top_position : 0,
left_position : 0,
jump_speed : 2,
h_direction : 1,
v_direction : 1,
intvl_speed : 10, // advance smiley every x milliseconds
id : "smiley"
}
function randomise_direction(s) {
var hd = parseInt(Math.random()*2);
var vd = parseInt(Math.random()*2);
if (hd === 0)
s.h_direction = -1;
if (vd === 0)
s.v_direction = -1;
}
function plotSmiley(sp /* sp = smiley params */) {
var existing_smiley = document.getElementById(sp.id);
if (existing_smiley !== null)
// delete existing smiley so we can move it
document.getElementById("smileybox").removeChild(existing_smiley);
var smiley_to_plot = document.createElement('img');
smiley_to_plot.setAttribute('src', "http://i.imgur.com/C0BiXJx.png");
smiley_to_plot.setAttribute('id', sp.id);
smiley_to_plot.setAttribute('onclick', "my_click_count()");
smiley_to_plot.style.position = 'absolute';
smiley_to_plot.style.top = sp.top_position + "px";
smiley_to_plot.style.left = sp.left_position + "px";
document.getElementById("smileybox").appendChild(smiley_to_plot);
}
function random_direction_change() {
var r = parseInt(Math.random()*200);
if (r===0)
return true;
else
return false;
}
function moveFace(sp_array /* sp_array = smiley params array */) {
var i;
var sp;
for (i=0; i < sp_array.length; ++i) {
// move ith element
sp = sp_array[i];
if (
(sp.h_direction > 0 && sp.left_position >= smiley_screen_params.width - smiley_screen_params.smiley_size) ||
(sp.h_direction < 0 && sp.left_position <= 0) ||
(random_direction_change())
) {
sp.h_direction = -sp.h_direction; // hit left/right, bounce off (or random direction change)
}
if (
(sp.v_direction > 0 && sp.top_position >= smiley_screen_params.height - smiley_screen_params.smiley_size) ||
(sp.v_direction < 0 && sp.top_position <= 0) ||
(random_direction_change())
) {
sp.v_direction = -sp.v_direction; // hit top/bottom, bounce off (or random direction change)
}
sp.top_position += sp.v_direction * sp.jump_speed;
sp.left_position += sp.h_direction * sp.jump_speed;
plotSmiley(sp);
}
}
if (typeof Object.create !== 'function') {
Object.create = function(o) {
var F = function () {};
F.prototype = o;
return new F();
};
}
function generateFaces() {
var smilies = new Array();
var s;
var i;
var css_smileybox=document.getElementById("smileybox");
var sb_style = getComputedStyle(css_smileybox, null);
// add info to the screen params
smiley_screen_params.width = parseInt(sb_style.width);
smiley_screen_params.height = parseInt(sb_style.height);
// create the smileys
for (i=0; i < smiley_screen_params.num_smilies; ++i) {
s = Object.create(smiley);
s.id = "smiley" + i;
s.top_position = parseInt(Math.random() * (smiley_screen_params.height - smiley_screen_params.smiley_size)),
s.left_position = parseInt(Math.random() * (smiley_screen_params.width - smiley_screen_params.smiley_size)),
randomise_direction(s);
smilies.push(s);
}
setInterval( function(){ moveFace(smilies) }, smiley.intvl_speed );
}
var click_count=0;
function my_click_count() {
++click_count;
document.getElementById("mg").innerHTML = "Number of clicks: " + click_count;
}
generateFaces();
The generateFaces() will generate parameters (for example, coordinates of where they are placed) for a bunch of smiley face images. The setInterval is within this function, and calls the moveFace function to make the smiley faces move at a fixed interval of time. moveFace computes the new coordinates of each smiley face image and then calls plotSmiley to plot each one on the screen in its new location (removing it from the old location). The plotSmiley sets the onclick attribute of each image to call a dummy function just to see if the clicks are registering.
Thanks in advance.
This is not a complete answer but it could give you some perspective to improve your code.
First of all, your idea of deleting the existing img so wrong. If it does exist, all you need is to just change its position so instead of this
if (existing_smiley !== null)
// delete existing smiley so we can move it
document.getElementById("smileybox").removeChild(existing_smiley);
you should do something like this:
if (existing_smiley !== null)
var smiley_to_plot = existing_smiley;
else {
var smiley_to_plot = document.createElement('img');
smiley_to_plot.setAttribute('src', "http://i.imgur.com/C0BiXJx.png");
smiley_to_plot.setAttribute('id', sp.id);
smiley_to_plot.style.position = 'absolute';
document.getElementById("smileybox").appendChild(smiley_to_plot);
smiley_to_plot.addEventListener('click', my_click_count);
}
smiley_to_plot.style.top = sp.top_position + "px";
smiley_to_plot.style.left = sp.left_position + "px";
As you can see new image is only being added if it's not already there. Also notice that adding events by using .setAttribute('onclick', "my_click_count()"); is not a good way to do. You should use .addEventListener('click', my_click_count); like I did.
Like I said this is not a complete answer but at least this way they response to the click events now.
FIDDLE UPDATE
Good luck!

Categories