All,
I have a circle that I drag and drop from the upper div to the bottom div. Please see fiddle. After I click the circle in the bottom I then try to change the height with the input button. The input button is between the top and bottom div and uses incremental values of 5.
However, my event handler doesn't change the height value after incrementing from 5 to 10.
My goal is to allow changing of a height especially after I dropped a circle in the bottom and div and after selecting the circle to simulate activation.
Is there something wrong with how I'm trying to associate the event handler to the circle and the input button?
https://jsfiddle.net/mdevera/ff1bfpsd/
destinationContainer.addEventListener("click", change);
function change(event) {
activeShape = event.srcElement;
}
function changeHeight(event) {
//var height = (parseInt(activeShape.clientHeight, 10) + parseInt(event.target.value, 10)) + "px";
activeShape.style.height = event.target.value + "px";
}
The problem is that your click event listener for the #destination element only calls the change function when it is clicked. In other words, the change function isn't fired when you drag/drop the element since there aren't any click events fired. As a result, the activeShape variable defined in the change function doesn't point to an element since the change function is never called.
Another approach would be to select the last child element of the #destination element using the :last-child pseudo class. The last child is always the last element appended which means that you would always target the most recently dropped element when changing the height.
Updated Example
function changeHeight(event) {
var activeShape = destinationContainer.querySelector(':last-child');
if (activeShape !== null) {
activeShape.style.height = event.target.value + "px";
}
}
After reading your comment:
In addition to the changes above, it also seems like you are looking for the input event rather than the change event. The input event is fired fired synchronously when the value of the element is changed, whereas the change event is fired on blur (which is when focus is removed from that field).
Updated Example
var destinationContainer = document.querySelector("#destination");
var input = document.querySelector('#height-input');
input.addEventListener('input', function (event) {
var activeShape = destinationContainer.querySelector(':last-child');
if (activeShape !== null) {
activeShape.style.height = event.target.value + "px";
}
});
It looks unusual, but you should move out of input after changes made or use keys up/down to "catch up" input changes. In general it's some kind of onblur needed. In modern browser oninput event is preferable one for such cases.
onchange - only after focus out
oninput - the same as onchange but do not need blur focus
onpropertychange -
Just change onchange in your HTML to oninput and your problem will be resolved.
Related
I have found many similar questions and answers like mine. Unfortunatly, I have tried to adapt those answers to fit my problem but I cannot make it work. I am making a drawing pad application. The drawing pad is made of a container full of divs. I want the color to change only when mousedown and mouseover are both true. basically, I want to click and drag my drawing lines. Im probably way out to lunch here but I am at my whits end trying things.
let boxes = document.getElementsByClassName("grid-item");
let isClicked = false;
let isHover = false;
for (box of boxes) {
box.addEventListener("mousedown", () => isClicked = true);
}
for (box of boxes) {
box.addEventListener("mouseover", () => isHover = true);
}
function draw() {
if (isClicked == true && isHover == true) {
box.target.style.background_color = "black";
}
}
Instead of trying to manage and track global variables, you can use the event object passed. In my example, I have a function which can make the event target black, by changing the background color. I did use the style.backgroundColor because style.background-color is incorrect for js. If the mousedown event is triggered, you can safely assume the cursor is over the element. The mouseover event does not always make the target black. Instead, I check the event property .buttons which will be 1 if the left mousebutton is pressed, and 0 if not. This way, I can verify if it is clicked, then we just pass the event along to our make black function.
It is possible to solve this problem by tracking global variables, however you would need to be doing a lot of "state managing" which can quickly become messy and complex. You would need a mouseout function that turns the isHover off, as well as a mouseup function that turns the isClick off. You would probably need some debouncing in case the mouseout or mouseup event didn't trigger due to a right click or the cursor being in a different position. Then you would also need to track which element isHover and isClick which is redundant in this case because we can just check the event object from our mouseover event.
const boxes = [...document.getElementsByClassName("grid-item")];
const makeBlack = event => event.target.style.backgroundColor = "black";
function equip(box) {
box.addEventListener("mousedown", makeBlack);
box.addEventListener("mouseover", event => {
if (event.buttons == 1) makeBlack(event);
});
}
boxes.forEach(equip);
I'm trying to make a simple plugin to be able to make a div draggable. Of course a div can have a content inside (typically a form) and it should be dragged with it.
Here is a prototype: http://jsfiddle.net/Xcb8d/539/
The problem is that the texbox inside this div never gets focus, so I cannot type in it:
<div id="draggable-element">Drag me!
<form>
<input type="text" style="width:50px;"/>
<button>ok</button><br><br>
<input type="checkbox">check it</input>
</form>
</div>
As you can see, this does not happen to other elements on the form. Checkbox can be regularily used, as well as the button.
In addition, I would like only the grey coloured area to be draggable, and not the inner elements. On this example, you can place the mouse cursor fully inside the textbox and start the drag of the whole parent div.
the onmousedown handler on the draggable element return false and there by stopping event propagation, allowing it will make the input focus-able and the dragging still works. (at least on chromium)
document.getElementById('draggable-element').onmousedown = function (e) {
// memorize the offset to keep is constant during drag!
x_offset = e.clientX - x_elem;
y_offset = e.clientY - y_elem;
_drag_init(this);
return true;
};
In your onmousedown handler you end with a return false. This prevents the click event from happening when you click on the input, and thus it never gets focus. What I think you are looking for is this:
// Bind the functions...
document.getElementById('draggable-element').onmousedown = function (e) {
if (e.id == 'draggable-element') {
// memorize the offset to keep is constant during drag!
x_offset = e.clientX - x_elem;
y_offset = e.clientY - y_elem;
_drag_init(this);
return false;
}
};
paradoxix's answer was correct in stating that the return falseon the mousedown event is preventing the propagation of all other events.
On any element listening to the mousedown event you won't have any problems, because the event happens for them first, and only after for the box itself. But the input listens to the focusevent, which never happens due to the return false in the box's event.
The solution is to prevent onmousedown from bubbling from the child elements into the box, like so:
var nodes = document.getElementById('draggable-element').childNodes;
for(var i=0; i<nodes.length; i++) {
nodes[i].onmousedown = function(e) {
e.stopPropagation();
}
}
Working fiddle: http://jsfiddle.net/Xcb8d/546/
I am implementing drag'n'drop functionality on the page. The idea is that user can start dragging image from special place and drop it (release left mouse button) inside textarea, where special tag insertion will occur.
I have no issues with the dragging itself, the problem I got is that I can't determine position of the mouse inside textarea. I know x and y positions from mouseup event and I definetely know the mouse pointer is inside textarea, but can't determine at which position do I need to insert the required tag. Since the focus is not inside the textarea, selectionStart and selectionEnd properties are 0. Also, it is worth noticing that I prevent default behavior by returning false in mousemove handler - otherwise default behavior will put the image itself inside the textarea (which is extremely bad for base64 images).
Below is the code I currently have.
window.onPreviewItemMouseDown = function (e) {
var curTarget = $(e.currentTarget);
var container = curTarget.parent();
window.draggingImage = funcToGetId();
$(document).on("mousemove", window.onPreviewItemDragged);
$(document).on("mouseup", window.onPreviewItemDropped);
};
window.onPreviewItemDragged = function (e) {
return false;
};
window.onPreviewItemDropped = function (e) {
var target = $(e.target);
$(document).off("mousemove");
$(document).off("mouseup");
if (target[0].id === ID_TEXTAREA_TEXT) {
// here I need to get mouse pointer position inside the text somehow
}
return false;
};
Any help is appreciated.
In your case it would be easier to use native ondragstart event instead of a complex mousedown-move-up implementation, and manipulate the data to drop. Something like this:
document.getElementById('img').addEventListener('dragstart', function (e) {
e.dataTransfer.setData("text", '[img]' + this.id + '[/img]');
});
A live demo at jsFiddle. Or a delegated version. Notice that you can also delegate to the "special place" element, which might make the page running a little bit faster.
Here is the JSFiddle.
I have two events here.
Is game.input.onDown which does some logic (generates particles in my example)
Is textButton.events.onInputDown, where textButton is a Phaser.Text object instance, which does another logic.
The problem is: when I click on my textButton both event are fired 1 and 2.
The question is, how to prevent event 1 from firing when I click on the textButton?
Part of code:
...
//This event is fired on click anywhere event # 1
game.input.onDown.add(particleBurst, this);
//This is Clickable text
textButton = game.add.text(game.world.width - 5, 5, "CLICK ME", fontStyle);
textButton.anchor.setTo(1, 0);
textButton.inputEnabled = true;
//This event is fired on click on text event # 2
textButton.events.onInputDown.add(function () {
console.log("button is Clicked");
}, this, 2);
...
You can add a background - transparent sprite - and use input.priorityID.
The priorityID is used to determine which game objects should get
priority when input events occur. For example if you have several
Sprites that overlap, by default the one at the top of the display
list is given priority for input events. You can stop this from
happening by controlling the priorityID value. The higher the value,
the more important they are considered to the Input events.
See: http://docs.phaser.io/InputHandler.js.html#sunlight-1-line-45
// This is event #1 added to background sprite
var bg = game.add.sprite(0, 0);
bg.fixedToCamera = true;
bg.scale.setTo(game.width, game.height);
bg.inputEnabled = true;
bg.input.priorityID = 0; // lower priority
bg.events.onInputDown.add(particleBurst);
Make sure your textButton has higher priority:
textButton.input.priorityID = 1; // higher pirority
Add the clicked sprite (our background) as a first parameter to the particle function:
function particleBurst(bg, pointer) {
This way only one event should be triggered.
Check out modified fiddle: http://jsfiddle.net/g05bbL6g/3/
I have the following html code:
<input type="text" id="theInput" value=""/>
Click me
I want to detect when the input changes and perform an operation in this case, but ONLY when the user has not clicked in the link. I have tried this:
$('#theLink').live('click', function(){
alert('click');
});
$('#theInput').live('change', function(){
alert('change');
});
However change is always executed before click when the value in the input changed, due to Javascript event precedence rules, and therefore only "change" message is displayed.
I would like it to display change only if the input value changed and the user exited the input clicking in any other place instead of the link. In that last case I would like to display click.
The example is here.
I use jQuery 1.6.4.
As far as I know, the click event fires after the blur and change events in every browser (have a look at this JSFiddle). The order of blur and change is different across browsers (source: Nicholas Zakas).
To solve your problem, you could listen to click events on the document and compare the event's target with #theLink. Any click event will bubble up to the document (unless it is prevented).
Try this:
var lastValue = '';
$(document).click(function(event) {
var newValue = $('#theInput').val();
if ($(event.target).is('#theLink')) {
// The link was clicked
} else if (newValue !== lastValue) {
// Something else was clicked & input has changed
} else {
// Something else was clicked but input didn't change
}
lastValue = newValue;
});
JSFiddle: http://jsfiddle.net/PPvG/TTwEG/
Both events will fire but in your example the alert in the onchange event handler fired when the onmousedown event occurs will stop the onmouseup event required for the onclick event to fire. Using console.log will show both events firing.
http://jsfiddle.net/hTqNr/4/
Ok, now i got it, you could do
$('#theLink').live('click', function(e){
alert('click');
});
$('#theInput').live('change', function(e){
//Check if the change events is triggerede by the link
if(e.originalEvent.explicitOriginalTarget.data === "Click me"){
//if this is the case trigger the click event of the link
$('#theLink').trigger("click");
}else{
//otherwise do what you would do in the change handler
alert('change');
}
});
Fiddle here http://jsfiddle.net/hTqNr/19/
why you dont pick the value of input box. you have to store initial value of input box on ready function
initialvalue= $('#theInput').val();
then compare the value
$('#theLink').live('click', function(){
var newvalue =$('#theInput').val();
if(newvalue!=initialvalue) {
//do something
}
});