Very basic Javascript code not functioning - javascript

I am new to JavaScript and I am trying to do small exercises to practice the concepts. I am facing an issue on this very basic onClick effect: The text is supposed to expand when you click on the button. The effect isn't applied and the console doesn't display any errors.
Here is my code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Test</title>
<link type = "text/css" rel = "stylesheet" href="style.css">
</head>
<body>
<div id="content">
<p>Has autem provincias, quas Orontes ambiens amnis imosque pedes Cassii montis illius celsi praetermeans funditur in Parthenium mare, Gnaeus Pompeius superato Tigrane regnis Armeniorum abstractas dicioni Romanae coniunxit.</p>
<p>Utque aegrum corpus quassari etiam levibus solet offensis, ita animus eius angustus et tener, quicquid increpuisset, ad salutis suae dispendium existimans factum aut cogitatum, insontium caedibus fecit victoriam luctuosam.</p>
<p>Montius nos tumore inusitato quodam et novo ut rebellis et maiestati recalcitrantes Augustae per haec quae strepit incusat iratus nimirum quod contumacem praefectum, quid rerum ordo postulat ignorare dissimulantem formidine tenus iusserim custodiri.</p>
<p>Has autem provincias, quas Orontes ambiens amnis imosque pedes Cassii montis illius celsi praetermeans funditur in Parthenium mare, Gnaeus Pompeius superato Tigrane regnis Armeniorum abstractas dicioni Romanae coniunxit.</p>
<p>Utque aegrum corpus quassari etiam levibus solet offensis, ita animus eius angustus et tener, quicquid increpuisset, ad salutis suae dispendium existimans factum aut cogitatum, insontium caedibus fecit victoriam luctuosam.</p>
<p>Montius nos tumore inusitato quodam et novo ut rebellis et maiestati recalcitrantes Augustae per haec quae strepit incusat iratus nimirum quod contumacem praefectum, quid rerum ordo postulat ignorare dissimulantem formidine tenus iusserim custodiri.</p>
</div>
<a id="show-more">Show More</a>
<script type="text/javascript">
var content = document.getElementById("content");
var button = document.getElementById("show-more");
button.onClick = function() {
if(content.className == "") {
content.className = "open";
button.innerHTML = "Show Less";
} else {
content.className = "";
button.innerHTML = "Show More";
}
};
</script>
</body>
</html>
CSS:
body {
background: #605770;
}
#content {
width: 400px;
max-height: 270px;
background: #EDCB96;
margin: 15px auto;
padding: 0 10px 10px;
font-family: sans-serif;
font-size: 12px;
color: black;
overflow: hidden;
-webkit-transition: max-height 0.7s;
-moz-transition: max-height 0.7s;
transition: max-height 0.7s;
}
#content.open {
max-height: 1000px;
-webkit-transition: max-height 0.7s;
-moz-transition: max-height 0.7s;
transition: max-height 0.7s;
}
#show-more {
width: 90px;
height: 20px;
text-transform: uppercase;
font-family: sans-serif;
font-size: 12px;
font-weight: bold;
color: #605770;
background: #EDCB96;
border: 1px solid #F7C4A5;
margin: 15px auto;
display: block;
text-align: center;
padding: 2px 5px;
cursor: pointer;
}
I have also tried to put my JavaScript in a separated file and link it on the HTML, but it doesn't help.

Change onClick to onclick:
button.onclick = function() {
if(content.className == "") {
content.className = "open";
button.innerHTML = "Show Less";
} else {
content.className = "";
button.innerHTML = "Show More";
}
};

Just you need to change onClick() to onclick(). You can find details here onclick

#askhan. It's very simple to solve the issue.
Practice makes you a good developer :)
Just you add the onclick function in the anchor Tag "a"
Show More
I used textSwap() function name. eg: Show More
Run that below code you get the output:
enter code here
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Test</title>
<link type = "text/css" rel = "stylesheet" href="style.css">
</head>
<body>
<div id="content">
<p>Has autem provincias, quas Orontes ambiens amnis imosque pedes Cassii montis illius celsi praetermeans funditur in Parthenium mare, Gnaeus Pompeius superato Tigrane regnis Armeniorum abstractas dicioni Romanae coniunxit.</p>
<p>Utque aegrum corpus quassari etiam levibus solet offensis, ita animus eius angustus et tener, quicquid increpuisset, ad salutis suae dispendium existimans factum aut cogitatum, insontium caedibus fecit victoriam luctuosam.</p>
<p>Montius nos tumore inusitato quodam et novo ut rebellis et maiestati recalcitrantes Augustae per haec quae strepit incusat iratus nimirum quod contumacem praefectum, quid rerum ordo postulat ignorare dissimulantem formidine tenus iusserim custodiri.</p>
<p>Has autem provincias, quas Orontes ambiens amnis imosque pedes Cassii montis illius celsi praetermeans funditur in Parthenium mare, Gnaeus Pompeius superato Tigrane regnis Armeniorum abstractas dicioni Romanae coniunxit.</p>
<p>Utque aegrum corpus quassari etiam levibus solet offensis, ita animus eius angustus et tener, quicquid increpuisset, ad salutis suae dispendium existimans factum aut cogitatum, insontium caedibus fecit victoriam luctuosam.</p>
<p>Montius nos tumore inusitato quodam et novo ut rebellis et maiestati recalcitrantes Augustae per haec quae strepit incusat iratus nimirum quod contumacem praefectum, quid rerum ordo postulat ignorare dissimulantem formidine tenus iusserim custodiri.</p>
</div>
<a id="show-more" onclick="textSwap();">Show More</a>
<script type="text/javascript">
var content = document.getElementById("content");
var button = document.getElementById("show-more");
function textSwap() {
if (content.className == "") {
content.className = "open";
button.innerHTML = "Show Less";
} else {
content.className = "";
button.innerHTML = "Show More";
}
};
</script>
</body>
</html>

Related

How to make an offCanvas Menu with multi-level sliding panes using jQuery similar to mmenu?

Off the bat I'd like to accept that there are a lot of libraries out there and there are a lot of similar questions on SO. But none address the issue at my hand.
I have created a OffCanvas Mobile-like sliding Menu inspired from mmenujs.
For achieving this I took the approach of making <div> panes with different z-index values and then translating them anchor click.
Is there a way to automatically create on.("click",function(){}); using jQuery to open the corresponding panes when clicked on the appropriate link.
Here's my code so far:
$(document).ready(function(){
$(".vjNav").prepend("<div class='vjNavHead' style='position:sticky;top:0;left:0;background:#222'><div style='flex-grow:1;height:50px;display:flex;align-items:center;justify-content:center'>HelloNav Heading</div><a id='closeNav' style='background:#111;height:50px;width:50px;display:flex;align-items:center;justify-content:center;padding:0'>x</a></div>");
addNavZindex();
$("#page").on("click",function(){ openNav(); });/* To make testing easier */
$("#overlay").on("click",function(){ closeNav(); });
$("#closeNav").on("click",function(){ closeNav(); });
function openNav(){
$("#navMain").toggleClass("TL");
$("#navbar").toggleClass("TR");
$("#page").toggleClass("TR");
$("html").toggleClass("noScroll");
$("#overlay").toggleClass("TL showOver");
};
function closeNav(){
$("html").toggleClass("noScroll");
$("#navMain").toggleClass("TL");
$("#overlay").toggleClass("TL showOver");
$("#navbar").toggleClass("TR");
$("#page").toggleClass("TR");
if($("#about").attr("class") == "vjNav"){
$("#about").toggleClass("TL");
}/* How can I escape coding closeNav for each and every pane manually? */
};
function addNavZindex(){
if( $("#navContainer").find("div").length ){
$(".vjNav").each(function(i){
$(this).attr('style', function(){
return "z-index: " + (20+i);
});
});
}
};
$("#aboutLink").on("click",function(){
$("#about").toggleClass("TL");
});/* How can I escape declaring onClick functions for each and every pane manually? */
});
html, body{
margin:0;padding:0;
overflow-x: hidden;
}
#page{
position: absolute;
top:0;left:0;
display: flex; flex-direction: column;
width: 100vw;min-height:100vh;height: 300vh;
padding: 0; margin:0;
background: orange;
transition: ease-in-out 500ms;
z-index: 990;
}
#navbar{
position: fixed; bottom: 0; left: 0;
width: 100vw; height: 5vh; min-height:40px;
background: forestgreen;
z-index: 991;
transition: ease-in-out 500ms;
}
#navMain,.vjNav{
position: fixed;
bottom:0;left:0;
background: #222;
display: flex;flex-direction: column;
width: 80vw; height: 100vh;
overflow-y: auto;
z-index: 20;
color: #ddd;
transition: ease-in-out 500ms;
}
.vjNavHead{
display: flex;flex-direction: row;
align-items: center; justify-content: space-between;
width: 100%;color: aqua;
font-size: 1.5rem;
box-shadow: inset #ddd 0 -1px;
}
.vjNav a{
color:#ddd;box-shadow: inset #ddd 0 1px 0 0;
text-decoration: none; font-size: 3vh;height: 6vh;line-height: 6vh;padding-left: 2vw;
display: flex; flex-direction: row;align-items: center; justify-content: space-between;
}
.vjNav a:hover, .vjNav a:focus{background: #111;}
.vjNav a#closeNav{box-shadow: inset #ddd 0 -1px, inset #ddd 0 0;}
#overlay{
position: fixed;
top:0;left:80vw;
display: flex;flex-direction: column;
background: rgba(0, 0, 0, 0.1);
width: 100vw;height: 100vh;
transition: all ease-in-out 500ms;
}
.showOver{
z-index: 999;
background: rgba(0, 0, 0, 0.7)!important;
}
.TL{
transform: translateX(-80vw);
}
.TC{
transform: translateX(0vw);
}
.TR{
transform: translateX(80vw);
}
.noScroll{
overflow: hidden;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<div id="navbar">
Hello
</div>
<div id="page" class="TC">
Hello
<p>Lorem ipsum dolor, sit amet consectetur adipisicing elit. Magnam exercitationem ipsam odit assumenda repellat. Sunt saepe nesciunt dolores culpa aspernatur, odit officia quis cumque iste reiciendis molestiae recusandae eum dolorum?</p>
</div>
<div id="overlay" class="TL"></div>
<div id="navContainer">
<div id="navMain" class="TL vjNav">
<a id="aboutLink" href="#about">About Us</a>
Contact
Hello
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Quibusdam alias autem ab adipisci, beatae ex quas sapiente voluptas eaque eos, commodi maiores fuga voluptatem! Ut facere necessitatibus aut enim sint.</p>
<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/>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequatur totam architecto distinctio cum nemo officia dolore voluptates enim quasi, neque dolorem culpa fuga corporis in, nesciunt nisi repudiandae officiis.</p>
</div>
<div id="about" class="TL vjNav">
About 01
About 02
About 03
About 04
About 05
</div>
<div id="about2" class="TL vjNav">
About 02-01
About 02-02
About 02-03
About 02-04
About 02-05
</div>
<div id="hello" class="TL vjNav">
hello 01
hello 02
hello 03
hello 04
hello 05
hello 06
hello 07
</div>
<div id="hello4" class="TL vjNav">
hello 01
hello 02
hello 03
hello 04
hello 05
hello 06
hello 07
</div>
</div>
</body>
If there is a better way to tackle this kind of menu please do guide...
You could try implementing something like this... Put it in a separate file and call it on the page.
/* PushMenu()
* ==========
* Adds the push menu functionality to the sidebar.
*
* #usage: $('.btn').pushMenu(options)
* or add [data-toggle="push-menu"] to any button
* Pass any option as data-option="value"
*/
+function ($) {
'use strict';
var DataKey = 'lte.pushmenu';
var Default = {
collapseScreenSize : 767,
expandOnHover : false,
expandTransitionDelay: 200
};
var Selector = {
collapsed : '.sidebar-collapse',
open : '.sidebar-open',
mainSidebar : '.main-sidebar',
contentWrapper: '.content-wrapper',
searchInput : '.sidebar-form .form-control',
button : '[data-toggle="push-menu"]',
mini : '.sidebar-mini',
expanded : '.sidebar-expanded-on-hover',
layoutFixed : '.fixed'
};
var ClassName = {
collapsed : 'sidebar-collapse',
open : 'sidebar-open',
mini : 'sidebar-mini',
expanded : 'sidebar-expanded-on-hover',
expandFeature: 'sidebar-mini-expand-feature',
layoutFixed : 'fixed'
};
var Event = {
expanded : 'expanded.pushMenu',
collapsed: 'collapsed.pushMenu'
};
// PushMenu Class Definition
// =========================
var PushMenu = function (options) {
this.options = options;
this.init();
};
PushMenu.prototype.init = function () {
if (this.options.expandOnHover
|| ($('body').is(Selector.mini + Selector.layoutFixed))) {
this.expandOnHover();
$('body').addClass(ClassName.expandFeature);
}
$(Selector.contentWrapper).click(function () {
// Enable hide menu when clicking on the content-wrapper on small screens
if ($(window).width() <= this.options.collapseScreenSize &&
$('body').hasClass(ClassName.open)) {
this.close();
}
}.bind(this));
// __Fix for android devices
$(Selector.searchInput).click(function (e) {
e.stopPropagation();
});
};
PushMenu.prototype.toggle = function () {
var windowWidth = $(window).width();
var isOpen = !$('body').hasClass(ClassName.collapsed);
if (windowWidth <= this.options.collapseScreenSize) {
isOpen = $('body').hasClass(ClassName.open);
}
if (!isOpen) {
this.open();
} else {
this.close();
}
};
PushMenu.prototype.open = function () {
var windowWidth = $(window).width();
if (windowWidth > this.options.collapseScreenSize) {
$('body').removeClass(ClassName.collapsed)
.trigger($.Event(Event.expanded));
}
else {
$('body').addClass(ClassName.open)
.trigger($.Event(Event.expanded));
}
};
PushMenu.prototype.close = function () {
var windowWidth = $(window).width();
if (windowWidth > this.options.collapseScreenSize) {
$('body').addClass(ClassName.collapsed)
.trigger($.Event(Event.collapsed));
} else {
$('body').removeClass(ClassName.open + ' ' + ClassName.collapsed)
.trigger($.Event(Event.collapsed));
}
};
PushMenu.prototype.expandOnHover = function () {
$(Selector.mainSidebar).hover(function () {
if ($('body').is(Selector.mini + Selector.collapsed)
&& $(window).width() > this.options.collapseScreenSize) {
this.expand();
}
}.bind(this), function () {
if ($('body').is(Selector.expanded)) {
this.collapse();
}
}.bind(this));
};
PushMenu.prototype.expand = function () {
setTimeout(function () {
$('body').removeClass(ClassName.collapsed)
.addClass(ClassName.expanded);
}, this.options.expandTransitionDelay);
};
PushMenu.prototype.collapse = function () {
setTimeout(function () {
$('body').removeClass(ClassName.expanded)
.addClass(ClassName.collapsed);
}, this.options.expandTransitionDelay);
};
// PushMenu Plugin Definition
// ==========================
function Plugin(option) {
return this.each(function () {
var $this = $(this);
var data = $this.data(DataKey);
if (!data) {
var options = $.extend({}, Default, $this.data(), typeof option == 'object' && option);
$this.data(DataKey, (data = new PushMenu(options)));
}
if (option === 'toggle') data.toggle();
});
}
var old = $.fn.pushMenu;
$.fn.pushMenu = Plugin;
$.fn.pushMenu.Constructor = PushMenu;
// No Conflict Mode
// ================
$.fn.pushMenu.noConflict = function () {
$.fn.pushMenu = old;
return this;
};
// Data API
// ========
$(document).on('click', Selector.button, function (e) {
e.preventDefault();
Plugin.call($(this), 'toggle');
});
$(window).on('load', function () {
Plugin.call($(Selector.button));
});
}(jQuery);

How can I change my code to jQuery instead of pure JS?

I am trying to set a function on jQuery instead of pure JS and I am getting an error:
15 | prev.css('height') = prev.scrollHeight + "px";
^ Expected an assignment or function call and instead saw an expression.
This is the actual code:
function expand(target)
{
let prev = target.previousElementSibling;
prev.style.height = prev.scrollHeight + "px";
target.style.display = "none";
}
#p {
height: 50px;
overflow: hidden;
}
#read-more {
background: linear-gradient(to bottom, rgba(255,0,0,0), rgba(255,255,255,1));
color: blue;
cursor: pointer;
position: absolute;
bottom: -20px;
padding: 15px 0;
text-align: center;
width: 100%;
}
#wrapper {
position: relative;
width: 200px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='wrapper'>
<p id='p'>Pinterest taxidermy et heirloom, ennui enim eu bicycle rights fugiat nesciunt commodo. High Life food truck jean shorts in. Blog asymmetrical cold-pressed photo booth. Neutra chia in, mustache Etsy nostrud plaid kogi. Magna polaroid stumptown aliqua put a bird on it gentrify, street art craft beer bicycle rights skateboard. DIY plaid gentrify, sustainable sapiente seitan mumblecore viral cardigan. Nisi pariatur laborum cornhole kitsch tempor fingerstache Bushwick. </p>
<div id='read-more' onclick="expand(this)">
READ MORE
</div>
</div>
And I am trying to set that here:
var toggleReadMore = function() {
$('#read-more').click(function(e) {
var prev = $(this).prev();
prev.css('height') = prev.scrollHeight + "px";
$(this).hide();
});
};
What am I doing wrong?
You cannot assign the value like that, you need to change it to something like
prev.css('height', prev.scrollHeight)
Where the second argument accepts the scroll height. In case of multiple CSS properties, you can pass an object like
prev.css({
height: 'some height here',
width: 'some width here'
});
** Change 3rd line like below **
var toggleReadMore = function() {
$('#read-more').click(function(e) {
var prev = $(this).prev();
prev.css('height', 50);
$(this).hide();
});
};

Move div on mouse move

I am trying to adopt a script I have found in this question, but changing the image to some content seems to be harder than I thought.
The script is quite simple and should make the #content div move inside the holder on mousemove:
// written by Roko C. Buljan
var $mmGal = $('#holder'),
$mmImg = $('#content'),
damp = 10, // higher number = smoother response
X = 0, Y = 0,
mX = 0, mY = 0,
wDiff, hDiff,
zeno;
function motion(){
zeno = setInterval(function(){ // Zeno's paradox "catching delay"
X += (mX-X) / damp;
Y += (mY-Y) / damp;
$mmGal.scrollLeft(X*wDiff).scrollTop(Y*hDiff);
}, 26);
}
// Get image size after it's loaded and run our fn
$mmImg.one('load', function() {
wDiff = ( this.width/$mmGal.width() )-1,
hDiff = (this.height/$mmGal.height())-1;
}).each(function() {
if(this.complete) $(this).load();
});
$mmGal.mousemove(function(e) {
mX = e.pageX-this.offsetLeft;
mY = e.pageY-this.offsetTop;
}).hover(function( e ){
return e.type=='mouseenter'? motion() : setTimeout(function(){
clearInterval(zeno);
},1200); // clear if not used
});
Why doesn't the div #content move (text and image)?
Example JSBIN
I have updated the demo and added content on moving background image.
Check the demo:
$(function(){
var $mmGal = $('#mmGal'),
$mmImg = $('#mmImg'),
damp = 10, // higher number = smoother response
X = 0, Y = 0,
mX = 0, mY = 0,
wDiff, hDiff,
zeno;
function motion(){
zeno = setInterval(function(){ // Zeno's paradox "catching delay"
X += (mX-X) / damp;
Y += (mY-Y) / damp;
$mmGal.scrollLeft(X*wDiff).scrollTop(Y*hDiff);
}, 26);
}
// Get image size after it's loaded and run our fn
$mmImg.one('load', function() {
wDiff = ( this.width/$mmGal.width() )-1,
hDiff = (this.height/$mmGal.height())-1;
}).each(function() {
if(this.complete) $(this).load();
});
$mmGal.mousemove(function(e) {
mX = e.pageX-this.offsetLeft;
mY = e.pageY-this.offsetTop;
}).hover(function( e ){
return e.type=='mouseenter'? motion() : setTimeout(function(){
clearInterval(zeno);
},1200); // clear if not used
});
});
*{margin:0;padding:0;}
.main-wrapper {
position: relative;
width:150px;
height:150px;
}
#mmGal{
position:relative;
margin: 20px auto;
width:412px;
height:220px;
overflow:hidden;
background:#eee;
z-index: 0;
}
.content {
position: absolute;
left: 0;
right: 0;
top:0;
color: #ffffff;
padding: 10px;
z-index: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="main-wrapper">
<div class="content">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. quae molestias ad dolores qui blanditiis, Quas eaque soluta quia ipsa? aliquam?</p>
</div>
<div id="mmGal">
<img id="mmImg" src="http://www.wired.com/images_blogs/rawfile/2013/11/offset_WaterHouseMarineImages_62652-2-660x440.jpg">
</div>
</div>
My original script uses a .load() for the underlay image to load. Since you don't have a background image to move - you don't need necessarily that code part.
Calculate w/hDiff inside the mousemove event.
Also, use jQuery's .outerWidth() and .innerWidth() for the calculation:
jQuery(function($) {
const $mm = $('#holder'),
$mmCont = $('#content'),
damp = 10; // 1 = immediate, higher number = smoother response
let X = 0, Y = 0,
mX = 0, mY = 0,
wDiff = 0, hDiff = 0,
zeno, tOut;
$mm.on({
mousemove(ev) {
wDiff = ($mmCont.innerWidth() / $mm.outerWidth()) -1,
hDiff = ($mmCont.innerHeight() / $mm.outerHeight()) -1;
mX = ev.pageX - this.offsetLeft;
mY = ev.pageY - this.offsetTop;
},
mouseenter() {
clearTimeout(tOut);
clearInterval(zeno);
zeno = setInterval(function() { // Zeno's paradox "catching delay"
X += (mX - X) / damp;
Y += (mY - Y) / damp;
// Use CSS transition:
// $mmCont.css({ transform: `translate(${-X * wDiff}px, ${-Y * hDiff}px)` });
// Use Scroll:
$mm[0].scrollTo(X * wDiff, Y * hDiff);
}, 26);
},
mouseleave() {
// Allow the image to move for some time even after mouseleave
tOut = setTimeout(function() {
clearInterval(zeno);
}, 1200);
}
});
});
#holder {
background: gray;
width: 100%;
position: relative;
overflow: hidden;
height: 180px;
}
#content {
width: 150%;
height: 600px;
background: lightgray;
padding: 40px;
}
<div id="holder">
<div id="content">
<div>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus dolore impedit dignissimos porro repellendus numquam aut quibusdam, consequuntur modi facere? Totam ut libero corporis sit sequi explicabo ab magni quaerat unde animi aliquid facere
necessitatibus, quae molestias ad dolores qui blanditiis, quisquam minima beatae autem iure. Neque animi tempore iste accusamus ut cum ipsam possimus, perspiciatis quia illo obcaecati sed molestiae amet architecto, nostrum cumque quaerat minima
minus, consequatur rem error nihil. Ipsa eveniet, praesentium suscipit optio blanditiis at, vel illum harum omnis quam. Quas eaque soluta quia ipsa? Illum inventore veritatis facilis eveniet voluptatibus atque laborum necessitatibus adipisci aliquam?</div>
<img src="https://i.stack.imgur.com/BfcTY.jpg">
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

Prevent divs from colliding

I have a game where users can chat. Every speech is appended to body as position absolute element with user x position as "left" CSS tag. They are also animated to go to top. I don't want them to have a colliding, vertically or horisontally.
Here's an example:
They don't have to be one on another, but they need to be "one after one"
I have tried a jquery each() and then remove 60 pixel from the current speech position. Here's my code:
var Speech = {
History: [],
New: function(user, text, int) {
var pos = getUserPosition(user).x + 18;
var speech = HTML.Speech.split('\n');
var maxInt = speech.length - 1;
if (int <= maxInt) {
var html = speech[int];
var random = Rand(10);
Speech.pushThemUp();
/** append here ect...
set left position...
$('#speech' + random).css("left", nLeft + "px"); **/
}
},
pushThemUp: function() {
$('.speech').each(function(i, obj) {
var newTop = parseInt($(this).css('top')) - 60;
$(this).css('top', newTop+'px');
});
},
Listener: function() {
var int = setInterval(function() {
$('.speech').each(function(i, obj) {
if(parseInt($(this).css('top')) < 0) {
$(this).remove();
} else {
var newTop = parseInt($(this).css('top')) - 10;
$(this).animate({'top': newTop+'px'});
}
});
}, 1000);
},
getHistory: function() {
return Speech.History;
}
};
Speech.Listener();
module.exports = Speech;
But it doesn't work. They can still have colliding like the example up.
How can I solve that?
Please note: in that example, Speech.Listener() wasn't called.
EDIT: finally, I think my current solution to loop over .speech class and then add top px is good, but why is it animated? Look at the gif, pushThemUp function don't have to animate the speech bubbles but directly edit position, how can I solve that?
I created a code snippet where messages appear and move upwards. When there's no space left, a scrollbar appears.
var box = document.getElementById("box");
var topp = 3;
function post(str) {
var obj = document.createElement("div");
obj.className = "chatObj";
obj.innerHTML = str;
box.appendChild(obj);
box.appendChild(document.createElement("br"));
var width = obj.clientWidth;
var height = obj.clientHeight;
obj.style.marginLeft = (box.clientWidth / 2 - width / 2) + "px";
var x = 15;
obj.style.top = (box.clientHeight - x - height) + "px";
var interval, ctop;
interval = setInterval(function() {
x += 4;
console.log(ctop, topp);
ctop = box.clientHeight - x - height;
obj.style.top = ctop + "px";
if (ctop <= topp) {
obj.style.top = topp + "px";
topp += height + 6;
clearInterval(interval);
}
}, 5);
}
setTimeout(function() {
post("Hi!");
}, 500);
setTimeout(function() {
post("Trollolo!");
}, 1500);
setTimeout(function() {
post("Lorem ipsum dolor sit amet, timeam aliquando ei cum, putent possim in usu, at causae pericula petentium has. In mea legere salutatus voluptaria. No vix ancillae accusata. Nec meis probo noster eu, ius no quas audire.<br><br>Qui quem nominavi ei. Pri nisl eirmod id. Has cetero vocent abhorreant no, at mei altera expetendis. Has id novum aeterno salutatus.<br><br>Prompta offendit et eos, eos an admodum comprehensam, ex velit doming dolorem mei. At has dolor alterum laoreet, id duo tollit libris contentiones. An mel recteque omittantur dissentiet, ex nam novum iuvaret. Per id alterum habemus gubergren.<br><br>Nulla possim mea in. Vis et postulant constituam. Viris vulputate vituperatoribus eu usu, wisi meis ex his. Prompta accumsan cum et, possim eligendi omittantur sed id. Eos ad nemore integre recusabo, agam doctus viderer ei pri, cu eius nonumes senserit vis. Qui iudico causae te.<br><br>Eam ne mandamus evertitur, case adversarium neglegentur duo ex, no cum nominati forensibus. Et vel putant deleniti. Illum aliquando voluptatibus per no, ei quo albucius phaedrum. Cu lorem appetere percipit sed, ubique epicuri ad eos, te eos diam nusquam persecuti. Eu qui meis illum eleifend, eam veniam vivendo no, nisl fierent in quo.");
}, 2500);
#box {
display: block;
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
background-color: tomato;
overflow: auto;
}
#box .chatObj {
position: absolute;
display: inline-block;
max-width: 80%;
background-color: white;
border-radius: 2px;
padding: 3px 6px;
margin: 3px 0;
box-shadow: 0 0 2px 1px rgba(0, 0, 0, 0.1);
font-family: Arial, sans-serif;
font-size: 14px;
}
#box .chatObj::after {
display: block;
position: absolute;
content: ".";
color: transparent;
height: 6px;
}
<div id="box"></div>
If you use position: relative and a wrapper element with display: block, you can get exactly what you want without having to worry about collision detection. The only thing you'll need to do is calculate the initial top value based on the players position minus the initial top position of the bubble (since using position: relative the bubbles will be added to the DOM bellow the last bubble).
See this simple jsfiddle. https://jsfiddle.net/straker/0n6jbupg/

Change Element Height as compared to Width in HTML/CSS

The width of the element changes as I type text between its tags. My question that I want some kind of relation of Width with Height. As the width gets longer, the height increases by the same but I don't want the height to exceed 35px nor start with below 5px.
The code I tried:
HTML:
<div class="btn bg-red">This buttons width expands as I write more and more text.</div>
CSS:
.btn {
padding-left: 10px;
padding-right: 10px;
display: inline-block !important;
border-radius: 6px;
color: #ffffff;
padding-top: 10px;
padding-bottom: 10px;
height: relative;
}
.bg-red{background-color:#F55C58;}
.bg-red:hover{background-color:#F44946}
I'm not sure if it is possible in CSS to do this.
Then I tried this:
HTML:
<div class="btn bg-red"><div class="auto">This buttons width expands as I write more and more text.</div></div>
CSS:
.btn {
padding-left: 10px;
padding-right: 10px;
display: inline-block !important;
border-radius: 6px;
color: #ffffff;
padding-top: 10px;
padding-bottom: 10px;
}
.auto {
height: 20%
}
.bg-red{background-color:#F55C58;}
.bg-red:hover{background-color:#F44946}
Javascript:
var cw = $('.auto').width();
$('.auto').css({'height':cw+'px'});
The second code doesn't seem to follow display:inline. It works when you change the code manually.
Find demo for First code here.
Find demo for Second code here.
Edit:
Understood Meaning: When the button/element has less text, the width is small and the same way, the height should act same but 20% less pixels. When the text is increased, the width increases and the height should also increase. The max length of Height can reach up to 35px but the Width is Infinite by default.
I don't know how do you add text on your div. Anyway, on the following snippets the eventlistener trigger is set to input since it's a contenteditable div (the text is added by the user throught keyboard).
Snippet #1:
document.getElementsByTagName("body")[0].onload=function(){equalize()};
var target = document.getElementById("target");
target.addEventListener("input", equalize);
function equalize() {
var x = target.offsetWidth;
target.style.height = x + "px";
}
#target {
display: inline-block;
background: skyblue;
}
<div id=target contenteditable="true">write here</div>
This second snippet is the same as the previous one, but now the height is 20% smaller than the width (it was equal on the previous example) plus have a max-height limit of 100px.
Snippet #2:
var target = document.getElementById("target");
document.getElementsByTagName("body")[0].onload=function(){equalize()};
target.addEventListener("input", equalize);
function equalize() {
var x = target.offsetWidth;
var reducedpart = x / 100 * 20;
var result = x - reducedpart;
if (result > 100) {
var result = 100;
}
target.style.height = result + "px";
}
#target {
display: inline-block;
background: skyblue;
}
<div id=target contenteditable="true">write here</div>
Same as before but using padding instead of height to let the text on center:
Snippet #3:
var target = document.getElementById("target");
document.getElementsByTagName("body")[0].onload=function(){equalize()};
target.addEventListener("input", equalize);
function equalize() {
var x = target.offsetWidth;
var reducedpart = x / 100 * 20;
var result = x - reducedpart;
if (result > 100) {
var result = 100;
}
var secresult = result / 2;
target.style.paddingTop = secresult + "px";
target.style.paddingBottom = secresult + "px";
}
#target {
display: inline-block;
background: skyblue;
padding-left: 15px;
padding-right: 15px;
}
<div id=target contenteditable="true">write here</div>
CSS-only workaround using padding instead of height:
Snippet #4:
.container {
vertical-align: bottom;
display: inline-block;
}
#a {
width: 100%;
padding-bottom: calc(80% - 1em);
background: gold;
}
#b {
width: 100%;
padding-top: calc(40% - 0.5em);
padding-bottom: calc(40% - 0.5em);
background: tomato;
}
<div class=container><div id=a contenteditable="true">write here</div></div>
<div class=container><div id=b contenteditable="true">write here</div></div>
In jquery there's a function .height() that get the current computed height for the html element in the given ID or Class. Getting the height value of your div.auto you can monitor the height increase. Given that, you can make a condition if ($('.auto').height() <= 35px) that limit it up to 35px .
Put this <script type="text/javascript" src="jquery-1.12.2.js"></script> in your <head> and that you have the latest JQuery library.
Here's the full implementation of code. Try it in your localhost, because sometimes it doesn't work on jsfiddle or likewise.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style media="screen">
.btn {
padding-left: 10px;
padding-right: 10px;
display: inline-block !important;
border-radius: 6px;
color: #ffffff;
padding-top: 10px;
padding-bottom: 10px;
}
.auto {
height: 20%
}
.bg-red{background-color:#F55C58;}
.bg-red:hover{background-color:#F44946}
</style>
<script type="text/javascript" src="jquery-1.12.2.js"></script>
</head>
<body>
<div class="btn bg-red"><div class="auto">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</div></div>
<script type="text/javascript">
var cw = $('.auto').width();
if ($('.auto').height() <= 35px) {
$('.auto').css({'height':cw+'px'});
}
</script>
</body>
</html>
Hope this will help

Categories