Constrain user selection to node without making it editable? - javascript

I have the following page:
<div class="a">
...
</div>
<div class="b">
...
</div>
My users interact with this page by selecting various pieces of text within .a and .b. The browser's native selection behaviour almost works, but I need to prevent my users from making selections, which span the boundary between .a and .b.
Is there a way to constrain the user's selection to a <div>?
Unfortunately, this content is not user editable - which is unfortunate, because setting contenteditable="true" on each <div> achieves the constraint I'm looking for.

How about starting with this:
HTML:
<div class = "a">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris id semper purus. Duis laoreet tellus in ante luctus semper. Praesent interdum urna quis luctus commodo.
</div>
<div class = "b">
Curabitur vehicula eget leo a tristique. Donec eget aliquam erat. Mauris id porttitor lacus.
</div>
CSS:
* {
margin: 0;
padding: 0;
}
body {
padding: 10px;
}
.noSelection {
-webkit-user-select: none;
-moz-user-select: none;
-o-user-select: none;
-ms-user-select: none;
user-select: none;
}
div + div {
padding-top: 10px;
}
jQuery:
$(function() {
$("div").hover(function() {
$(this).siblings("div").toggleClass("noSelection");
});
});
Here's a fiddle: http://jsfiddle.net/J2fJz/.

Related

Image max height and max width while preserving aspect ratio

Is it possible to give max-height and max-width to an image while preserving aspect ratio without using js?
For example,
I want an image to be with a height of 38px and the width auto.
If the width is higher than 200px, I want the width to be 200px and the height auto.
If it's not possible without js, does anyone have an idea how to do it with js and without resizing the image after it's already loaded?
You can nest the image in a 200x38 container, then set the max-width and max-height of the image to 100%. Here is a working snippet (I have included JS to make it interactive, but it is not necessary. Try resizing the container using the sliders):
var width = document.getElementById("width");
var height = document.getElementById("height");
var widthInput = document.getElementById("widthInput");
var heightInput = document.getElementById("heightInput");
var imageContainer = document.querySelector("div");
widthInput.addEventListener("input", function() {
width.innerHTML = this.value + "px";
imageContainer.style.width = this.value + "px";
});
heightInput.addEventListener("input", function() {
height.innerHTML = this.value + "px";
imageContainer.style.height = this.value + "px";
});
div {
width: 200px;
height: 200px;
border: 1px dashed #000;
}
.image {
display: block;
max-width: 100%;
max-height: 100%;
background: #333;
}
<div>
<img class="image" src="https://via.placeholder.com/400"/>
</div>
<br/>
<label>Width: <span id="width">200px</span></label>
<br/>
<input id="widthInput" type="range" min="0" max="400"/>
<br/>
<label>Height: <span id="height">200px</span></label>
<br/>
<input id="heightInput" type="range" min="0" max="400"/>
You can notice that however you change the dimensions of the container, the image is still contained within it. By setting the container to 200px wide by 38px tall, you can force the image to stay within the limits 0px ≤ width ≤ 200px and 0px ≤ height ≤ 38px.
There is a built in CSS style called max-width and max-height and I really do not think min-width exists, incase you are wondering. You can refer to the example below to understand better. Also I am using text instead of an image, but you should get the idea.
I have nested the actual div instead another div so you could play around with the resizing.
#con {
resize: both;
overflow: auto;
}
#box {
/*Here you could say auto instead*/
height: 200px;
max-width: 200px;
}
<!DOCTYPE html />
<html>
<head></head>
<body>
<div id="con">
<div id="box">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus dapibus auctor ipsum, in convallis mi lobortis in. Phasellus molestie suscipit rutrum. Duis et convallis lectus. Etiam id urna massa. Nulla sagittis erat nec arcu rutrum elementum. Vestibulum blandit erat vestibulum, ullamcorper augue vitae, accumsan mi. Sed consectetur, quam vel efficitur interdum, ante ligula interdum justo, a dictum ligula tortor sed nunc. Cras eget magna ac urna imperdiet laoreet eget sed ante. Vivamus condimentum tortor sit amet diam elementum malesuada sed sed neque. Vestibulum et magna mollis, consequat nibh ut, facilisis orci. Phasellus fermentum sodales libero, et vehicula enim ornare ut. Donec non bibendum metus. Cras hendrerit, quam a pellentesque varius, tortor nunc maximus lectus, at gravida diam ipsum ut metus. Etiam orci felis, dapibus id cursus eu, dapibus ut augue. Proin a leo viverra, tempus ipsum nec, lacinia lacus. Maecenas id dolor nec neque lobortis interdum quis quis nisi.</div>
</div>
</body>
</html>
Using both width auto and height auto will give to following code. To center horizontal I used the align-items center of the flexbox.
.container,
.container * {
box-sizing: border-box;
}
.container {
display: flex;
width: 800px;
margin: 10px auto;
}
.img {
display: flex;
align-items: center;
width: 25%;
height: 150px;
border: 2px solid silver;
}
.img img {
display: block;
border: 0;
width: auto;
max-width: 100%;
height: auto;
max-height: 100%;
margin: auto;
}
<div class="container">
<div class="img">
<img src="http://placekitten.com/200/300" alt="">
</div>
<div class="img">
<img src="http://placekitten.com/300/200" alt="">
</div>
<div class="img">
<img src="http://placekitten.com/250/350" alt="">
</div>
<div class="img">
<img src="http://placekitten.com/350/200" alt="">
</div>
</div>
You have to use max-width and height and object-fit CSS properties for image.. see example
.img img {
max-width: 200px;
height: 38px;
object-fit: contain;
object-position: left;
}
<div class="img"><img src="https://stackoverflow.design/assets/img/logos/so/logo-stackoverflow.png"></div>
Hope it works... if any question comment pls
Here are 2 examples of the solution I think would work, the first image has less than width: 200px; and the second one has more than width: 200px;
Again, I'm not sure if it would work for you, but I think it would, and if it doesn't I would love to know why.
<style>
img {
max-width: 200px;
height: auto;
}
</style>
<img src="https://dummyimage.com/180x400/666/fff.jpg" alt="test">
<br>
<img src="https://images.pexels.com/photos/5686476/pexels-photo-5686476.jpeg?auto=compress&cs=tinysrgb&dpr=3&h=750&w=1260" alt="test 2">
Specifying height or width will keep the aspect ratio. Specifying both the max-height and max-width will keep the aspect ratio. Specifying height and max-height makes no sense. Specifying height and max-width cannot guarantee your aspect ratio.

fade out transition for .mouseout using .animate?

I have a div that when you hover, another div shows up. They aren't parent/child or wrapped, so I used a script to get this to work the easiest I could and to have what I needed. With .mouseover the hover div slowly appears which is what I want.
My issue is getting the .mouseout to make the hover div slowly disappear and stay gone. I've tried different variations but the closest I got is to make the div slowly fade away, but it pops back up after the delay I had set.
I'm very new to js, really no experience at all. I wrote the first part of this code which works but the .mouseout is what I'm having issues with.
Here's my code:
$("#show_stats1 h1").mouseover(function() { $(".stat-1_info").css({opacity: 0.0, visibility: "visible"}).animate({opacity: 1}, 200); });
$("#show_stats1 h1").mouseout(function() { $(".stat-1_info").css({opacity: 0.0, visibility: "hidden"}).animate({opacity: 1}, 200); });
I know it's probably simple, but I don't know much if anything about js.
Here is the html:
<div id="show_stats1" class="stats">
main, visible div
</div>
<div class="stat-1_info" style="visibility:hidden;">
hidden div to be shown on hover
</div>
Here's a jsfiddle https://jsfiddle.net/yt3h9xnf/
You can use the .animate() method with either opacity or visibility. There is no reason to use both.
If you can't figure out which one to use read this answer here.
$("#show_stats1 h1").mouseover(function() {
$(".stat-1_info").animate({opacity: 1}, 200);
});
$("#show_stats1 h1").mouseout(function() {
$(".stat-1_info").animate({opacity: 0}, 200);
});
.stat-1_info {
opacity: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="show_stats1" class="stats">
<h1>main, visible div</h1>
</div>
<div class="stat-1_info">
hidden div to be shown on hover
</div>
Make it simple by using fadeIn() and fadeOut() with sec as parameter. This will take care of the time you want to see the text and want to disappear.
Use display:none; which is latest and best in market now than using visibility property.
fadeIn()
fadeOut()
$(document).ready(function() {
$("#show_stats1 h1").mouseover(function() {
$(".stat-1_info").fadeIn(3000); // Choose your own time(3sec)
});
$("#show_stats1 h1").mouseout(function() {
$(".stat-1_info").fadeOut(2000); // Choose your own time(2sec)
});
});
.stats_container {
width: 310px;
padding: 10px;
margin-bottom: 0px;
}
.stats {
width: 300px;
height: 34px;
margin: 15px 0px -3px 0px;
}
.stats h1 {
text-align: left;
}
.stats h2 {
position: absolute;
left: 260px;
margin-top: 8px;
width: 50px;
text-align: right;
}
.stats h1 {
display: inline-block;
font-weight: 400;
color: #000;
line-height: 9.5pt;
font-size: 9.5pt;
}
.stat-1_info {
top: -50px;
margin: 0px;
}
.stat-1_info {
float: right;
position: relative;
left: 0px;
display: inline-block;
width: 380px;
height: 334px;
background: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="stats_container">
<div id="show_stats1" class="stats">
<h1>Strength:</h1>
</div>
</div>
<div class="stat-1_info" style="display:none;">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam pretium magna et velit dignissim, a placerat nisi rutrum. Vestibulum odio ipsum, rutrum a ex ac, fringilla fermentum ante. Donec nec elit molestie massa finibus pulvinar non nec lacus. Nullam
ipsum nulla, sodales non ornare et, accumsan a sem. Donec tempus leo non laoreet viverra. Vestibulum ac nunc sem. Aenean vitae convallis velit, non molestie augue. Curabitur tristique eleifend mi, malesuada fringilla erat tristique imperdiet.
</div>

How do I add a JavaScript event handler so that when the user moves the mouse cursor onto the content element a timeout timer starts?

Here is what I am trying to do,
I want to add a JavaScript event handler so that when the user moves the mouse cursor onto the content element, a timeout timer is started that will set the opacity of the payWall element to 1.0 – three second later.
Then I want to dd another JavaScript event handler so that when the user clicks the subscribe button, an alert box appears with the message “Subscribing now.”
When the alert is OK-ed, the payWall slides down the page and out of sight. I think I will need to set an interval timer so that the payWall moves down like 2 pixels every 30 milliseconds.
I am not sure how to do it, I tried my best, but if someone can please help me, I would really appreciate it.
function init()
{
document.getElementById("subscribe").onclick = function()
{
}
}
window.onload=init;
* {
margin: 0;
box-sizing: border-box;
}
body {
font: 1em Verdana, sans-serif;
background-color: antiquewhite;
}
h2, h4 {
text-align: center;
}
#header {
border-bottom: 2px solid black;
font-size: 2.5em;
padding: 0.5em 0;
height: 100px;
}
#footer {
border-top: 2px solid black;
padding: 1em 0;
}
#header, #footer {
text-align: center;
background-color: #CCC;
}
#leftnav, #rightnav {
position: absolute;
width: 20%;
padding-top: 3em;
}
#rightnav{
left: 80%;
}
#wrapper {
background-color: dodgerblue;
overflow: hidden;
}
#content div {
border: 1px solid black;
border-radius: 10px;
padding: 0.5em;
margin-bottom: 10px;
background-color: #ccc;
}
#content div:last-child {
margin-bottom: 0px;
}
#content div:hover {
border-color: dodgerblue;
background-color: white;
}
#content {
padding: 0.5em;
margin: 0 20%;
border-left: 2px solid black;
border-right: 2px solid black;
background-color: white;
}
/* ---------------------------------------------------------*/
#payWall {
background-color : darkseagreen;
font-size: 2em;
opacity: 0.5;
}
<body>
<div id="header">
The Header
</div>
<div id="wrapper"> <!-- Can be used to apply bg colour -->
<div id="leftnav">
<h4> Left</h4>
</div>
<div id="rightnav">
<h4> Right</h4>
</div>
<div id="content">
<div>
<h2> Article 1 </h2>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Suspendisse ultricies condimentum velit vel scelerisque.
</p>
</div>
<div>
<h2> Article 2 </h2>
<p>
Mauris sagittis aliquam odio vitae pulvinar.
Suspendisse id dolor nibh, sed consectetur sem.
Phasellus lacinia laoreet sem, ac ultrices libero lobortis quis.
Morbi accumsan tempus neque, sed varius lectus molestie imperdiet.
Vivamus porttitor facilisis nunc, sed feugiat quam adipiscing ac.
</p>
</div>
<div>
<h2> Article 3 </h2>
<p>
Proin ultrices lectus vel orci lacinia a iaculis nibh hendrerit.
Mauris sagittis aliquam odio vitae pulvinar.
Suspendisse id dolor nibh, sed consectetur sem.
Phasellus lacinia laoreet sem, ac ultrices libero lobortis quis.
Morbi accumsan tempus neque, sed varius lectus molestie imperdiet.
Vivamus porttitor facilisis nunc, sed feugiat quam adipiscing ac.
</p>
</div>
</div> <!-- end of content -->
</div> <!-- end of wrapper -->
<div id="footer">
<h3>
The End
</h3>
<div id="payWall">
For further access please subscribe here. <br>
<button id="subscribe"> Subscribe</button>
</div>
</div>
</body>
First:
Use <div onmouseenter='setTimeout(doStuff, 3000)'> for a three second delay when the cursor enters the div
In JS:
Add a function, doStuff, which has the following code:
document.getElementById('payWall').style.opacity = '1';
document.getElementById('subscribe').onclick = function(){
alert("Subscribing now");
vanishPayWall();
}
One problem is that the payWall would just keep moving down the page. If you wanted it to disappear, you'd want to put overflow-y: hidden on the payWall, and shorten the paywall by 2px every time as well as setting the upper margin to 2px higher. Maybe something like
function vanishPayWall() {
var key = window.setInterval(function(){
var pw = document.getElementById('payWall');
pw.style.height = String(Number(pw.style.height.slice(-2)) - 2) + 'px';
pw.style.marginTop = String(Number(pw.style.height.slice(-2)) + 2) + 'px';
}, 25)
setTimeout(function(){
clearInterval(key)
}, Number(pw.style.height.slice(-2)) * 12.5)
}
Not absolutely sure this will work, but it should help out a bit.

How to position button depending on what content is on the page

I'm having troubles positioning a button on a page with css. I want the button to be fixed at a certain position but when there is a lot of content on the page I want the button to move down.
Firstly I want the button at the bottom of the page when there isn't much content such as the code below which does this:
#Button
{
position: fixed;
height:90px;
width:220px;
left:16%;
top:70%;
border:none;
background:none;
}
Then when there is lots of content I want the button to move down such as the code below:
#Button
{
position: absolute;
height:90px;
width:220px;
left:16%;
padding-top:10%;
padding-bottom: 13%;
border:none;
background:none;
}
Can anyone help? I've looked online but cant make sense of it.
If you define a wrapper block element (a <div> for example) around all your content and put the <button> directly under that element, it is possible to reach the desired result with CSS only.
HTML:
<div id="wrapper">
<!-- other content goes here -->
<button id="button">Sample</button>
</div>
CSS:
#wrapper {
position: relative;
min-height: 100vh;
}
#button {
position: absolute;
bottom: 0;
}
However, I have to warn you about the fact that legacy browsers do not support the vh unit and some others show buggy behavior. Take a look at here before you implement it in your project.
I don't know your structure, but I'll try to help you.
Let's use the following markup:
<div class="parent">
<p class="texto">Your text goes here!</p>
<input type="button" value="OK" />
</div>
To solve your problem, I'd simply use a min-height in the content.
.parent .texto {
min-height: 100px;
}
In this way, the button will always be in the same position if there isn't much content. And it'll follow the height if there are lots of content.
Snippet:
.parent {
width: 200px;
padding: 5px;
border: 1px solid black;
float: left;
margin: 5px;
}
.parent .texto {
min-height: 100px;
}
<div class="parent">
<p class="texto">
Small text!
</p>
<input type="button" value="OK" />
</div>
<div class="parent">
<p class="texto">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi mi urna, rhoncus vitae hendrerit ut, hendrerit a turpis. Phasellus sed rhoncus augue, eget vehicula neque. Vivamus lobortis, velit vitae maximus porttitor, erat nulla scelerisque est, nec
sagittis diam diam id nisl. Maecenas dictum lacinia dignissim. Duis eget ligula fermentum, vulputate dui sed, vestibulum ipsum. Duis non consectetur dolor. Nunc urna eros, tincidunt id nisl id, dapibus imperdiet orci. Mauris posuere convallis ullamcorper.
</p>
<input type="button" value="OK" />
</div>
Hope it helps!
use position:relative for the element which you have defined before this button.

display all textarea rows without scrolling [duplicate]

This question already has answers here:
Creating a textarea with auto-resize
(50 answers)
Closed 7 years ago.
How can I display all textarea rows instead of having that vertical scroll. I have tried with css using min-height and max-height and height: auto but is not working.
.form-control{
width:400px;
min-height: 100px;
max-height: 900px;
height: auto;}
I don't really know if is possible to do that with css.
Maybe is possible with native javascript so I am trying something like this
function expandtext(expand) {
while (expand.rows > 1 && expand.scrollHeight < expand.offsetHeight) {
console.log("display all rows!")>
}
}
I find something nice here but it only increase and decrease rows , so how can I display all textarea rows without using scroll. DON'T NEED SOLUTION WITH FIXED HEIGHT, NEED SOMETHING DYNAMIC or other solutions that works only on chrome browser or only on firefox like Object.observe().
Demo
function expandtext(expand) {
while (expand.rows > 1 && expand.scrollHeight < expand.offsetHeight) {
console.log("display all rows!") >
}
}
body {
padding: 20px;
}
.form-control {
width: 400px;
min-height: 100px;
max-height: 900px;
height: auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
<link href="http://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet"/>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet"/>
<div class=" form-group">
<label>remove texarea scroll and display all rows</label>
<textarea class="form-control" rows="4" onkeydown="expandtext(this);">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque suscipit, nisl eget dapibus condimentum, ipsum felis condimentum nisi, eget luctus est tortor vitae nunc. Nam ornare dictum augue, non bibendum sapien pulvinar ut. Vestibulum ante ipsum
primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras congue congue purus, quis imperdiet tellus ornare in. Nulla facilisi. Nulla elementum posuere odio ut ultricies. Nullam tempus tincidunt elit eget posuere. Pellentesque sit amet
tellus sapien. Praesent sed iaculis turpis. Nam quis nibh diam, sed mattis orci. Nullam ornare adipiscing congue. In est orci, consectetur in feugiat non, consequat vitae dui. Mauris varius dui a dolor convallis iaculis.</textarea>
</div>
<div class=" form-group">
<label>remove texarea scroll and display all rows</label>
<textarea class="form-control" rows="4" onkeydown="expandtext(this);">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque suscipit, nisl eget dapibus condimentum, ipsum felis condimentum nisi, eget luctus est tortor vitae nunc. Nam ornare dictum augue, non bibendum sapien pulvinar ut.</textarea>
</div>
External JSFiddle.
Simple jQuery solution is:
$(function() {
$('textarea').each(function() {
$(this).height($(this).prop('scrollHeight'));
});
});
Check Fiddle.
As you need a plain JavaScript solution, use following script that was created by User panzi. You can view the original answer here.
var observe;
if (window.attachEvent) {
observe = function (element, event, handler) {
element.attachEvent('on'+event, handler);
};
}
else {
observe = function (element, event, handler) {
element.addEventListener(event, handler, false);
};
}
function init () {
var text = document.getElementById('textarea');
function resize () {
text.style.height = 'auto';
text.style.height = text.scrollHeight+'px';
}
/* 0-timeout to get the already changed text */
function delayedResize () {
window.setTimeout(resize, 0);
}
observe(text, 'change', resize);
observe(text, 'cut', delayedResize);
observe(text, 'paste', delayedResize);
observe(text, 'drop', delayedResize);
observe(text, 'keydown', delayedResize);
text.focus();
text.select();
resize();
}
Check Fiddle Here.
No Javascript required.
You can display a no-scroll (ie. automatically re-sizing) editable text area with the following HTML and CSS:
.textarea {
width:250px;
min-height:50px;
height:auto;
border:2px solid rgba(63,63,63,1);
}
<div class="textarea" contenteditable="true">
The Mozilla Developer Network has an Autogrowing textarea example on their HTMLTextAreaElement page. You should definitely check this out if you want to stay away from CSS3 solutions that can break on older browsers.
Here is the code from the example.
The following example shows how to make a textarea really autogrow while typing.
function autoGrow(oField) {
if (oField.scrollHeight > oField.clientHeight) {
oField.style.height = oField.scrollHeight + "px";
}
}
textarea.noscrollbars {
overflow: hidden;
width: 300px;
height: 100px;
}
<form name="myForm">
<fieldset>
<legend>Your comments</legend>
<p>
<textarea class="noscrollbars" onkeyup="autoGrow(this);"></textarea>
</p>
<p>
<input type="submit" value="Send" />
</p>
</fieldset>
</form>
Autoadjust
This example will take care of the case where you remove lines.
function autoAdjustTextArea(o) {
o.style.height = '1px'; // Prevent height from growing when deleting lines.
o.style.height = o.scrollHeight + 'px';
}
// =============================== IGNORE =====================================
// You can ignore this, this is for generating the random characters above.
var chars = '\n abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
var randRange=function(min,max){return max==null?randRange(0,min):~~(Math.random()*(max-min)+min);}
var randChars=function(chrs,len){return len>0?chrs[randRange(chrs.length)]+randChars(chrs,len-1):'';}
// ============================== /IGNORE =====================================
// Get a reference to the text area.
var txtAra = document.getElementsByClassName('noscrollbars')[0];
// Generate some random characters of length between 150 and 300.
txtAra.value = randChars(chars,randRange(150,300));
// Trigger the event.
autoAdjustTextArea(txtAra);
textarea.noscrollbars {
overflow: hidden;
width: 400px; /** This is via your example. */
}
<form name="myForm">
<fieldset>
<legend>Your comments</legend>
<p>
<textarea class="noscrollbars" onkeyup="autoAdjustTextArea(this);"></textarea>
</p>
<p>
<input type="submit" value="Send" />
</p>
</fieldset>
</form>
Using Jquery and some logic I have tried to do what you need.
Here is the jsfiddle;
https://jsfiddle.net/45zsdzds/
HTML:
<textarea class="myClass" id="FurnishingDetails" name="FurnishingDetails" id="FurnishingDetails"></textarea>
Javascript:
$('#FurnishingDetails').text('hello\nhello1\nhello2\nhello3\nhello4\nhello5');
String.prototype.lines = function() { return $('#FurnishingDetails').text().split(/\r*\n/); }
String.prototype.lineCount = function() { return $('#FurnishingDetails').text().lines().length; }
$('#FurnishingDetails').css('height', ($('#FurnishingDetails').text().lineCount() + 1) + 'em');
CSS:
textarea[name='FurnishingDetails']{
height:2em;
}
Used How to get the number of lines in a textarea? to add a String prototype inorder to get the linecount.

Categories