Javascript event which occurs when resizing a DOM element? - javascript

Im working on a project in which the height value of a resizable div always needs to be divisible by 24 (This is so it always matches the default lineheight). I have created a function for resizing the div and i now need to run the function whenever the div is resized. Events that fire when the entire window is resized exist but im not able to find any events which fire when a specific DOM element is resized.
The following is my code:
HTML
<body>
<div id="resizable-div" onresize="changeHeight()"></div>
<body>
Javascript
let resizeDiv = document.getElementById('resizable-div');
function changeHeight(){
if (resizeDiv.style.height % 24 != 0) {
resizeDiv.style.height = `${Math.round(resizeDiv.offsetHeight / 24) * 24}px`
}
}
I was expecting the above code to change the height of resizable-div whenever it was resized. It doesn't, however when writing my code like this:
<body onresize="changeHeight()">
<div id="resizable-div"></div>
<body>
It produces the outcome im looking for, but only whenever the size of the entire viewport is changed. How can i call my function whenever the height of my resizable-div changes?

After deciding to use my brain the solution was painfully simple. Since the div is resized by the user dragging it, i can simply add an event listener to the resizable-div which listens to the mouseup event. Here is the code:
HTML
<body>
<div id="resizable-div"></div>
<body>
Javascript
let resizeDiv = document.getElementById('resizable-div');
function changeHeight(){
if (resizeDiv.offsetHeight % 24 != 0) {
resizeDiv.style.height = `${Math.round(resizeDiv.offsetHeight / 24) * 24}px`
}
}
resizeDiv.addEventListener('mouseup', (event) => {
changeHeight();
})
This will make the div snap to the closest height that is divisible by 24 whenever the user stops dragging it.

Related

Detecting weather user scrolls the bottom of the div or not in react js and javascript

I want to implement infinite scrolling in the table, so I am calculating div height in one possible way, you can see below
let fixedCh = e.target.clientHeight;
let calCh = e.target.scrollHeight - e.target.scrollTop;
if (fixedCh === calCh) {
alert('load more');
}
In this approach,calCh is varied from different resolutions. Is there any other way of doing this, so that it can work through all kind of browser and screen resolution
Your approach is good; you need to call your function initially when the user loads the page to check if the user's screen resolution is already to the end of the scroll, call "alert('load more')".
The problem is that for some users, based on their screen, the scrollbar will not be visible to scroll, so your event of scroll won't check the element. To fix this, as I said above, you need to initially load your screen check function when the "Dom is ready".
Here is the basic implementation:
function loadMore (e) {
let fixedCh = e.clientHeight;
let calCh = e.scrollHeight - e.scrollTop;
if (fixedCh === calCh) {
alert('load more');
}
}
// listen on scroll and check target element fixedCh === calCh
function listenOnScroll() {
document.getElementById('app').addEventListener('scroll', (e) => {
loadMore(e.target)
})
},
window.onload = (event) => {
loadMore(document.getElementById('app').target)
};
I will call the function "loadMore" when the dom is ready or loaded and pass the targetted Dom element.
Later, I'll call the "listenOnScroll" function to listen on the target element scroll and then call the "loadMore" function from it.

trying to get onmouseenter and onmouseout working on new img in dom

Environment: Safari 110.0.1, OSX (MacOS) 10.12.6
I am working on an image gallery type of display. There's an element that is loaded with an image by the Javascript; I want that element to have functionality on onmouseenter and onmouseout.
It would appear that I can't add those when I'm creating the img element, because the image is not loaded, and I read (somewhere, lol, it's been a long day) that an element has to be loaded before one can attach functions to it. I did try it in the HTML; no joy.
So I have a timer going, and I am trying to attach it there, but that doesn't work either - the functions are never called.
I tried starting the timer after the page is loaded, but, that doesn't work - the over/out functions still don't fire. The timer is definitely running, that's what forces the redraw if the page scaling changes, and that works. You can see what I want to happen with the mouse over/out by clicking the checkmark below the image.
Here's the page, all the HTML and Javascript code is visible there (lower on the page.) Any insight is appreciated.
The best I've been able to do so far is to get the events to attach to a surrounding div by specifying out in the HTML, where they do pretty much the right thing as far as the div is concerned. But when the mouse is over the image, it is out of the div, so the opposite of what I want happens: the onmouseout fires and the thing I want to have happen over the image goes away.
Is there some reason I can't attach these functions during the timer? Here's the timer code:
function mousingover()
{
console.log('over');
if (dismode == 1) return;
show_image_notes('mypic');
}
function mousingaway()
{
console.log('away');
if (dismode == 0) return;
show_image('mypic');
}
function ticker()
{
// var pic = document.getElementById('mypic'); // get (eventually) ready element
// var eltype = pic.nodeName;
// console.log('eltype:',eltype);
// pic.onmouseenter = function() { mousingover(); }
// pic.onmouseout = function() { mousingaway(); }
// console.log(pic.onmouseout);
// When the display is rescaled, the width of this div changes
// This is used to re-fire the calculation of where the notes go:
var myAnchor = document.getElementById('picdiv');
var xd = myAnchor.offsetWidth;
if (working == 0 && xd != xdim)
{
working = 1;
if (dismode == 1) show_image_notes('mypic');
else show_image('mypic');
xdim = xd;
working = 0;
}
tcounter = tcounter + 1;
if (tcounter > 10 || tcounter < 0) // trying to delay so image has time to load
{
var pic = document.getElementById('mypic'); // get (eventually) ready element
pic.onmouseenter = function() { mousingover(); }
pic.onmouseout = function() { mousingaway(); }
tcounter = 0;
}
}
The console confirms that I am finding the IMG with that ID, which is correct, and also that the functions are attached. They just don't fire.
I'm actively working on this, so the code for the timer will change; the page always displays the code that's in use at the moment.
I'm trying to do this with pure Javascript.
I looked at your HTML, and you have a canvas element in there along with the img element. It looks like the canvas overlays the image, yes? If so, the canvas is going to get the mouse events, and the img won't see them.

i cant get the correct height() and get width()

I have a function that is called when a button is clicked.
The function first changes the size of the control and then i have 2 lines of code that fetch the height and width of a control and display them in the paragraph as text.
When the user first clicks on the button they will get the wrong values of 340*150 and when they click the button again they get the correct values 600*400
the 340*150 is the old/original size before the control expands.
However on the first click even though the wrong values are displayed i still get the correct control size of 600*400 displaying.
function a () {
//change control to 600*400
//now get the height and width and display in 'p' and 'g'.
document.getElementById('p').innerHTML = jQuery("#hi").width();
document.getElementById('g').innerHTML = jQuery("#hi").height();
}
<button id="btn" onClick="a()"> Maximize 600x400 </button
also using settimeout function resolves the issue. but i want to fix it properly.
Could you do something like this?
function a () {
var w = 600;
var h = 400;
// change control to 600*400 using the w and h variables
// code to do that here ...
// now get the height and width and display in 'p' and 'g'.
document.getElementById('p').innerHTML = w;
document.getElementById('g').innerHTML = h;
}
<button id="btn" onClick="a()"> Maximize 600x400 </button
If the size of your element is properly being changed then the numbers should be the same either way. No need to get the numbers from the element.
If you create an event on page load, say btnResize, then you can emit it after the resize, it will solve your problem. jQuery uses trigger() to emit an event.
function a(){
$('#hi').width(600);
$('#hi').height(400);
$('#hi').trigger('btnResize');
}
$('#hi').on('btnResize', function(){
$('#p').html($('#hi').width());
$('#g').html($('#hi').height());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btn" onClick="a()"> Maximize 600x400 </button>
<div id="p"></div>
<div id="g"></div>
<br>
<button id="hi" style="width:340px; height:150px;" > resize me </button>
I believe your issue was as simple as the asynchronous nature of JavaScript. You were getting the width and height before the function a() was called.

Adding a window state (max,min etc.) listener in chrome app example

I'm trying to have a function fire upon window state change (js already has an onresize function and firefox has a statechange listener, however going from min to max to restore is not a resize event).
manifest.json calls main.js:
main.js: [launches index.html]
window.chrome.app.runtime.onLaunched.addListener(function() {
window.chrome.app.window.create('index.html',{id: "index"})});
index.html: [includes a div that should change upon window state change
through a call to htmlBoundScript.js]
<script src=htmlBoundScript.js></script>
<!--below should change when screen is maximized-->
<div id="window_state">state has not yet changed</div>
<!--it does not change-->
htmlBoundScript.js -> [Listens for state change and updates div in html]
chrome.app.window.onFullscreened.addListener(function()
{
var isMax = chrome.app.window.get('index').isMaximized();
document.getElementById('window_state').innerHTML =
("state has ... changed, isMax = " + isMax);
});
//The above code does not behave as intended,
//that is it does not change the div in the html
Following: https://developer.chrome.com/apps/app_window#event-onMaximized , however I'm sure there's a basic element that need adjustment.
From SE's link:
chrome.app.window.current().onBoundsChanged.addListener(updateCurrentStateReadout);
function updateCurrentStateReadout() {
if(chrome.app.window.current().isMaximized())
{
//do action ...
}
}
However, still searching for an example of how to use the onFullscreened method.

After resizing the window, elements within do no fit anymore

I have a modal dialog (window.showModalDialog) with html in it. when I resize the dialog, the HTML within it does not repect the new boundaries and I get scroll bars or elements that don't expand 100% to the new width.
To fix this I have to drag it around for a bit and it then jolts it self back into the correct sizes.
To fix it programtically. I do the following window.document.getElementById('removeMainBody').innerHTML =window.document.getElementById('removeMainBody').innerHTML;
But this causes some dynamic objects in the html to stop functionin.
How can i solve this problem and make the elemnts within the dialog resize after I resize the dialog?
Here is my code
else if(<c:out value="${staffCount}" /> > 1){
document.getElementById('removeDiv').style.display = '';
window.dialogWidth='770px';
window.dialogHeight='320px';
window.document.getElementById('removeMainBody').innerHTML =window.document.getElementById('removeMainBody').innerHTML;
}
If you set a style or a Class from the Body-Tag, this should force an HTML Reflow, and the Site would be displayed correct again, without setting the innerHTML Property.
example:
...
window.document.body.className = "relfow";
// if the body class Attribute was set, than set it now back
window.document.body.className = "oldBodyStyleClassName" ; / Or just to ""
...
if the browser optimizes, the refresh calls, so that now reflow occures you could
setTimeout(function(){
...
window.document.body.className = "relfow";
// if the body class Attribute was set, than set it now back
window.document.body.className = "oldBodyStyleClassName" ; / Or just to ""
...
})
i hope this helps. (here you can find some info to Reflow Link)

Categories