jQuery get the tager from event - javascript

I am using Hexagon.js and I need to get the .html() of the caller. If i do something like event.target and start moving with the slider, as long as the cursor is on the slider it works just fine, but if i move the cursor somewhere else (and still holding the slider, just like any other, dragging it with cursor and moving outisde of the slider box), I will get the data of that element I am currently hovering above. I need just the data of the caller, not form enyone else.
$(".slider").each(function() {
slider = new hx.Slider(this, {max:100});
slider.on('change', function(value){
var target = $( event.target );
console.log(target);
});
});
Thanks for any hep.

Without seeing the html it's a little bit hard to answer but well, according to docs you have to initialize the slider with an html element and, you do.
new hx.Slider(this, {max:100});
this in this line is the html element, so you could just use it.
Now the problem is that since you use function () {...} syntax, each function has its own this.
You may either use arrow function (they don't have their own this) as .on(...) callback (if it works ok, because sometimes it doesn't with JQuery) or save current this in a variable.
$(".slider").each(function(){
const slide = this;
const slider = new hx.Slider(
slide,
{max:100}
);
slider.on('change', function(value){
console.log(slide, `is html element!`);
console.log(value, `is the value that has just changed!`);
});
});

Related

Get coordinates out of click to work with

So, I've been trying to render some div instead of the context menu once the use user right-click anywhere on the page, and for this, I need to receive the coordinates of the click. Currently, I'm doing it like this
function printMousePos(event) {
let coordinates = [event.clientX, event.clientY];
//console.log(coordinates);
return coordinates;
}
document.addEventListener("click", printMousePos);
In the console, I got an array with x and y, but I can't work with them outside the function. I've been trying something like
let a = function (event){...}
but it doesn't seem to return the array in any case, so how could I refer to x and y? The problem is that those are dynamic and change only when the event occurs. Should I just render the menu inside of the printMousePos(event)
? Or is there any other way to get x and y?
EDIT
Thanks a lot for your answers, works for me now. I did the following - rendered the menu outside everything, hide it using CSS, and on click it changes class to visible and appears in the coordinates of the click. Goes something like
rendering the menu in window =>
rootNode.addEventListener('contextmenu', event => {
event.preventDefault();
//console.log('123');
menu.classList.add('active');
menu.style.top = `${event.clientY}px`;
menu.style.left = `${event.clientX}px`;
});
and it shows on click. So, no need to get the coordinates outside.
As Teemu said "You can't return anything from an event listener". And you don't need to.
You can either declare the coordinates array outside the event listener and fill it with data once the event fired OR (and I'd prefer that) write the function that is supposed to work with the coordinates and then call it inside the event listener (which is pretty much what you suggested yourself):
function handleClick(x,y) {
// do stuff with x and y here, like drawing a div...
}
document.addEventListener("click", function(event) {
handleClick(event.clientX, event.clientY);
});

Passing "this" to a function in jQuery problems

sorry but couldn't find a solution for my problem so far.
I am writing a kind of an email template editor as a little task for my boss.
$('a, span').click(function(event){
var editableElement = $(this);
if($(this).is('a')){
event.preventDefault();
}
if(editableElement.is('span')){
processType(editableElement, 'simpleText', modalContent)
When I send the 'editableElement' variable first time, everything's fine, sends object to my function, where I open up a modal window, where there is a textarea, which if i enter text and submit it using only jQuery it will put the text from the textarea (using .val()) to my desired element, in this case a "span" element which is the 'editableElement' using .text() on it. No problem, it works for the first time. After I try to edit a second span, it constantly modifies the previous span too, with whatever I enter in to the textarea (which is cleared out completely, the problem is NOT here) I've ran a fast debug with a simple foreach on the editable element, and the problem is that for some reason it keeps adding objects to the editableElement variable everytime I send it to the function. The number of spans I try to edit, the number of objects will be in my variable all with the index of 0.
Any idea what could be the cause of this?
Thanks in advance!
EDIT:
As requested the whole code in one piece which I have problem with, though it was the whole code before too, I'm in an early stage of writing it, I understand that it was hard to read though, perhaps now it is properly formatted as requested.
$(window).load(function()
{
var modalContent = $('#modalContent');
modalOverlay = $('#modalOverlay');
$('a, span').click(function(event)
{
var editableElement = $(this);
if($(this).is('a'))
{
event.preventDefault();
}
if(editableElement.is('span'))
{
processType(editableElement, 'simpleText', modalContent)
}
});
$('#codeGenButton').click(function()
{
var container = $('#codeContainer');
container.empty();
container.text(getPageHTML());
});
$('#modalClose').click(function()
{
$(this).parent().parent().animate({'opacity': '0'}, 200,
function(){
$(this).css({'display': 'none'});
});
});
});
function fillData(targetDomElement, modalObject)
{
$('#modalSubmit').click(function(){
targetDomElement.text($('#simpleTextEdit').val());
closeModalWindow();
});
}
function processType(targetDomElement, type, modalObject)
{
modalObject.empty();
if(type == 'simpleText')
{
modalObject.append("<p id='simpleTextEditTitle'>Text editor</p><textarea id='simpleTextEdit'></textarea>");
getModalWindow();
fillData(targetDomElement, modalObject);
}
}
Step by step of what it should do:
First of all, the html should not be needed for this, it does not matter, and this is the whole code honestly.
When you click on either an element of (span) or an element of (a) it triggers the function.
It will check if it was actually a (span), or an (a) element.
Currently if it is an element (a), it does nothing, not implemented yet, but if it is a (span), it will call in the processType function, which it sends the "handler?" of the element to namely "editableElement" which has been declared right after the click event, the 'simpleText' which gets send too, is just to differentiate between element types I will send to the processType function later on, and for the last, "modalConotent" is only a div container, nothing more.
Once the function gets the data first, it will make sure, that the modal window gets cleared of ALL data that is inside of it, then it will append a bit of html code as you can see, in to the modal window, which pops up right after I have appended data in to it, it is literally just a 'display: block' and 'animate: opacity: 1' nothing special there.
Lastly it will trigger the 'fillData' function, which will put my desired data from '#simpleTextField' which is only a (textarea) where you can write in, to my desired element 'editableElement' which is the element you have clicked at the first place, a (span) element after the submit, which is again, just a css of 'display: none' and 'opacity: 0' closes the modal window.
THE END.
Your problem is here
function fillData(targetDomElement, modalObject)
{
$('#modalSubmit').click(function(){
targetDomElement.text($('#simpleTextEdit').val());
closeModalWindow();
});
}
Each time this function is called it adds a new click handler with the perameters at the time the handler was created. This handler is added in addition to the already created handlers. See a demo here. After successive clicks on the spans notices how fillData is called multiple times for a single click.
To give you the best possible answer I need to know where your modalSubmit button is in relation to modalContent. Also is is modalSubmit dynamic or static on the page?
Here is a fairly hacky fix in the mean time using on and off to bind and remove the handler respectively:
function fillData(targetDomElement, modalObject)
{
$('#modalSubmit').off("click"); /*Clear Hanlders*/
$('#modalSubmit').on("click", function(){
console.log("fill data");
console.log(targetDomElement);
targetDomElement.text($('#simpleTextEdit').val());
/*closeModalWindow(); Don't have anything for this so ignoring it*/
});
}
Demo
I've solved it myself by using .submit() (of course this means adding form, and an input with the type of submit) instead of .click() when I send the request to modify the element I've clicked on originally.
I don't understand though, why it did what it did when I've used the .click() trigger.

jQuery UI - Slider unbinds after one use

I'm still a novice, so please go easy on me!
I'm making a JavaScript game. The game works fine, as do the basics of the user interface, like making menu selections or switching screens. But I'm also trying to implement jQuery UI sliders in one of my options menus, which is where I run into trouble.
I can only use the slider once, after which it becomes "stuck." It responds to mouseover - it'll highlight as though it's ready to scroll - but will not budge if I try to move it again.
So far, I've ruled out any problems with the build of jQuery/jQUI I'm using; the demo page works fine.
I have no idea what the problem might be, but I suspect it has something to do with the way I've put together my UI. The way my UI works is by creating a "View" object that contains pointers to a parent DOM element. I then use jQuery to construct its children and use the "loadElement" method to add it to the view's list of children elements:
function CView (parent, target, visible, jQElements) {
this.parent = parent;
this.visible = visible;
this.parentDisplay = parent.css("display");
this.parentPosition = parent.css("position");
this.elements = [];
for(element in jQElements) {
this.elements.push(element);
}
if (!this.visible) {
this.parent.css({ // Default to hidden state
"opacity": 0,
"display": "none"
});
}
this.parent.appendTo(target);
};
CView.prototype.loadElement = function(element) {
element.appendTo(this.parent);
this.elements.push(element);
return element;
};
All these elements can be shown and hidden together with a method call on the View object. Currently, hiding a view unbinds all event listeners in the elements of that view. I don't think this is the problem, since I get this problem immediately after creating a new view.
The issue, I think, might be in this code, which is for swapping views- Perhaps I'm unbinding some kind of document-level listener that jQUI uses?
var swapView = GameUI.swapView = function(view, callbacks) {
$(document).off(); // unbind key listeners
currentView && currentView.hideView(); // also unbinds event listeners
currentView = view;
view.showView(callbacks);
};
There's one more thing that might be relevant, the way I construct the slider and put it in:
var $volumeSlider = jQuery("<div/>", {
class: "options-menu-volume-slider"
});
var resetVolumeSlider = function () {
$volumeSlider.slider({
range: "min",
value: GameUI.options.volume,
min: 0,
max: 100
})
};
resetVolumeSlider();
If you need to see more code, let me know. I really am not sure what's going wrong here. Any and all help is appreciated. (Also, I don't know how to host my game online to demo it. It's basically just an HTML page that runs a bunch of JS.)
It turns out that this problem was caused by my call to $(document).off(), which I used to remove potentially dangling document-level keypress handlers. This had the unfortunate result of also destroying event handlers for jQuery UI.
In the future, my views will have keypresses bound at the parent div level with tab indices set for each div, so that I don't have to make the call to $(document).off() and can simply use hideView() to unbind.

How to toggle JQueryUI Draggable on/off in an if statement

I wrote a block of code (below) that toggles JQuery Draggable on/off on an element.
In short , when you click a div called button it toggles the draggable effect on/off on another div called dragBlock
This took me awhile but I finally got it working. The question I have is I don't understand why the code below doesn't work with only one Draggable instance. Mainly the one that uses the state argument.
$(dragBlock ).draggable(state);
Instead it only works when I use this:
$(dragBlock ).draggable(state);
$(dragBlock ).draggable(); // This line is needed for the code to work. Why?
This isn't a big issue but I would like to know why this is and I figure someone here might be able to explain it. JSfiddle is here:
And the code is below:
$(document).ready(function() {
var state = "disable";
var button = document.getElementById("button");
var dragBlock = document.getElementById("dragBlock");
var toggle = function() {
if (state==="enable") {
state = "disable";
}
else if(state==="disable") {
state = "enable";
}
$(dragBlock ).draggable(state);
$(dragBlock ).draggable(); // This line is needed for the code to work. Why?
console.log(state);
};
button.addEventListener("click", toggle, false);
});
You should really have the .draggable() outside the event handler, and only the .draggable(state) inside.
Calling .draggable() is how you initially setup the draggable functionality on the element.
Calling .draggable('enable') or .draggable('disable') is a way to enable or disable an already-configured draggable element. It's a way to interact with a draggable element that you've already setup.
Note though, that by calling draggable() outside the event handler your default initial state will now be enabled. You need to either disable it immediately or change your initial value for the state variable.
You can initialize the draggable and leave it disabled with this (outside the event handler)
('#dragBlock').draggable({disabled: true});
And then you'll only need the .draggable(state) inside the event handler.

jQuery draggable item is changing the href of the page when dropped into "trash"

I have a pretty simple jQuery draggable/sortable/droppable combination going on where I'm sorting several divs, each of which contain an image wrapped in an anchor element with an href.
The problem is, when I drag a sortable item to the "trash" droppable area (to destroy it), the page sometimes changes its location and goes to the href URL from within the draggable!
I have debugged the hell out of the page and it is not any of my code causing this. The drop event happens normally and returns (I've tried returning true and false) just fine. It's something in jQuery UI's code causing the href to be fired.
It doesn't happen every time. I'm not "clicking" the element - just dragging.
Can anyone offer a suggestion please?
Example of my droppable code:
var trash = this._area_trash.droppable({
drop: this.eventtrashDrop,
hoverClass: 'highlight'
});
// ...
this.eventtrashDrop = function(event,ui) {
var o = ui.draggable;
if( typeof(o)=='object' && o!=null ) {
if( o.parents(obj._selector_stack_area).length>0 ) {
var id = parseInt(o.attr('lang'));
o.remove();
obj.eventStateRemove(id);
}
}
// Page location hasn't been changed yet!
return true;
}
EDIT: the original issue still remains, and I suspect it's some kind of bug in jQuery UI. However a workaround is to replace the anchor element with a div before destroying the sortable item so it can't change to the anchor's href:
var anchor = jQuery(o).find("a");
var img = jQuery(anchor).html();
jQuery(anchor).replaceWith("<div/>").html(img);
Sounds to me like the anchor is being triggered on the click.
You need to listen for event and prevent the default action.
Something like this:
$('a').click(function(event){
event.preventDefault();
});

Categories