Javascript event handler with parameter - javascript

I'm trying to set the onmousemove event for an svg element. The code below works in chrome, but in firefox it is not setting the onmousemove property correctly every time. After the 2nd change it gets messed up.
mysvg.setAttribute('onmousemove','window.updateXY(evt,' + that.chartNumber + ')');
mysvg is still the correct svg element according to firebug: svg#chart0
the svg property onmousemove says function(e) instead of onmousemove(evt) when it gets messed up, but no error is reported in firebug
Edited to show more code:
var YAxis = function(mysvg,chartNumber){
this.chartNumber = chartNumber;
var that = this;
var g = document.createElementNS(xmlns, "g");
this.id = 'YAxis' + chartNumber;
g.id = this.id;
mysvg.appendChild(g);
var shift = false;
this.selected = false;
this.yScale = function(e){
e.stopPropagation();
that.origY = e.pageY;
that.shift = e.ctrlKey;
mysvg.onmousemove = that.dragY;
mysvg.onmouseup = that.dropY;
}
this.dragY = function(e) {
var chart = charts[that.chartNumber];
if(chart.log)
displayXYText.innerHTML = 'range: ' + Math.round(Math.pow(10,chart.max*(1 + (e.pageY - that.origY)/(chart.height)))*100)/100 + '-' + Math.round(Math.pow(10,chart.min*(1 - (e.pageY - that.origY)/(chart.height)))*100)/100;
else
displayXYText.innerHTML = 'range: ' + Math.round(chart.max*(1 + (e.pageY - that.origY)/(chart.height))*100)/100 + '-' + Math.round(chart.min*(1 - (e.pageY - that.origY)/(chart.height))*100)/100;
}
this.dropY = function(e) {
var chart = charts[that.chartNumber];
if(that.shift){
var range = (chart.max - chart.min)*Math.round((e.pageY - that.origY)/(chart.height)*1000)/1000;
chart.max += range;
chart.min += range;
}else{
var range = chart.max - chart.min;
chart.max *= 1 + Math.round((e.pageY - that.origY)/(chart.height)*1000)/1000;
chart.min *= 1 - Math.round((e.pageY - that.origY)/(chart.height)*1000)/1000;
if(chart.max <= chart.min){
chart.max = chart.min + range;
}
}
mysvg.setAttribute('onmousemove','window.updateXY(event,' + that.chartNumber + ')');
//mysvg.onmousemove = updateXY(e,that.chartNumber);//function() { updateXY(e,that.chartNumber)}; //set back to orig function
//mysvg.setAttribute('onmousemove','updateXY(evt,' + that.chartNumber + ')');
//console.debug(mysvg.onmousemove.textContent);
mysvg.setAttribute('onmouseup','window.mouseUp(event)');
//console.debug("got here onmousemove");
chart.redraw();
}
}

I tried all the methods above but none worked properly in firefox. The solution was to not pass any parameters other than event to the updateXY function. When the other parameters were undefined, run separate logic to determine what the parameters should be in that case. Once the code is in the window frame, you can use setAttribute like you normally do. #FirefoxOOPfail

Related

Jquery change color of SVG element using jscolor.js is failing

I have a web page in which SVG is embedded. I am pulling references of elements of SVG and creating color swatches for every element using jscolor.js library.
I want to adjust color of these elements using swatches I am dynamically creating on click jquery event listener.
The problem is, after couple of changes SVG element is becoming black due to some error which is assigning 'undefined' fill color to this SVG element.
I am not getting why it not working all the time.
The main function to do this job is as follows
$("#svg_obj").on("click", ".badge", function(event) {
event.stopPropagation();
var rect = event.target.getBoundingClientRect();
$(".badge").attr('selection', null);
this.setAttribute('selection', true);
var svg_left = ((Math.round(this.getAttribute('width')) - Math.round(this.getBoundingClientRect().width)) / 2);
$(".selector").css("left", Math.round(this.getBoundingClientRect().x - svg_left) + 'px')
$(".selector").css("top", Math.round(this.getBoundingClientRect().y) + 'px')
$(".selector").css("width", Math.round(this.getAttribute('width')) + 'px');
$(".selector").css("height", Math.round(this.getAttribute('height')) + 'px');
$(".selector").css("visibility", "visible");
for (let i = 0; i < this.childNodes.length; i++) {
var svg_g = this.childNodes[i];
// console.log(this.childNodes[i].nodeName);
if (svg_g.nodeName == 'g') {
var polygons = Array.from(svg_g.querySelectorAll("polygon"));
var polygons = polygons.concat(Array.from(svg_g.querySelectorAll("path")));
// console.log(polygons);
Object.values(polygons).forEach(val => {
// console.log(val.attributes.fill.value.substring(1));
console.log(val);
$("#status_bar").append("<p class='swatches " + val.attributes.fill.value.substring(1) + "' >Color:<input data-jscolor='{position:"right"}' value='" + val.attributes.fill.value + "'></p>").on('change', '.' + val.attributes.fill.value.substring(1), function() {
val.attributes.fill.value = $('#status_bar .' + val.attributes.fill.value.substring(1)).find('input').val();
console.log($('.' + val.attributes.fill.value.substring(1)).find('input').val());
});
});
} else {
// console.log("Not a group " +svg_g);
}
}
jscolor.install();
});
jsfiddle for working code
Could you please help to fix this issue?
Thanks

Extending Touch EventListener to Additional DOM Element

I used a Codrops article/experiment to create an interactive environment for a local group to use at their conferences. The problem with this is the default interaction is not very intuitive. The template used Flickity.js and what seems like classie.js to create this sliding interface I am having trouble with.
The page can be found here:
www.eyeconic.tv/ky-ffa/
Issue: The only way to activate the view-full is by clicking on the html element:
<h2 class=".stack-title">
// After the stack is active you should be able to activate the full view by clicking on the first .stack-item used to create the thumbnail below it. This entire div should be clickable. Users are touching everywhere all over the screen and not actually clicking the title for the desired action. I hope this makes sense.
In other words you should be able to click the stack-title and the image below the title of each stack to pull the stack into the full view mode on the screen. Then click the x or anywhere else on the screen to close the full view.
The following is located in main.js and the reference I found to create the events I am referring to.
//
function initEvents() {
stacks.forEach(function(stack) {
var titleEl = stack.querySelector('.stack-title');
// expand/close the stack
titleEl.addEventListener('click', function(ev) {
ev.preventDefault();
if( classie.has(stack, 'is-selected') ) { // current stack
if( classie.has(bodyEl, 'view-full') ) { // stack is opened
var closeStack = function() {
classie.remove(bodyEl, 'move-items');
onEndTransition(slider, function() {
classie.remove(bodyEl, 'view-full');
bodyEl.style.height = '';
flkty.bindDrag();
flkty.options.accessibility = true;
canMoveHeroImage = true;
});
};
// if the user scrolled down, let's first scroll all up before closing the stack.
var scrolled = scrollY();
if( scrolled > 0 ) {
smooth_scroll_to(isFirefox ? docElem : bodyEl || docElem, 0, 500).then(function() {
closeStack();
});
}
else {
closeStack();
}
}
else if( canOpen ) { // stack is closed
canMoveHeroImage = false;
classie.add(bodyEl, 'view-full');
setTimeout(function() { classie.add(bodyEl, 'move-items'); }, 25);
bodyEl.style.height = stack.offsetHeight + 'px';
flkty.unbindDrag();
flkty.options.accessibility = false;
}
}
else if( classie.has(stack, 'stack-prev') ) {
flkty.previous(true);
}
else if( classie.has(stack, 'stack-next') ) {
flkty.next(true);
}
});
titleEl.addEventListener('mouseenter', function(ev) {
if( classie.has(stack, 'is-selected') ) {
canMoveHeroImage = false;
imghero.style.WebkitTransform = 'perspective(1000px) translate3d(0,0,0) rotate3d(1,1,1,0deg)';
imghero.style.transform = 'perspective(1000px) translate3d(0,0,0) rotate3d(1,1,1,0deg)';
}
});
titleEl.addEventListener('mouseleave', function(ev) {
// if current stack and it's not opened..
if( classie.has(stack, 'is-selected') && !classie.has(bodyEl, 'view-full') ) {
canMoveHeroImage = true;
}
});
});
window.addEventListener('mousemove', throttle(function(ev) {
if( !canMoveHeroImage ) return false;
var xVal = -1/(win.height/2)*ev.clientY + 1,
yVal = 1/(win.width/2)*ev.clientX - 1,
transX = 20/(win.width)*ev.clientX - 10,
transY = 20/(win.height)*ev.clientY - 10,
transZ = 100/(win.height)*ev.clientY - 50;
imghero.style.WebkitTransform = 'perspective(1000px) translate3d(' + transX + 'px,' + transY + 'px,' + transZ + 'px) rotate3d(' + xVal + ',' + yVal + ',0,2deg)';
imghero.style.transform = 'perspective(1000px) translate3d(' + transX + 'px,' + transY + 'px,' + transZ + 'px) rotate3d(' + xVal + ',' + yVal + ',0,2deg)';
}, 100));
// window resize
window.addEventListener( 'resize', throttle(function(ev) {
// recalculate window width/height
win = { width: window.innerWidth, height: window.innerHeight };
// reset body height if stack is opened
if( classie.has(bodyEl, 'view-full') ) { // stack is opened
bodyEl.style.height = stacks[flkty.selectedIndex].offsetHeight + 'px';
}
}, 50));
// Flickity events:
flkty.on('cellSelect', function() {
canOpen = false;
classie.remove(bodyEl, 'item-clickable');
var prevStack = stacksWrapper.querySelector('.stack-prev'),
nextStack = stacksWrapper.querySelector('.stack-next'),
selidx = flkty.selectedIndex,
cellsCount = flkty.cells.length,
previdx = selidx > 0 ? selidx - 1 : cellsCount - 1;
nextidx = selidx < cellsCount - 1 ? selidx + 1 : 0;
if( prevStack ) {
classie.remove(prevStack, 'stack-prev');
}
if( nextStack ) {
classie.remove(nextStack, 'stack-next');
}
classie.add(stacks[previdx], 'stack-prev');
classie.add(stacks[nextidx], 'stack-next');
});
flkty.on('dragStart', function() {
canOpen = false;
classie.remove(bodyEl, 'item-clickable');
});
flkty.on('settle', function() {
classie.add(bodyEl, 'item-clickable');
canOpen = true;
});
}
init();
})();
I wrapped the title and the first stack item in a div class .touch-me and it worked fairly well. I had previously tried to do this and received an error. But I may have mistyped something because it only made sense.
ISSUE: It works on mouseclick, but it is not working with touch on windows. I have untested it in any other environment because it will be deployed on a windows touch screen.
Although I cannot tell the layer not to close on touch when you swipe or touch the header image for the stack.... I'm afraid I do not have the skillset to properly modify the logic in the javascript since I do not entirely understand the plugins being used.

Why i am getting multiple element appended while clicking the button?

I just adding a span as parent of text selection. i do 2 ways one using clicking on button another on by pop-up button (on select will appear)
When i click the pop-up button multiple times, i am getting appended as much of (multiple times) spans as parent of my selection.
how to fix this? any one help me?
myjs:
function selHTML() {
var nNd = document.createElement("span");
var w = getSelection().getRangeAt(0);
w.surroundContents(nNd);
$(nNd).addClass('highlight');
}
$("#addText").on('click', function(event) {
event.preventDefault();
$(selHTML());
});
$("div.content").mouseup(function(event) {
var range = window.getSelection().getRangeAt(0);
if (!range.collapsed) {
var bounds = range.getBoundingClientRect();
var x = bounds.left + ((bounds.right - bounds.left - $(".savetooltipAll").outerWidth()) / 2);
var y = bounds.top - $(".savetooltipAll").outerHeight() + $(window).scrollTop();
$(".savetooltipAll").css("top", (y+(bounds.top)) + 'px');
$(".savetooltipAll").css("left",x + 'px');
$(".savetooltipAll").show();
$("button").click(function(){
$(selHTML()); //it calls multiple times...
});
} else {
$(".savetooltipAll").hide();
}
});
$("div.content").mousedown(function(event) {
var range = window.getSelection();
console.log(range.type);
});
Live Demo
You're (re)registering the .click handler every time the .mouseup handler is invoked.
Just do it once, outside of the handler.
Aldo, don't write $() around the call to selHTML() - it's invoking jQuery but will have no effect has you're discarding the result.
$("button").on('click', function(){
selHTML(); //it won't call multiple times... :)
});
$("div.content").mouseup(function(event) {
var range = window.getSelection().getRangeAt(0);
if (!range.collapsed) {
var bounds = range.getBoundingClientRect();
var x = bounds.left + ((bounds.right - bounds.left - $(".savetooltipAll").outerWidth()) / 2);
var y = bounds.top - $(".savetooltipAll").outerHeight() + $(window).scrollTop();
$(".savetooltipAll").css("top", (y+(bounds.top)) + 'px');
$(".savetooltipAll").css("left",x + 'px');
$(".savetooltipAll").show();
} else {
$(".savetooltipAll").hide();
}
});

SCRIPT438: Object doesn't support this property or method script2.js, line 92 character 5

Popups work in Firefox and Safari but not in Internet Explorer 9. Using the Dev Tools in Internet Explorer 9, I get the following error (occurs in the function openPopUp).
SCRIPT438: Object doesn't support this property or method
script2.js, line 92 character 5
Here is <script2.js>
var popup_content_cache = '';
var popup_content_src_id = '';
jQuery.fn.center = function () {
console.log("*****NEW******");
this.css("position", "absolute");
this.css("top", (($(window).height() - this.outerHeight()) / 2) +
$(window).scrollTop() + "px");
this.css("left", (($(window).width() - this.outerWidth()) / 2) +
$(window).scrollLeft() + "px");
console.log(this.css('top'));
console.log(parseInt(this.css('top')));
if (parseInt(this.css('top')) < 0) this.css('top', '20px');
console.log(parseInt(this.css('top')));
return this;/*
this.css("position","absolute");
var top=($(window).height() - this.outerHeight())/2;
console.log("top: " + top)
console.log($(window).height());
console.log(this.outerHeight());
if(top<0){
console.log("** IF");
this.css("top", "20px");
this.css("left", (($(window).width() - this.outerWidth()) / 2) + $(window).scrollLeft() + "px");
}
else {
this.css("top", (($(window).height() - this.outerHeight()) / 2) +
$(window).scrollTop() + "px");
this.css("left", (($(window).width() - this.outerWidth()) / 2) +
$(window).scrollLeft() + "px");
}
console.log();
return this;*/
}
function openLayerBC() {
tWidth = $(document).width();
tHeight = $(document).height();
//$("select").fadeOut('fast');
$('#filter').css("width", tWidth + "px");
$('#filter').css("height", tHeight + "px");
// $('#filter').css('z-index',9990);
$("#filter").css("opacity", 0.8);
$('#filter').fadeIn('fast');
//$('#filter').bind("click",closePopup1);
$('#filter,#close').click(function () {
$('#filter').fadeOut('fast');
$('#case_light_box').hide();
o = document.getElementById('divid');
o.style.display = o.style.display === 'block' ? 'none' : 'block';
});
}
function closePopup() {
$('#filter').fadeOut('fast');
o = document.getElementById('popup');
o.style.display = 'none';
// o.style.display = o.style.display=='block'?'none':'block';
$(o).css("position","absolute");
$(popup_content_src_id).html(popup_content_cache);
var popup_content_cache = '';
var popup_content_src_id = '';
}
function openPopUp(div) {
openLayerBC();
div = div.replace('#', '');
file = div;
page = '/v/vspfiles/templates/OSS/ajax/products/' + div + '.html';
$.get(page, {}, function(data)
{
msgbox = document.getElementById('popup');
$(msgbox).html(data);
$(msgbox).css('width',$('#'+div).css('width'));
$('#'+div).show();
$(msgbox).center();
$(msgbox).show();
});
}
This following is the line 92 of <script2.js> the message refers to.
page = '/v/vspfiles/templates/OSS/ajax/products/'+div+'.html';
Disclaimer: I inherited this JavaScript code and have little experience myself with JavaScript and its syntax.
Try adding 'var' before 'page':
var page = '/v/vspfiles/templates/OSS/ajax/products/'+div+'.html';
page looks like it might be undefined. Also, it's possible that div or page are not strings. You can open a developer console, put a debugger; statement before the error, and inspect the div and page variables before the error is thrown to narrow it down.

Change mousedown focus to a new div

So here's my code:
function drawGridSquare(tableText)
{
gridSquare = document.getElementById('square');
gridSquare.innerHTML = tableText;
document.body.appendChild(gridSquare);
gridSquare.style.display = 'block';
gridSquare.style.top = e.pageY - gridSquare.offsetHeight + 1;
gridSquare.style.left = e.pageX - gridSquare.offsetWidth/2;
gridSquare.focus();
}
This function is called on mousedown from a td element:
<td onmousedown="drawGridSquare('textData');">
This generates a pretty little square which uses jQuery draggable/droppable function. All I want to do is while the user's mouse is STILL pressed down, the focus would revert to the gridSquare that was created.
What are my options for this?
Seeing as how I couldn't find a clear way to do this, my work around is as follows:
function drawGridSquare(tableText, cellPosition)
{
gridSquare = document.getElementById('square');
gridSquare.innerHTML = tableText;
document.body.appendChild(gridSquare);
gridSquare.style.display = 'block';
startPositionX = endPositionX = cellPosition;
gridSquare.style.top = mouseY(event) - gridSquare.offsetHeight + 1;
gridSquare.style.left = mouseX(event) - gridSquare.offsetWidth/2;
squareReady = true;
}
function moveGridSquare()
{
if (squareReady)
{
squareIsMoving = true;
characterWidth = 1;
gridSquare = document.getElementById('square');
gridSquare.style.top = mouseY(event) - gridSquare.offsetHeight + 1;
gridSquare.style.left = mouseX(event) - gridSquare.offsetWidth/2;
}
}
function selectionEnd() {
if (squareIsMoving)
{
//Code to DROP INTO THE GRID
var dataStart = (Math.round((startPositionX) / characterWidth)) + 1;
var dataLength = Math.abs((Math.round((endPositionX)/characterWidth)) - (Math.round((startPositionX) / characterWidth)));
var data = dataStart + "," + dataLength + "," + theSelectedText;
dropDone(data);
//Set square to false
squareIsMoving = false;
squareReady=false;
//Destroy the square
document.getElementById('square').innerHTML = "";
document.getElementById('square').style.display = 'none';
}
}
<body onmousemove="moveGridSquare();">
<div id="square" onmousedown="squareReady=true;moveTheSquare();" onmouseup="selectionEnd();" style="display:none;" ></div>

Categories