Div Resize Event not working - javascript

I have a tree that expands and collapses, whenever the container div changes sizes i want to do some other stuff, however the .resize() doesn't seem to be working as i wish.
I have the code posted on jsfiddle below:
http://jsfiddle.net/2nXtu/
Thanks

resize() is an event for the resizing of the browser window.
Just put the status updater inside the duplication click event:
$('.dup').live('click', function(){
var clone = $(this).clone();
$(this).parent().append( clone );
$('.height').html( $('.content-body').height() );
$('.status').html('Resizing');
});
Here it is in action.

One way I did this is using a dirty-checking technique.
Basically you check the size of the div you want to monitor the first time, then register a function that runs on a specified interval (say 500ms) and checks for the div size again. If the size has changed from the one you had before you trig some event or run some function and store the new size. It works well if you create efficient closures around your variables.

Related

Bind to offsetHeight of the <body> from inside a Svelte component

I'm trying to bind to the total (scrolling) height of the body element inside of a Svelte component such that I can calculate the scroll position in an interval between zero and one. This allows for some cool scroll-triggered CSS animations. The value I'm looking for is stored in the body.offsetHeight property.
My first impluse was to bind the property directly using the <svelte:body> element.
<script>
let h;
</script>
<svelte:body bind:offsetHeight={h}></svelte:body>
<span class="debug">{h}</span>
In this example h will remain undefined even if the window is resized.
The documentation mentions that the <svelte:...> elements are primariliy intended to bind event listeners to them. With this in mind, I tried to bind the resize event and getting the sizes from there, together with the initial value of body.offsetHeight in the onMount callback.
<script>
const handleResize = () => { console.log("yay"); };
</script>
<svelte:body on:resize={handleResize}></svelte:body>
Once again, the handleResize function is not called when the body is resized.
Is there a way to idiomatically solve this problem in Svelte?
Is it safe to just bind to the body's resize event manually in on-mount and updating values from there?
Thanks for taking the time to read this question!
You can set on:resize on the window element itself instead
<svelte:window on:resize={handleResize}></svelte:window>
Alternatively, you might be able to get the same information of from the window as well? There the bindings work smoothly.

Add a resize event handler only once

I have a widget that insert a div element in the DOM;
that div needs some js that handles the resize event;
the problem is:
the widget can be added multiple times on the same page, but I don't wanto to add many identical resize event handlers on the page (one, acting on the specific widget's class will be enough for all the widget instances);
the page that will embeed the widget can have its own resize event handler, that should not be deleted;
do you have any suggestion about how to implement this?
Honestly, I didn't get most of workflow explained as you didn't provide any html and js but I hope the following works for you:
var resized = 0; // works as a flag
$( window ).on('resize', function () {
if ( resized++ >= 1 ) return;
// do something here..
console.log('resized once'); // console.log as an example!
});
Good luck.

How can I detect when a certain DIV has changed size without polling? I.e., I want a resize event listener?

So I am running ads on a website that I have and one of the ads periodically changes the dimensions of the DIV that it is in -- it grows and shrinks and shows bouncing things and flashing lights and sparkles, etc. This is fantastic and I love it.
One problem, however, is that the layout of other elements on my page is screwed up when this happens.
This is no big deal though -- all I have to do is add an event listener to the DIV element in question and listen for resizing events. When they occur, I will run a callback function that will adjust the layout of the other elements of my site.
My problem is that the resize event listener is only available for the window object itself, not for other elements in the DOM. How can I listen for resizing events on a particular DIV without polling?
I would like to do something like:
$('my-div-id').on('resize', function() {
do_things();
adjust_layout();
etc();
});
You could use a window.setInterval, that checks every x ms if the element in question has changed size:
var ElementSize = $("#element").width();
window.setInterval(function(){
if( $("#element").width() != ElementSize )
{
ElementSize = $("#element").width();
redolayout();
}
}, 50);
function redolayout()
{
// Add code here to resize other elements according to the change.
}
Another option: https://github.com/sdecima/javascript-detect-element-resize

Resizing multiple images via jquery one at a time

So I am writing some jquery that is basically meant to resize any image when I click on it, meaning I can click on one image and resize it, and then click on any other image and start resizing it as well, but idependently. The code I have to do this is as follows:
$('img').click(function(e) {
thisImage = this;
$(document).keypress(function(event) {
if ( event.which == 115) {
$(thisImage).css('width', "+=25").css('height', "+=25");
};
if ( event.which == 97) {
$(thisImage).css('width', "-=25").css('height', "-=25");
};
});
});
This works fine the first time you use it. You can click on an image when there is more than one image present and the image that you clicked on will resize appropriately when you hit the appropriate buttons. Upon clicking the second image to resize it, however, both it and the first image you clicked will start resizing together. This scales with as many images as you can put on the page, i.e., three images will resize together after each has been clicked on.
Does anyone know why this is happening and how I can stop it? I would like to be able to click each image and be able to resize it independently, no matter the order it was clicked on. I have a feeling this has something to do with the way I am using "this," but I am relatively new to jquery and javascript so I cannot think what it would be.
Any help would be appreciated. Thanks!
-Alex
Essentially the issue here is that each time you click an image, you are binding a new listener to the document.
This means that every time you press a key, you invoke all of the listeners that you have added. What you would want to do is unbind the listeners that are still on the document when you click the next image, which will mean that only one image will be listening for your keypresses at a time.
For example, in this jsfiddle we have the code:
$('#in').keypress(function(event) { alert('first'+event.which); });
//$('input').unbind('keypress');
$('#in').keypress(function(event) { alert('second'+event.which); });
Which adds two listeners to an input element, and as you can see by pressing a key within the element, it causes both listeners to run. Essentially you are adding a new keypress listener each time you click an image, and the old ones are never being cleared out. If you uncomment the unbinding command in the jsfiddle, you will see that only the second alert will be invoked, because the first listener is released. If you only ever want the keys to be listening to one image at a time, then you will want to have something along the lines of $(document).unbind('keypress') at the beginning of the click listener (of course this will clear all keypresses, so if you have other listeners attached to the document you will want to be a bit more careful managing them, for this problem it will be sufficient).
Yes, that's how it will work with this code.
Reason is, in the img.click event handler you attach a new event handler on document.keypress which will resize the image by passing it a reference to 'thisImage'.
What happens is, this document.keypress event handler for this image will continue to live on, even if you click on another image, and will resize the image on each keypress.
These event handlers will continue to accumelate as you keep selecting new images.
What you need to do is remove the previous event handlers when user clicks on a new image.

Multiple event listeners on HTML5 canvas

I've been trying to create a game in strictly HTML5 and JavaScript and have run into an issue that I can't seem to wrap my head around. In an attempt to try and avoid using third party classes/libraries, I'm creating my own class for handling custom buttons within the HTML5 canvas element. I almost got them to work and then had to re-write most of the script after realizing that my event listeners kept adding on top of each other every time the canvas redrew (I was using an anonymous function in the mouseDown event listener before, but have since switched to a different method).
First of all, my event listeners now use a function which holds a reference to whichever button I'm trying to use. My prototype's mouseDownFunc is then called, it checks the boundary of the button instance's dimensions, and then finally calls a referenced onPress() (which is actually an overridden method that every button uses, so each button has a custom set of instructions when pressed).
So, if you're still following along (I know, it's a bit confusing without seeing the full script), the problem is that because my event listeners are using the same function, they're overwriting the previous event listener, so only the last button added functions correctly. To sum this all up, how can I add multiple event listeners to the canvas element, which all use the same function without erasing the previous event listeners. Note that I'm trying to do this without the use of jQuery or other third-party extensions.
If more information is needed in regards to my code so that it's easier to understand, let me know. Thanks in advance for any type of feedback.
Edit: Perhaps this might help. Note that this isn't the complete code, but contains the main points:
Adding a button:
this.test_button = new CreateButton(this, 'test_button');
this.test_button.onPress = function() {
alert('Blue button works!');
};
this.test_button.create(200, 50, 30, 200, 'text');
When using create() on a button, variables are checked and stored, as well as an array that holds onto all current buttons (so they can be referenced at any point). Then this is run: this.that.custom_canvas.addEventListener('mousedown', this.create.prototype.mouseDownFunc, false);
When mouseDownFunc is called, this takes place:
CreateButton.prototype.create.prototype.mouseDownFunc = function(e) {
var mouse_x = e.clientX-this.offsetLeft;
var mouse_y = e.clientY-this.offsetTop;
// Check if the mini-button button was actually clicked
if(mouse_x >= test2.x && mouse_y >= test2.y && mouse_x <= (test2.x + test2.width) && mouse_y <= (test2.y + test2.height)){
alert('clicked and working!');
test2.onPress(); // A reference to the saved function
}
};
Currently, my test2 is a reference to any given object -- it's a global var, but after I get these other issues fixed, I'll deal with getting rid of the global var (I know, I know - it was just a temporary quick-fix).
Maybe instead of an event listener for each and every possible button, and checking box size within the function, you could create a single event that calls a routing function to check where on the element the event occurred, and then delegate to another function
You need to design something to handle the event dispatch in your program. You seem to have components that have their listeners all disorganized. You could build a tree data structure (https://en.wikipedia.org/wiki/Tree_%28data_structure%29) that is a hierarchy for the event dispatch in your components ( such as buttons, text areas etc.). The idea is that when the tree is traversed the events will be handled in an ordered fashion. The tree would be reorganized based on how the user interacts with your program. For a simple example, to start this tree could perhaps prioritize the most recently drawn component (out of some structure that holds a list of everything to be drawn) as the event listener to receive event handling first. Then, if a component is blocked by another component the blocked component (like a button covering the button) it's event handling could either be disabled or scheduled to happen later depending on your implementation. Of course your implementation may be more complex, but you need to keep track the event handling. Java uses a component heirarchy data structure to handle a wide variety of GUI events that you can learn more about here http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html

Categories