Detect if .append is not possible? - javascript

I'm creating a modal window bookmarklet that allows you to quickly add content to my website. It all works fine and dandy except for non-html content, because then it cannot append data to the body. Instead, I'd like to do a simple location.href.
Current code:
if (typeof jQuery == 'undefined') {
var jQ = document.createElement('script');
jQ.type = 'text/javascript';
jQ.onload=runthis;
jQ.src = 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js';
document.body.appendChild(jQ);
} else {
runthis();
}
function runthis() {
if ($("#baasframe").length == 0) {
$("body").append("\
<div id='baasframe'>\
<div id='baasframe_veil' style=''>\
<p>Loading...</p>\
</div>\
<iframe src='http://example.com/submit.php?url="+encodeURIComponent(location.href)+"&title="+encodeURIComponent(document.title)+"' onload=\"$('#baasframe iframe').slideDown(500);\">Enable iFrames.</iframe>\
<style type='text/css'>\
#baasframe_veil { display: none; position: fixed; width: 100%; height: 100%; top: 0; left: 0; background-color: rgba(0,0,0,.50); cursor: pointer; z-index: 900; }\
#baasframe_veil p { color: white; font: normal normal bold 20px/20px Helvetica, sans-serif; position: absolute; top: 50%; left: 50%; width: 10em; margin: -10px auto 0 -5em; text-align: center; }\
#baasframe iframe { display: none; position: fixed; top: 10%; left: 10%; width: 80%; height: 80%; z-index: 999; border: 10px solid rgba(0,0,0,.5); margin: -5px 0 0 -5px; }\
</style>\
</div>");
$("#baasframe_veil").fadeIn(750);
}
$("#baasframe_veil").click(function(event){
$("#baasframe_veil").fadeOut(750);
$("#baasframe iframe").slideUp(500);
setTimeout("$('#baasframe').remove()", 750);
});
}
function getSelText() {
var s = '';
if (window.getSelection) {
s = window.getSelection();
} else if (document.getSelection) {
s = document.getSelection();
} else if (document.selection) {
s = document.selection.createRange().text;
}
return s;
}
How can I make it detect that the appending of data didn't work and direct it to a location.href instead?
Much obliged,
Dennis

Use document.documentElement.

Related

How to achieve the same function of position:sticky using jQuery or JavaScript?

I'm having a hard time figuring out why the code below doesn't work as expected.
What I'm trying to achieve is same functionality with position:sticky whereas when the scrolled reaches the top of the #second-header then fixes its position below the #header which is also fixed, however, the height of the #header is unknown which is I believe can be calculated using the function outerHeight(true) on JQuery.
Then after reaching out to the bottom of the #second-header-container, remove the fixed position of #second-header turning it back to normal position.
Due to browser compatibility issues and other customization, I cannot simply use the position:sticky of css.
It looks like my logic is wrong, and I need help.
jQuery(document).ready(function(){
var $document = jQuery(document);
var header = jQuery('#header');
var second_header = jQuery('#second-header-container').find('#second-header');
var second_header_container = jQuery('#second-header-container');
var second_header_offset = second_header.offset().top;
var second_header_container_offset = second_header_container.offset().top;
jQuery(window).scroll(function(){
var top_margin = header.outerHeight(true);
var second_header_height = second_header.outerHeight(true);
var second_header_container_height = second_header_container.outerHeight(true);
if( jQuery(window).scrollTop() > (second_header_offset - second_header_height) && jQuery(window).scrollTop() < second_header_container_height) {
second_header.addClass('fixer');
second_header.css({position:'fixed', top:top_margin, 'z-index':'999999'});
} else {
second_header.removeClass('fixer');
second_header.css({position:'relative', top:'0px', 'z-index':'0'});
}
});
});
*{
color: #FFFFFF;
padding: 0;
margin: 0;
}
.fixer{
position: fixed;
width: 100%;
}
#header, .banner, #second-header, .contents{
padding: 5px;
}
#header{
position: fixed;
width: 100%;
height: 74px;
z-index: 99999;
background-color: #000000;
}
.banner{
padding-top: 84px;
height: 200px;
background-color: #583E5B;
}
#second-header-container{
min-height: 300px;
background-color: #775F5E;
}
#second-header{
padding-bottom: 10px;
padding-top: 10px;
background-color: #4C3D3C;
}
.contents{
min-height: 200px;
background-color: #97A36D;
}
.footer{
background-color: #80A379;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header id="header">HEADER</header>
<div class="banner">BANNER</div>
<div id="second-header-container">
<div id="second-header">SECOND-HEADER</div>
<!--Other contents and elements...-->
</div>
<div class="contents">OTHER...</div>
<footer class="contents footer">FOOTER</footer>
To achieve this you need first check if the scroll height is near the second div header and within the height of the second div. Then add a class that make it stick below the main header. I have created a sticky class and added it while scrolling conditions are met.
Please check below code
jQuery(document).ready(function() {
var headerHeight = $('#header').outerHeight(true);
var secondHeaderContainer = $('#second-header-container');
const secondHeaderTopPos = secondHeaderContainer.offset().top;
const secondHeaderContainerHeight = $(secondHeaderContainer).height();
$(window).scroll(function() {
const scrollTop = $(this).scrollTop();
const secondContainerHeightEnd = secondHeaderContainerHeight + secondHeaderTopPos - $('#second-header').height() - headerHeight;
if (((secondHeaderTopPos - headerHeight) <= scrollTop) && (secondContainerHeightEnd >= scrollTop)) {
$('#second-header').addClass('sticky').css('top', headerHeight);
} else {
$('#second-header').removeClass('sticky');
}
});
});
* {
color: #FFFFFF;
padding: 0;
margin: 0;
}
.sticky {
position: fixed;
width: 100%;
top: 0;
left: 0;
}
.fixer {
position: fixed;
width: 100%;
}
#header,
.banner,
#second-header,
.contents {
padding: 5px;
}
#header {
position: fixed;
width: 100%;
height: 74px;
z-index: 99999;
background-color: #000000;
}
.banner {
padding-top: 84px;
height: 200px;
background-color: #583E5B;
}
#second-header-container {
min-height: 300px;
background-color: #775F5E;
}
#second-header {
padding-bottom: 10px;
padding-top: 10px;
background-color: #4C3D3C;
}
.contents {
min-height: 200px;
background-color: #97A36D;
}
.footer {
background-color: #80A379;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header id="header">HEADER</header>
<div class="banner">BANNER</div>
<div id="second-header-container">
<div id="second-header">SECOND-HEADER</div>
<!--Other contents and elements...-->
</div>
<div class="contents">OTHER...</div>
<footer class="contents footer">FOOTER</footer>

How to set delay show and hide with JS

I have my code in below, I want to delay 3 seconds before the show in and when showing 3 texts is done, the last text will hide after 3 seconds (not repeat). My code not working as I want.
And I want to add some CSS show and hide effect like this:
But I don't know how I can do it.
Can you help me?
Thanks
var x = document.getElementById('x'),
s = ['Hello', 'What can I help you ?', 'Click me to get some help!'];
(function loop() {
s.length && (x.innerHTML = s.shift(), setTimeout(loop, 3000));
return false;
})();
.speech-bubble {
position: relative;
padding:20px;
}
.speech-bubble:after {
content: '';
position: absolute;
right: 0;
top: 50%;
width: 0;
height: 0;
border: 10px solid transparent;
border-left-color: #00aabb;
border-right: 0;
margin-top: 15px;
margin-right: -10px;
}
span#x {
color: white;
font-family:roboto;
padding: 20px;
background: #00aabb;
position: absolute;
border-radius:5px;
right: 0px;
top: 50%;
}
.hideclass{display:none;}
<div class="speech-bubble"><span id="x" ></span></div>
Try the following code:
var x = document.getElementById('x');
s = ['Hello', 'What can I help you ?', 'Click me to get some help!'];
var times=0;
(function loop() {
var loops=setTimeout(loop, 3000);
if (times==3){
clearTimeout(loops);
$('#animate').addClass('bounceOut faster');
}
else{
s.length && (x.innerHTML = s.shift(), loops);
setTimeout( function(){$('#animate').removeClass('bounceIn faster');}, 2000);
$('#animate').addClass('bounceIn faster');
}
times++;
return false;
})();
.speech-bubble {
position: relative;
padding:20px;
}
.speech-bubble:after {
content: '';
position: absolute;
right: 0;
top: 50%;
width: 0;
height: 0;
border: 10px solid transparent;
border-left-color: #00aabb;
border-right: 0;
margin-top: 15px;
margin-right: -10px;
}
span#x {
color: white;
font-family:roboto;
padding: 20px;
background: #00aabb;
position: absolute;
border-radius:5px;
right: 0px;
top: 50%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.0/animate.min.css" rel="stylesheet"/>
<div class="animated bounceIn faster speech-bubble" id="animate"><span id="x" ></span></div>
times is used to count the loop count.
clearTimeout is to be done with loop.
$('#animate').removeClass('infinite bounceIn'); is to remove bounceIn animation
$('#animate').addClass('bounceOut'); is to add bounceOut animation
For faster animation, setTimeout is used to add delay.
var x = document.getElementById('x');
s = ['Hello', 'What can I help you ?', 'Click me to get some help!'];
var times=0;
(function loop() {
var loops=setTimeout(loop, 3000);
if (times==3){
clearTimeout(loops);
$('#animate').addClass('bounceOut faster');
}
else{
s.length && (x.innerHTML = s.shift(), loops);
setTimeout( function(){$('#animate').removeClass('bounceIn faster');}, 2000);
$('#animate').addClass('bounceIn faster');
}
times++;
return false;
})();
.speech-bubble {
position: relative;
padding:20px;
}
.speech-bubble:after {
content: '';
position: absolute;
right: 0;
top: 50%;
width: 0;
height: 0;
border: 10px solid transparent;
border-left-color: #00aabb;
border-right: 0;
margin-top: 15px;
margin-right: -10px;
}
span#x {
color: white;
font-family:roboto;
padding: 20px;
background: #00aabb;
position: absolute;
border-radius:5px;
right: 0px;
top: 50%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.0/animate.min.css" rel="stylesheet"/>
<div class="delay-1s animated bounceIn faster speech-bubble" id="animate"><span id="x" ></span></div>
Edit: for adding delay go add delay-xs on div class with x as the number of seconds you would like to delay. Don't forget to also update the timeout so that the animation work as intended.
Updated in snippet on <div class="delay-1s animated bounceIn faster speech-bubble" id="animate">
If you want to remove the delay just add the delay-1s on remove class in snippet. And add as needed.

Inserting input field to chat popup

I am trying to learn by creating a chat bar. I have created a side nav bar with users and once I click the chat pop up box will open at the bottom. I want to add input field to that chatbox.
I tried to add the input field but I just got half success; it just gets added to the body not at the bottom of the chat box.
chat.html
<script>
//this function can remove a array element.
Array.remove = function(array, from, to) {
var rest = array.slice((to || from) + 1 || array.length);
array.length = from < 0 ? array.length + from : from;
return array.push.apply(array, rest);
};
var total_popups = 0;
//arrays of popups ids
var popups = [];
function close_popup(id)
{
for(var iii = 0; iii < popups.length; iii++)
{
if(id == popups[iii])
{
Array.remove(popups, iii);
document.getElementById(id).style.display = "none";
calculate_popups();
return;
}
}
}
function display_popups()
{
var right = 220;
var iii = 0;
for(iii; iii < total_popups; iii++)
{
if(popups[iii] != undefined)
{
var element = document.getElementById(popups[iii]);
element.style.right = right + "px";
right = right + 320;
element.style.display = "block";
}
}
for(var jjj = iii; jjj < popups.length; jjj++)
{
var element = document.getElementById(popups[jjj]);
element.style.display = "none";
}
}
function register_popup(id, name)
{
for(var iii = 0; iii < popups.length; iii++)
{
//already registered. Bring it to front.
if(id == popups[iii])
{
Array.remove(popups, iii);
popups.unshift(id);
calculate_popups();
return;
}
}
var element = '<div class="popup-box chat-popup" id="'+ id +'">';
element = element + '<div class="popup-head">';
element = element + '<div class="popup-head-left">'+ name +'</div>';
element = element + '<div class="popup-head-right">✕</div>';
element = element + '<div style="clear: both"></div></div><div class="popup-messages"></div></div>';
element = element + '<div class="popup-bottom"><div class="popup-bottom"><div id="'+ id +'"></div><input id="field"></div>';
document.getElementsByTagName("body")[0].innerHTML = document.getElementsByTagName("body")[0].innerHTML + element;
popups.unshift(id);
calculate_popups();
}
//calculate the total number of popups suitable and then populate the toatal_popups variable.
function calculate_popups()
{
var width = window.innerWidth;
if(width < 540)
{
total_popups = 0;
}
else
{
width = width - 200;
//320 is width of a single popup box
total_popups = parseInt(width/320);
}
display_popups();
}
//recalculate when window is loaded and also when window is resized.
window.addEventListener("resize", calculate_popups);
window.addEventListener("load", calculate_popups);
</script>
style.css
<style>
#media only screen and (max-width : 540px)
{
.chat-sidebar
{
display: none !important;
}
.chat-popup
{
display: none !important;
}
}
body
{
background-color: #e9eaed;
}
.chat-sidebar
{
width: 200px;
position: fixed;
height: 100%;
right: 0px;
top: 0px;
padding-top: 10px;
padding-bottom: 10px;
border: 1px solid rgba(29, 49, 91, .3);
}
.sidebar-name
{
padding-left: 10px;
padding-right: 10px;
margin-bottom: 4px;
font-size: 12px;
}
.sidebar-name span
{
padding-left: 5px;
}
.sidebar-name a
{
display: block;
height: 100%;
text-decoration: none;
color: inherit;
}
.sidebar-name:hover
{
background-color:#e1e2e5;
}
.sidebar-name img
{
width: 32px;
height: 32px;
vertical-align:middle;
}
.popup-box
{
display: none;
position: absolute;
bottom: 0px;
right: 220px;
height: 285px;
background-color: rgb(237, 239, 244);
width: 300px;
border: 1px solid rgba(29, 49, 91, .3);
}
.popup-box .popup-head
{
background-color: #009688;
padding: 5px;
color: white;
font-weight: bold;
font-size: 14px;
clear: both;
}
.popup-box .popup-head .popup-head-left
{
float: left;
}
.popup-box .popup-head .popup-head-right
{
float: right;
opacity: 0.5;
}
.popup-box .popup-head .popup-head-right a
{
text-decoration: none;
color: inherit;
}
.popup-box .popup-bottom .popup-head-left
{
position:absolute;
left: 0px;
bottom: 0px
text-decoration: none;
color: inherit;
}
.popup-box .popup-messages
{
height: 100%;
overflow-y: scroll;
}
</style>
posting relevant parts hopw you can make sense of it.
HTML
<div class="popup-box chat-popup">
<div class="popup-head">
<div class="popup-head-left">name</div>
<div class="popup-head-right">✕</div>
<div style="clear: both"></div>
</div>
<div class="popup-messages"></div>
<div class="popup-bottom-container">
<div class="popup-bottom">
<div id="'+ id +'"></div>
<input type="text" id="field">
</div>
</div>
</div>
CSS
.popup-bottom
{
position:absolute;
left: 0px;
bottom: 10px;
text-decoration: none;
color: inherit;
}
.popup-box .popup-messages
{
height: 200px;
overflow-y: scroll;
}
It is always better to try out your layout in plain html before testing with js

I am not able to add and remove the classes

My Code:
window.addEventListener('scroll', scrollWhere);
function scrollWhere(e) {
var windowScroll = $(window).scrollTop();
var idScroll = $('.me').offset().top;
var height = $("#half-who").height();
if (windowScroll > idScroll) {
$('.me').addClass('me-fixed');
} else {
$('.me').removeClass('me-fixed');
}
}
I want to add a class when the scroll is past a certain point and remove it when is smaller than that certain point.
Get your idScroll value outside scrollWhere function as because it re-initiate calculation again and again and returns different values each time as because it has a fixed position. check below snippet for reference.
window.addEventListener('scroll', scrollWhere);
var idScroll = $('.me').offset().top;
function scrollWhere(e) {
var windowScroll = $(window).scrollTop();
//var height = $("#half-who").height();
if (windowScroll > idScroll) {
$('.me').addClass('me-fixed');
} else {
$('.me').removeClass('me-fixed');
}
}
.container {
height: 300vh;
width: 100%;
background-color: grey;
padding: 0;
margin: 0;
}
.content {
height: 100px;
width: 100%;
background-color: cyan;
}
.me {
height: 50px;
width: 100%;
background-color: red;
}
.me-fixed {
position: fixed;
top: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="content"></div>
<div class="me"></div>
</div>
Here's a simple example to add a class when scroll passing a certain point. Hope you can get an idea. >>> JSFiddle
$(window).scroll(function(){
var winH = $(window).scrollTop();
var ruler = $('.ruler').position().top;
if(ruler < winH){
$('.nav').addClass('me-fixed');
}
else{
$('.nav').removeClass('me-fixed');
}
});
body{
height: 1500px;
}
.nav{
height: 50px;
background: #a1bfbe;
color: #000;
width: 100%;
position: relative;
top: 250px;
text-align: center;
}
.nav.me-fixed{
background: #c2debf;
}
p{
font-size: 20px;
display: none;
}
.me-fixed p{
display: block;
}
.ruler{
position: fixed;
top: 150px;
border-bottom: 1px solid red;
width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="nav">
<p>
Fixed
</p>
</div>
<div class="ruler">
</div>
Also if you can provide the html and css structure, it will be easy to identify the issue.

lightbox with 2 different progress bar inside

I have created a lightbox in javascript and I have placed inside it a progress bar that I have also created it in javascript. My problem is that when I was trying to insert a second progress bar inside my lightbox only the first works. Any idea how to fix this?
this is my jsfiddle :http://jsfiddle.net/QHMKk/3/
and my code is this:
my javascript is:
function show() {
document.getElementById('light').style.display='block';
document.getElementById('fade').style.display='block';
}
function start() {
var stepSize = 50;
setTimeout((function() {
var filler = document.getElementById("filler"),
percentage = 0;
return function progress() {
filler.style.height = percentage + "%";
percentage +=1;
if (percentage <= 100) {
setTimeout(progress, stepSize);
}
}
}()), stepSize);
}
function start() {
var stepSize = 50;
setTimeout((function() {
var filler2 = document.getElementById("filler2"),
percentage = 0;
return function progress() {
filler.style.height = percentage + "%";
percentage +=1;
if (percentage <= 100) {
setTimeout(progress, stepSize);
}
}
}()), stepSize);
}
this is my html:
OPEN
<div id="light" class="white_content_stats">
<div class="prog">
<div id="filler" class="filler"></div>
</div>
</br>
<div class="prog2">
<div id="filler2" class="filler2"></div>
</div>
<a href = "javascript:void(0)" onclick = " document.getElementById('light').style.display='none';document.getElementById('fade').style.display='none'; ">
</br>CLOSE</a>
and this is my CSS:
.black_overlay_stats{
display: none;
position: absolute;
top: 0%;
left: 0%;
width: 100%;
height: 50%;
z-index:1001;
-moz-opacity: 0.6;
opacity:.70;
filter: alpha(opacity=70);
}
.white_content_stats {
display: none;
position:fixed;
top: 15%;
width: 300px;
padding: 30px;
margin-left:10px;
background-color:#F2F2F2;
border-radius: 0px;
box-shadow: 0px 0px 0px 20px rgba(0,0,0,0.6);
z-index:1002;
}
.prog {
height: 100px;
width: 30px;
border: 1px solid white;
position: relative;
}
.filler {
height: 0%;
width: 30px;
position: absolute;
bottom: 0;
background-color: grey;
}
.prog2 {
height: 100px;
width: 30px;
border: 1px solid white;
position: relative;
}
.filler2 {
height: 0%;
width: 30px;
position: absolute;
bottom: 0;
background-color: grey;
}
You define 2 functions with the same name start, so the second will be used and only it will be run, hence you can see only 1 progress bar works. You can modify the function start to make it accept an argument of id like this:
function start(id) {
//...
var filler = document.getElementById(id)
//...
}
Then call both start('filler') and start('filler2'):
OPEN
Updated Demo.
Note that you should not use inline event property.

Categories