Resizable block for internet explorer. Problem with MouseMove event - javascript

I want to make a resizable block (<div>). It must resize when user grab the top left corner of the block. It is something like http://jqueryui.com/demos/resizable/ but for top left corner, not for bottom right.
HTML code:
<div class="chatBlockBody">
<img src="resizeMarker.png" class="topMarker" alt="" />
content of block
</div>
CSS code:
.chatBlockBody
{
width:240px;
height:250px;
border:1px solid #4a73ce;
position:absolute;
bottom:25px;
right:0;
display:block;
background-color:White;
}
.topMarker
{
position:absolute;
top:3px;
left:3px;
}
The js-code is following:
var dragObject;
$(".topMarker").mousedown(function(e){
dragObject = this;
$(dragObject).parent().css("z-index",42);
return false;
});
$(document).mouseup(function() {
dragObject = null;
});
$(document).mousemove(function(event){
if(dragObject!=null){
var hg=Math.max($(document).height()-event.pageY,250);
var wd=Math.max($(document).width()-event.pageX-parseInt($(dragObject).parent().css("right")), 240);
$(dragObject).parent().css("height",hg+"px");
$(dragObject).parent().css("width",wd+"px");
}
});
It works fine for Chrome and Firefox. But it didn't work in IE.
IE doesn't execute the mousemove code, when user move mouse with pressed mouse button. So, it didn't redraw the border of div.
How can I fix it and make resizable block for IE?

If jqueryui.resizable is satisfying except the position of the handle, you can use the handles-option there, the handles can be defined on every side you want to:
$('.chatBlockBody').resizable({ handles: 'nw' });

Related

Set position of <div> at runtime

On mouseover I want to move the "imgbox" to a specific absolute position (which might move it on top of the "i" image).
The second image ("newimg") loads, so that part works (including hiding it again in "onmouseout") but it's displayed below everything (like in the HTML code). It seems like setting imgbox.style.left and imgbox.style.top doesn't do anything. If I set "margin" instead, the image is displayed 200px to the right and 200px down from where it originally was (but still below everything else).
What did I miss? How do I move the "imgbox" at runtime with regular Javascript (no JQuery please!)?
function onHoverIn(url) {
var imgbox = document.getElementById("imgbox");
imgbox.style.visibility='visible';
var newimg = document.createElement("img");
newimg.src = url;
var oldimg = document.getElementById("i");
/*if(oldimg.addEventListener){ //Removed so the snippet'll run
oldimg.addEventListener('mouseout',onHoverOut,false);
} else {
oldimg.attachEvent('onmouseout',onHoverOut);
}*/
imgbox.innerHTML='';
imgbox.appendChild(newimg);
imgbox.style.left = '200px';
imgbox.style.top = '200px';
//imgbox.style.marginLeft = '200px';
//imgbox.style.marginTop = '200px';
}
#imgbox {
position : absolute;
border: 1px solid #999;
background : #FFFFFF;
filter: Alpha(Opacity=100);
visibility : hidden;
z-index : 50;
overflow : hidden;
}
<img id="i" src="https://i.pinimg.com/originals/53/02/a4/5302a4c318139bf5753c433b1f4c6aa8.jpg" alt="DP" onmouseover="onHoverIn('https://i.pinimg.com/originals/b2/1b/07/b21b0738ea390fc56a4d3efe76ab88de.jpg')">
<p>Long Teeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeext<br><br><br><br><br>END TEEEEEEEEEEEXT</p>
<div id="imgbox"></div>
Sorry, the images are pretty big, so not sure how well it'll work. I tested the code with Firefox 85.0, Chrome 88, IE and Edge by simply double-clicking the .html file and the positioning doesn't work properly in any of them.
This was quite a bit harder than I thought it would be, made some changes to your code. Hope this still works for you.
NOTE: I implemented an onHoverOut locally and noticed that when I moved my mouse around on the image it would flicker. This happens because the new image is loaded and once moving again the old image registers a onHoverOut (because you hover on top of the new image) which would then remove the new image, at which point the old image registers the onmouseover again and adds the new image. This would keep looping for as long a you move the mouse around.
function onHoverIn(url) {
var imgbox = document.getElementById("imgbox");
imgbox.style.visibility='visible';
var newimg = document.createElement("img");
newimg.src = url;
var oldimg = document.getElementById("i");
if(oldimg.addEventListener){
oldimg.addEventListener('mouseout',onHoverOut,false);
} else {
oldimg.attachEvent('onmouseout',onHoverOut);
}
//imgbox.innerHTML='';
imgbox.appendChild(newimg);
}
function onHoverOut() {
console.log('onHoverOut: not implemented');
}
.article{
width:640px;
padding:0 16px;
}
.image-box{
position:relative;
width:100%;
height:0;
/* 16:9 */
padding-top:56.25%;
overflow:hidden;
}
.image-box img{
position:absolute;
top:0;
width:100%;
}
<div class="article">
<p>content before..</p>
<div id="imgbox" class="image-box">
<img id="i" src="https://i.pinimg.com/originals/53/02/a4/5302a4c318139bf5753c433b1f4c6aa8.jpg" alt="DP" onmouseover="onHoverIn('https://i.pinimg.com/originals/b2/1b/07/b21b0738ea390fc56a4d3efe76ab88de.jpg')">
</div>
<p>content after..</p>
</div>

reset of div's position only working sometimes

I'm having an issue resetting a div's left position with jquery after an animation. I'm trying to animate a div from off the screen(left) to on the screen. However, I only want to trigger this animation if the value of scrollTop of the window is greater than a certain value. once the value of scrollTop is less than the value, I want the div's position to change so that it is offscreen again. This is working but only sometimes and I'm not sure why. I am also setting the position of the div to absolute at the same time I am setting it to go off the screen and this change always works!. Below is the code as well as the CSS of the div I'm trying to animate. Thank you!
Function to change position on scroll
$(window).scroll(function() {
if( $(this).scrollTop() > 500 {
$(".animated-logo").css({position:'fixed'});
$(".animated-logo").animate({left: '20px'},500);
}
else{
$('.animated-logo').css({position: 'absolute',left:'-150px'});
}
});
CSS for the animated-logo element
.animated-logo
{
position:absolute;
top:0;
left:-150px;
width:100px;
z-index:2;
}
So first off, you have a syntax error.
I would approach this with using classes instead of doing it like this. At best you're going to have a buggy transition. You can adjust the css transition to make it your desired timing.
JS:
$(window).scroll(function() {
if( $(this).scrollTop() > 500) {
$(".animated-logo").addClass('visible');
}
else{
$(".animated-logo").removeClass('visible');
}
});
CSS:
.animated-logo{
position:absolute;
top:0;
left:-150px;
width:100px;
z-index:2;
transition:0.5s;
}
.animated-logo.visible{
position:fixed;
left:20px;
}
https://jsfiddle.net/783z9rhm/6/
When you say This is working but only sometimes and I'm not sure why, it's not sure what the problem is so I'll assume you are having issues with the animation after the first time it runs. The is maybe because you are firing it ON EVERY USER SCROLL ACTION, which is a lot. Using a flag to fire it only once every time the 500px threshold is crossed will get rid of the glitch
HIH
var visible = false;
$(window).scroll(function() {
if( $(this).scrollTop() > 500) {
if(!visible){
visible = true;
$(".animated-logo").css({position:'fixed'});
$(".animated-logo").animate({left: '20px'},500);
}
}
else{
visible = false;
$('.animated-logo').css({position: 'absolute',left:'-150px'});
}
});
.animated-logo
{
position:absolute;
top:0;
left:-150px;
width:100px;
height:100px;
z-index:2;
background: red
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="animated-logo"></div>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br>

How to prevent text selection from obstructing onMouseMove event?

I'm implementing a "resize handle" to change the width of my left navigation panel. It is a div that receives an onMouseDown() event, calculates the necessary widths and applies them to the right elements in the subsequent calls to onMouseMove(). But I'm having some problems.
1) The article element, to the right of the navigation panel and handle, does not activate the onMouseUp() if I release the mouse there. Is this because the onMouseDown() was activated in other element?
2) If I move the mouse fast to the right, I can't prevent the text in the article from being selected, even calling methods like preventDefault() and stopPropagation().
3) Even if there's no text in the article, the resizing only works if I move the mouse very slowly. If the mouse moves fast over the article element, the resize stops, unless I release the mouse button - in this case the resize goes smoothly (suggesting it was the text-selecting that was stopping the resize, even with no text at all). But if I release the mouse button, the resize should stop (see point 1).
I've seen some solutions using CSS user-select: none, but this would prevent any text from being selected inside article, which is obviously an overkill.
So, how can I make the resizing smooth, without selecting any text, when I move the mouse over any element in my document? (After pressing the button in the right div, of course.)
That's my HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'>
<title>CSS Template</title>
</head>
<body>
<header>Header</header>
<main>
<nav id='nav'>
<div class='navcont' onmousemove='handMm(event)' onmouseup='handMu(event)'>
<p>nav 1</p>
<p>nav 2</p>
</div>
<div class='handle' onmousedown='handMd(event)' onmousemove='handMm(event)' onmouseup='handMu(event)'>
</div>
</nav>
<article id='article' onmousemove='handMm(event)' onmouseup='handMu(event)'>
</article>
</main>
<footer>Footer</footer>
</body>
</html>
That's my CSS:
html, body {
height:100%;
margin:0;
}
body {
display:flex;
flex-direction:column;
}
header {
text-align:center;
}
main {
flex:1;
display:flex;
min-height:0;
}
article {
background:#CCC;
width:auto;
overflow:auto;
padding:10px;
flex-grow:1;
}
nav {
width:300px;
height:auto;
overflow: hidden;
display:flex;
}
.navcont {
background:#8C8;
width:auto;
flex-grow:1;
}
.handle {
background:#333;
right:0px;
width:30px;
cursor:col-resize;
}
footer {
text-align:center;
}
That's my Javascript:
var mx,px,moving=false;
function handMd(e) {
mx = e.pageX;
px = document.getElementById('nav').clientWidth;
moving = true;
}
function handMm(e) {
if (moving) {
e.preventDefault();
e.stopPropagation();
e.cancelBubble = true;
e.returnValue = false;
var diff = e.pageX - mx;
document.getElementById('nav').style.width = (px + diff)+'px';
document.getElementById('article').style.width = (window.innerWidth-px-diff)+'px';
}
}
function handMu(e) {
moving = false;
}
And here is a working example: https://jsfiddle.net/45h7vq7u/
Another example, including Ryan Tsui's answer: https://jsfiddle.net/v1cmk2f6/1/ (the text-selection is gone, but the div still won't move smoothly, but only when moving fast to the right).
Catch the events of start moving and finish moving with your preferred method (onMouseDown and onMouseUp are fine). Add a CSS class to specify the moving state when the action starts. Remove the CSS class when the action finishes.
In your case, you may try the followings:
Add a new CSS class:
.moving {
user-select: none;
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
}
Extend your handMd() and handMu() functions:
function handMd(e) {
mx = e.pageX;
px = document.getElementById('nav').clientWidth;
moving = true;
document.getElementById('article').classList.toggle('moving', true); // Add this line. 'article' is the id of the element where you don't want the selection to occur.
}
function handMu(e) {
moving = false;
document.getElementById('article').classList.toggle('moving', false); // Add this line. 'article' is the id of the element where you don't want the selection to occur.
}
After analyzing how this was solved somewhere else, I came to the following changes.
HTML - only one event handler needed:
...
<main>
<nav id='nav'>
<div class='navcont'>
<p>nav 1</p>
<p>nav 2</p>
</div>
<div class='handle' onmousedown='handMd(event)'>
</div>
</nav>
<article id='article'>
</article>
</main>
...
Javascript - attach and detach the onmousemove event handler is way better than calling onmousemove every time the mouse moves (to only then test if the mouse button has been pressed). Also, the event is now attached to the document, not to each div on screen:
var mx,px,minW = 200;
function handMd(e) {
mx = e.pageX;
px = document.getElementById('nav').clientWidth;
document.addEventListener('mousemove',handMm);
document.addEventListener('mouseup',handMu);
document.getElementById('article').classList.toggle('moving',true);
document.getElementById('nav').classList.toggle('moving',true);
}
function handMm(e) {
var diff = e.pageX - mx;
if (px+diff >= minW && window.innerWidth-px-diff >= minW) {
document.getElementById('nav').style.width = (px+diff)+'px';
document.getElementById('article').style.width = (window.innerWidth-px-diff)+'px';
}
}
function handMu(e) {
document.removeEventListener('mousemove',handMm);
document.removeEventListener('mouseup',handMu);
document.getElementById('article').classList.toggle('moving',false);
document.getElementById('nav').classList.toggle('moving',false);
}
CSS - thanks to Ryan Tsui's answer, I eliminated the unwanted text selection while resizing:
.moving {
user-select:none;
-moz-user-select:none;
-webkit-user-select:none;
-ms-user-select:none;
}
I don't know how to stop the selection but I can tell you for some help that the event triggered when something is selected is onselect.

Scroll to top in a lightbox

I have created a customized menu. See here. On click of this link I have a shadowbox popping up which has a long list of items. Now I want to have a "back to top" anchor link which takes me back to the top of the menu list.
I've set your lightbox with the #box id.
Html
<div id="box">
...
<!-- long content there -->
To Top
</div>
CSS (setting the width of elements)
#box {
position:relative;
width:200px;
height:250px;
overflow:auto;
}
#box #toTop {
position:absolute;
display:none;
left:150px;
top:10px;
}
jQuery
$('#box').bind('scroll', function(e) {
if ($(this).scrollTop() > 100) {
$('#toTop').fadeIn();
$('#toTop').css({'top' : $(this).scrollTop() + 100});
} else {
$('#toTop').fadeOut();
}
});
$(document).on('click', '#toTop', function(e) {
e.preventDefault();
//$('#box').scrollTop(0); //just go to top
$('#box').animate({scrollTop : 0},'slow'); //animate
});
Fiddle
Pretty easy with:
document.querySelector("iframe").contentWindow.scrollTo(0,0);
Now put a button on the page and call that on click. Oh, and omit the height:100% on your body of the iframe, this way you get rid of the second scrollbar.
You can try this out by just pasting the line above and executing it in the console of your browser with your webpage.

Disabling mouse scrolling

I have a page with a textbox in it. When I scroll the textbox to the bottom, the document will scroll after it. How to disable mouse scrolling for the document but enable scrolling for the textbox when mouse is over textbox? I only need to disable mouse scroll and not window scrollbars.
The page has a fixed size and there will only be scrollbars when the browser window is not maximized. The document has a 800x600 px size and should fit for most users I think.
I'm using JavaScript with jQuery.
$('#txt').hover(function (){
$('body').css('overflow','hidden');
}, function (){
$('body').css('overflow','auto');
})
You could try the following
<script type="text/javascript">
function stop()
{
return false;
}
document.onmousewheel=stop;
</script>
You could also do this in CSS if you choose to do so using the following;
body{
overflow: hidden;
}
Off the top of my head I came up with that. If you don't want them to scroll you could also add some stuff to your CSS class like the following
Hope this helps!
Happy Coding! ;)
Use the following code to disable scrolling:
if(window.addEventListener){ //Firefox only
window.addEventListener("DOMMouseScroll", function(e){e.preventDefault()}, true);
}
window.onscroll = function(e){e.preventDefault()};
For compability, see: http://www.quirksmode.org/dom/events/scroll.html
This solution is same of Sameera but without Jquery:
var azul = document.getElementById("azul");
azul.onmouseover = function(){
document.body.style.overflowY = "hidden";
};
azul.onmouseout = function(){
document.body.style.overflowY = "auto";
};
#total{
height: 900px;
}
#amarela{
background-color: yellow;
height:50%;
}
#azul{
background-color: blue;
height:50%;
}
<div id="total">
<div id="amarela"></div>
<div id="azul"></div>
</div>

Categories