I have an div that sticks to the bottom of a page. Inside that div, a button pops up (after 2 seconds) that the user can click to close the housing div.
The housing div has a fixed position and the button is absolute with top:0;right:0;. But when the element is displayed (as shown in the snippet), the styling for the button changes to "font-size: 12px; font-family: tahoma; right: 0px; color: rgb(85, 85, 85); visibility: visible;", removing the original absolute. If I manually add it into it using the inspect element, it goes to the right as intended. But why does it not show in the first place?
adh('test', 320, 100);
function adh(dfp, len, hgt) {
var adhBase = document.createElement('div');
adhBase.id = dfp;
if (false) {
// is there mobile horizon???
} else {
adhBase.style = "z-index:9999;height:" + hgt + "px;position:fixed;bottom: 0;left: 50%;width:" + len + "px;transform: translateX(-50%);box-sizing: border-box;background-color:lightblue;";
}
document.body.appendChild(adhBase);
// Close button
var adhClose = document.createElement('button');
adhClose.id = 'closeBtn';
adhClose.style = 'font-size:12px;font-family:tahoma;position:absolute:top:0;right:0;border:1 px solid #ccc;color: #555;box-sizing:border-box:text-decoration:none;visibility:hidden';
adhClose.innerHTML = 'close';
document.getElementById(dfp).appendChild(adhClose);
console.log('3');
// function that closes the button
document.getElementById('closeBtn').addEventListener('click', function(e) {
e.preventDefault();
this.parentNode.style.display = 'none';
});
setTimeout(function() {
adhClose.style.visibility = "visible"
}, 2000);
}
Related
We are using drag & drop feature of HTML.
As you can see div width is 410px and if start dragging this div, its ghost image of it fades out completely. I have big/large images to display while dragging them and as they are big in size they start to fade out completely. Is there any problem ?
If I change div width to 210px then the ghost image looks fine. Then what's the problem with 410px is there any limit to it? If yes, how can I increase it ?
var els = document.getElementsByTagName('div');
for (var i = 0, l = els.length; i < l; i++) {
els[i].addEventListener('dragstart', function (e) {
e.dataTransfer.setData('text/plain', e.target.innerText);
});
}
div {
display: inline-block;
line-height: 300px;
text-align: center;
background: orange;
margin: 20px;
}
<div draggable="true" style="width:410px">Item 2</div>
hide original image using event.dataTransfer.setDragImage(new Image(), 0, 0);
on dragstart. onDrag get the ghost image, update position using event.pageX, evenet.pageY
onDrag(event){
event.preventDefault();
const parentElement = <HTMLDivElement>(document.querySelector('.darggable-ghost-wrapper'));
parentElement.style.position = "fixed";
parentElement.style.left = event.pageX + "px";
parentElement.style.top = event.pageY + 5 + "px";
parentElement.style.opacity = ArhitectUtlityConstants.GHOSTPREVIEW.ghostOpacity;
parentElement.style.border = "1px solid green !important";
}
I am creating a canvas alike without using canvas tag , by creating new div each time mouse is down, i can't figure out how to run a second event.
Like mousedown then mousemove event where the seconed event occur only after the first one is true?
also if you can help with the offset coordinates
var paintbox = document.getElementById("canvas");
var start = function() {
paintbox.addEventListener("mousedown", drawOnCanvas);
};
var newColor = document.getElementById("colorPick");
var drawOnCanvas = function() {
var newClick = document.createElement("div");
newClick.setAttribute("id", "smallDiv");
newClick.style.backgroundColor = newColor.value;
newClick.style.width = "10px";
newClick.style.height = "10px";
newClick.style.position = "absolute";
paintbox.appendChild(newClick);
}
Set the handler on the mousemove event instead of mousedown and in the handler check whether the mouse button is down.
It would be better to move the 10px/position style settings in a CSS class. Also, don't generate elements with the same id attribute value: that generates invalid HTML. Use a class instead.
For the positioning you can use the pageX and pageY properties of the event object.
Finally, as the events will be triggered on the small divs when you make small moves, an extra check might be necessary to verify the mouse is still in the paint box.
var paintbox = document.getElementById("canvas");
var start = function() {
paintbox.addEventListener("mousemove", drawOnCanvas);
};
var newColor = document.getElementById("colorPick");
var drawOnCanvas = function(e) {
if ((e.buttons & 1) === 0) return; // Mouse button is not down
// Extra check to see we are well within the box boundaries:
var box = paintbox.getBoundingClientRect();
if (e.clientX - 5 < box.left || e.clientX + 5 > box.right
|| e.clientY - 5 < box.top || e.clientY + 5 > box.bottom) return;
var newClick = document.createElement("div");
newClick.className = "smallDiv"; // Don't create duplicate ID; put CSS in class
newClick.style.backgroundColor = newColor.value;
paintbox.appendChild(newClick);
newClick.style.left = (e.pageX-5) + "px";
newClick.style.top = (e.pageY-5) + "px";
}
start();
#canvas {
height: 150px;
width: 300px;
border: 1px solid;
display: inline-block;
margin: 10px;
}
.smallDiv {
width: 10px;
height: 10px;
position: absolute;
}
Color: <input id="colorPick" type="color"><br>
<div id="canvas"></div>
Im trying to get the shapes to appear once after clicking. After 1.2 seconds it appears, then when clicked it disappears, then the whole process repeats. The problem is after a few clicks two shapes appear.
This is the link to the program.
https://jsfiddle.net/EyedFox/w98naLjx/2/
function show() {
var randomColor = colors[Math.floor(colors.length * Math.random())]; // Random color chosen
var randomX = Math.floor(Math.random() * 60); // random x axis margin
var randomY = Math.floor(Math.random() * 80); // random y axis margin
square = document.getElementById("square");
circle = document.getElementById("circle");
var shapeArray = [square, circle];
var randShape = shapeArray[Math.floor(shapeArray.length * Math.random())];
randShape.style.margin = randomX + "% " + randomY + "%";
randShape.style.backgroundColor = randomColor;
randShape.style.display = "block";
randShape.addEventListener("click", click);
function click() {
randShape.style.display = "none";
setTimeout(show, 1200);
}
}
setTimeout(show, 1200);
Your code keep adding click event listener to randShape, but it never cleans them those event. As a result, they keep being added and click (and thus show) will get executed several times per click. Try to add console.log('clicked on', randShape); at the beginning of your click function to see it. If by chance all the show execution selects the same shape, you'll see only this one on screen, but otherwise you'll get both.
Your click function should look like this:
function click() {
console.log('clicked on', randShape);
randShape.style.display = "none";
setTimeout(show, 1200);
randShape.removeEventListener('click', click); // cleaning after myself ;-)
}
(btw (function() { ... })() is not executed on load, but as soon as it is encountered by the javascript vm)
Here is a fiddle that fixes the issue.
Edited my response based on #autra response
I would probably completely clean the canvas before redrawing:
https://jsfiddle.net/c0L54uk3/
Essentially made a reset function like so:
function reset(){
square = document.getElementById("square").style.display = "none";
circle = document.getElementById("circle").style.display = "none";
randShape.removeEventListener("click", click);
}
And called it at the beginning of the click() function to reset the canvas like so:
function click() {
reset();
setTimeout(show, 1200);
}
Hope that helps.
Delegate Events Instead of Registering Them Individually
addEventListener() should be outside the callback function (i.e. show()). There's an event listener being added to the clicked tag but none of them are being removed. So when the 4th to 7th click occurs, the browser starts slowing down and that setTimeout is never 1.2 seconds because it will be cued to fire off which means it'll wait however long then wait 1.2 seconds. As the cue accumulates, the clicks will out race the setTimeout.
Register the parent tag, .container to listen to the click event event for all of its children tags. This pattern is called Event Delegation. In doing so, you can add the click event to an unlimited number of tags within .container using only one event listener instead of one for each shape.
The #triangle was never styled so it's an extra invisible div that floats around. In the demo I have styled the #triangle and added a .blank <div> outlined in gold (you can remove the .blank).
Demo
Fiddle
Details commented in demo
// Reference parent tag
var box = document.querySelector('.container');
function show() {
// Collect all .shape into a NodeList and convert into an array
var shapes = Array.from(document.querySelectorAll('.shape'));
var colors = ["yellow", "red", "green", "purple", "aqua", "chartreuse", "coral", "dodgerBlue", "deepPink"];
var rColor = colors[Math.floor(colors.length * Math.random())];
var rX = Math.floor(Math.random() * 60);
var rY = Math.floor(Math.random() * 80);
var rShape = shapes[Math.floor(shapes.length * Math.random())];
rShape.style.margin = rX + "% " + rY + "%";
// if #triangle change the border-bottom-color
if (rShape.id === 'triangle') {
rShape.style.borderBottomColor = rColor;
// otherwise change background-color
} else {
rShape.style.backgroundColor = rColor;
}
rShape.style.display = "block";
}
/*
Run show()
A setTimeout nor an IIFE is needed to initially run show()
Simply call it.
*/
show();
// Register box to click event...
box.addEventListener('click', function(e) {
// ...reference the clicked tag (i.e. .shape)...
var tgt = e.target;
// ...reference the registered parent tag...
var cur = e.currentTarget;
/*
...if the clicked tag IS NOT the registered parent tag...
*/
if (tgt !== cur) {
// ...then hide clicked element...
tgt.style.display = "none";
// ...and run show() in about 1.2 seconds
setTimeout(show(), 1200);
}
});
.container {
overflow: hidden;
height: 800px;
width: 80%;
background-color: rgb(0, 34, 85);
margin: 0 auto;
margin-top: 5em;
}
#square {
width: 80px;
height: 80px;
background-color: red;
margin-left: 0%;
margin-top: 10%;
display: none
}
#circle {
width: 100px;
height: 100px;
background: red;
border-radius: 50px;
display: none
}
#triangle {
width: 0;
height: 0;
border-left: 45px solid transparent;
border-right: 45px solid transparent;
border-bottom: 90px solid cyan;
display: none
}
.shape {
cursor: pointer
}
.blank {
outline: 10px solid gold
}
<div class="container">
<div id="square" class='shape'></div>
<div id="triangle" class='shape'></div>
<!--
This .blank represents what #triangle was before it
had any style.
-->
<div class='blank'></div>
<div id="circle" class='shape'></div>
</div>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/css/bootstrap.min.css" />
I have a chat box where people will beable to add there own message to it but my problem is that when new messages are added it does not scroll down to reveal the new message.
I fixed this by using this code
$('.panel-body').scrollTop($('.panel-body').height()*$('.panel-body').height());
(panel-body is the class of my scrolling div)
But the problem with this is that if a user wants to scroll back up at previous messages he or she will be forced back down to the bottom. What would be the best way to stop "auto scrolling" when the user scrolls but when the user scrolls back down or just loads the page it would start up again.
function addMsg(is_admin, name, mes, time) {
var newDiv = document.createElement("div");
newDiv.className = "row";
var p = document.createElement("p");
p.className = "text-muted name";
var p2 = document.createElement("p");
var text = document.getElementById("start");
var hr = document.createElement("hr");
var times = document.createElement("p")
text.appendChild(newDiv);
newDiv.appendChild(p);
p.innerHTML = name + ":";
newDiv.appendChild(p2);
newDiv.appendChild(times)
times.className = "time";
if (is_admin) {
p.style = "color: red;";
p2.innerHTML = mes;
times.innerHTML = "time: " + time;
} else {
p2.innerHTML = mes;
times.innerHTML = time;
}
newDiv.appendChild(hr);
This is my addMsg Function that i have already created
Here's a quick attempt I threw together.
By subtracting the element's height() (jQuery) from its scrollHeight (JS) and comparing that to the user's scrollTop (jQuery scroll position), we can determine if we're currently at the bottom of the scrollable container before the new message appears.
If we are at the bottom, then keep the user down there by setting the new scrollTop. Otherwise, don't change anything. Hope this helps!
Live demonstration:
function newMsg() {
// FOR DEMO (naming each message)
var count = $('.msg').length;
// shouldScroll will be true if we're at the bottom of the
// scrollable container before the new message appears
var $panel = $('.panel-body');
var shouldScroll = $panel[0].scrollHeight - $panel.height() <= $panel.scrollTop();
// this is where you append a new message to the container
$panel.append('<div class="msg">Message ' + count + '</div>');
// if we were at the bottom before the new message,
// then scroll to the new bottom of the container
if (shouldScroll) {
$panel.scrollTop($panel[0].scrollHeight);
}
}
// FOR DEMO (new message every .5 seconds)
setInterval(newMsg, 500);
.panel-body {
border: 1px solid #000;
overflow: auto;
width: 200px;
height: 200px;
}
.msg {
border-bottom: 1px solid #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="panel-body"></div>
I have a page with a large 100% width photo at the top and a title on top of the photo. I would like to have the fixed position title change color as you scroll past the photo. I have been able to create a working version in jsfiddle here:
http://jsfiddle.net/dtZDZ/647/
Here is the javascript (I am new to JS)
var tStart = 100 // Start transition 100px from top
,
tEnd = 300 // End at 300px
,
cStart = [255, 255, 255] // white
,
cEnd = [156, 156, 156] // black
,
cDiff = [cEnd[0] - cStart[0], cEnd[1] - cStart[1], cEnd[1] - cStart[0]];
$(document).ready(function () {
$(document).scroll(function () {
var p = ($(this).scrollTop() - tStart) / (tEnd - tStart); // % of transition
p = Math.min(1, Math.max(0, p)); // Clamp to [0, 1]
var cBg = [Math.round(cStart[0] + cDiff[0] * p), Math.round(cStart[1] + cDiff[1] * p), Math.round(cStart[2] + cDiff[2] * p)];
$("h1 a").css('color', 'rgb(' + cBg.join(',') + ')');
});
});
Unfortunately, once I start scrolling the h1 no longer changes color when I hover over it. Also when I try to open a page with this code inside chrome the text simply goes from white to black instead of the dark grey as I specified. Does anyone know how to fix either of these issues?
Thank you
Instead of setting the color explicitly I would instead use class switching:
var title = $('h1:first'),
titleText = title.find('a'),
titleTextHeight = titleText.height(),
meow = $('#meowmeow'),
meowBottom = meow.offset().top + meow.outerHeight();
$(document).ready(function () {
$(document).scroll(function () {
if ($(document).scrollTop() + titleTextHeight > meowBottom) {
titleText.addClass('bare');
} else {
titleText.removeClass('bare');
}
});
});
Then it is just a matter of selectors:
h1 a {
position:fixed;
color: white;
text-decoration:none;
padding: 5%;
font-size: 2em;
}
h1 a.bare {
color: rgb(156, 156, 156);
}
h1 a:hover, h1 a.bare:hover {
color: rgb(200, 200, 200)
}
http://jsfiddle.net/9PJ9g/1/
As far as the hover not working, the inline style that you are setting overrides the :hover state in your CSS.
Quick Fix:
h1 a:hover {
color: rgb(200, 200, 200)!important;
}
Also, the link doesn't work in jsFiddle by design because it is running in an iframe. If you are really tempted to do this for some reason though, then add target="_parent" to the anchor tag