I want to create some divs and place the around the body. That means left , right, up and down. I create a div every time a client connect via socket. and here is the code
var parent = document.getElementById("#parent-div")
socket.on("isConnected", function(data) {
// Receive the 'data' and check if 'isConnected' is true
if(data.isConnected == true) {
parent.innerHTML += "<div class='new-div'></div>"
}
});
and here is the style of the div :
.ZE {
position: fixed;
width: 400px;
height: 100px;
background-color: #73AD81;
overflow: hidden;
border-radius: 20px 60px;
border: 2px solid #965D31;
}
how can i do that ?
Your code will work as you have it once you've made a few adjustments.
jsFiddle Demo
First, you have a number symbol (#) you don't need in your getElementById():
Should be:
var parent = document.getElementById("parent-div");
Next, create classes for the locations you want to place them in:
.ZE.left {
top: 50%;
transform: translateY(-50%);
}
.ZE.right {
right: 0;
top: 50%;
transform: translateY(-50%);
}
.ZE.up {
left: 50%;
transform: translateX(-50%);
}
.ZE.down {
left: 50%;
transform: translateX(-50%);
bottom: 0;
}
Up to you how you place them. Above is just one way to place them left/right/top/bottom and may not be the best way at that but I've based it on your existing code.
Lastly you'll want to add those classes, incrementally, or otherwise in your callback function:
// for demo purposes
var data = {
isConnected: true
},
classes = ['left', 'right', 'up', 'down'];
//socket.on("isConnected", function(data) {
// Receive the 'data' and check if 'isConnected' is true
// loop for demo purposes
for (var i = 0; i < 4; i++) {
if(data.isConnected === true) {
parent.innerHTML += "<div class='ZE " + classes[i] + "'></div>"
}
}
//});
var newDiv = document.createElement("div");
var parentDiv = document.getElementById("div_to_place_within");
parentDiv.appendChild(newDiv);
newDiv.id = "some_id";
newDiv.className = "some classnames";
createElement & appendChild
Related
The first function uses dollar ($) which loops the functions/variables ($slider, $.instagramFeed and slick). At the function end, outside I created another function called $("#instagram-feed-slider .slick-slide > figcaption").each(function(e), which is based on #dean-meehan's code from Wrapping css class to Hashtag(#) content & At(#) content.
I have moved the function to several parts inside the first function, but it does not work;
I added $(document).on to the seconf function, but no effect;
I added different variables with $(document).on, but no effect;
I removed e from function(e) and changed from $("#instagram-feed-slider .slick-slide > figcaption") to $(figcaption"), no effect.
I tested with Firefox's Console's "Run", the function worked and detected the matches of at and hashtags.
Here is the minimal JavaScript code:
(function ($) {
// (...)
const $slider = $('#instagram-feed-slider');
// (...)
$.instagramFeed({ // (...) });
// (...)
$.each(slides, function(id, slide) { /* (...)*/ });
$slider.on('init', function(slick) { /* (...)*/ }).slick({ /* (...)*/ });
// (...)
})(jQuery);
$("#instagram-feed-slider .slick-slide > figcaption").each(function(e)
{
var words = $(this).text().split(" ");
for (var i = 0; i < words.length; i++)
{
if (words[i].charAt(0) == "#") {
words[i] = `<span class="hashtag">${words[i]}</span>`;
}
if (words[i].charAt(0) == "#") {
words[i] = `<span class="at">${words[i]}</span>`;
}
}
$(this).html(words.join(" "));
});
I also provide a snippet to run:
(function ($) {
// instagram username
let username = "instagram";
// slide count (max ever returned in callback data for a user is 12)
let count = 12;
// instagram feed slider
const $slider = $('#instagram-feed-slider');
// grab our instagram feed
$.instagramFeed({
'username': username,
'container': false,
'display_profile': false,
'display_biography': true,
'display_captions': true,
'display_gallery': true,
'display_igtv': true,
'image_size': 160,
'lazy_load': true,
'callback': function(data) {
// view raw instagram callback data
// console.log(data);
// latest owner timeline media not videos
let media = data.edge_owner_to_timeline_media.edges;
// slider media data
let slides = {};
// each media function
$.each(media, function(i, item) {
// current slide index
let id = item.node.shortcode;
// set slides id as object
slides[id] = {};
// get media caption from item
let caption = item.node.edge_media_to_caption.edges;
// check media caption is an array
if($.isArray(caption)) {
// check if we have caption array item
if(caption[0]) {
// set caption as caption
slides[id].caption = caption[0].node.text;
}
}
// create thumb data object
let thumb_data = {};
// each item node thumb resource function
$.each(item.node.thumbnail_resources, function(i, thumb) {
// get thumb data width and src url
thumb_data[thumb.config_width] = thumb.src;
// add thumb data to our slides object
slides[id].media = thumb_data;
});
});
// use this console the our custom slick instagram slides data
//console.log(slides);
// iterator counter
let iterator = 0;
// each slides function
$.each(slides, function(id, slide) {
// add 1 to iterator
iterator++;
// if iterator is less than or equal to count
if (iterator <= count) {
// create our slide html string ( div > a > img )
let slickSlide = '';
// build our slick slide figure image with figcaption
slickSlide += '<figure>';
slickSlide += '<a href="https://www.instagram.com/p/' + id + '" target="_blank">';
slickSlide += '<img src="' + slide.media[640] + '" alt=""/>';
slickSlide += '</a>';
// if we have a caption
if(slide.caption) {
// add figcaption to figure
slickSlide += '<figcaption><p>' + slide.caption + '</p></figcaption>';
}
// close our slick slide figure
slickSlide += '</figure>';
// append figure slide to instagram feed slider div
$slider.append(slickSlide);
}
});
// init slider with slick
$slider.on('init', function(slick) {
// do stuff here when slick initializes
// slight delay so slick init completes render
setTimeout(function() {
// reveal the slider with opacity
$slider.addClass('slick-reveal');
// delay time .1 second
}, 100);
// then our slick options
}).slick({
mobileFirst: true,
dots: true,
infinite: true,
arrows: false,
adaptiveHeight: true,
autoplay: false,
slidesToShow: 2,
slidesToScroll: 2,
responsive: [{
breakpoint: 480,
settings: {
slidesToShow: 3,
slidesToScroll: 3
}
},
{
breakpoint: 600,
settings: {
slidesToShow: 4,
slidesToScroll: 4,
}
},
{
breakpoint: 1024,
settings: {
slidesToShow: 6,
slidesToScroll: 6
}
}
]
});
}
});
})(jQuery);
$("#instagram-feed-slider .slick-slide > figcaption").each(function(e) {
//Get full string as words
var words = $(this).text().split(" ");
for (var i = 0; i < words.length; i++) {
if (words[i].charAt(0) == "#") {
words[i] = `<span class="hashtag">${words[i]}</span>`;
}
if (words[i].charAt(0) == "#") {
words[i] = `<span class="at">${words[i]}</span>`;
}
}
$(this).html(words.join(" "));
});
body
{
margin: 0;
padding: 20px;
}
#instagram-feed-slider
{
height: 0;
opacity: 1;
transition: all 0.5s ease;
width: 1024px;
}
#instagram-feed-slider.slick-initialized
{
height: auto;
}
#instagram-feed-slider.slick-initialized.slick-reveal
{
opacity: 1;
}
#instagram-feed-slider .slick-slide
{
display: block;
height: auto;
margin: 0;
margin: 0;
position: relative;
background-color: #000000;
}
#instagram-feed-slider .slick-slide::before
{
content: "";
display: block;
padding-top: 100%;
position: relative;
}
#instagram-feed-slider .slick-slide> a
{
position: absolute;
display: block;
overflow: hidden;
top: 10px;
right: 10px;
bottom: 10px;
left: 10px;
}
#instagram-feed-slider .slick-slide> a> img
{
max-width: 100%;
max-height: 100%;
display: block;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 15px;
}
#instagram-feed-slider .slick-slide:hover> a> img
{
opacity: 0.25;
transition: all 0.8s ease;
}
#instagram-feed-slider .slick-slide> figcaption
{
font-family: "Helvetica", serif;
font-size: 80%;
hyphens: auto;
overflow-wrap: break-word;
word-wrap: break-word;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
text-align: center;
opacity: 0;
color: #FFFFFF;
padding: 10px;
overflow-y: scroll;
}
#instagram-feed-slider .slick-slide:hover> figcaption
{
opacity: 1;
transition: all 0.8s ease;
text-align: center;
}
.at
{
color: #c1d72c;
}
.hashtag
{
color: #bda3f7;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick-theme.min.css" rel="stylesheet"/>
<div id="instagram-feed-slider"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.instagramFeed/1.4.1/jquery.instagramFeed.min.js"></script>
Or check my pen https://codepen.io/gusbemacbe/pen/dypzNYW. Go to the line 171 of JavaScript.
.slick-slide is a class that gets added by Slick on initialization of the carousel. So, $("#instagram-feed-slider .slick-slide > figcaption") is returning an empty jQuery object. I'd recommend removing that class from the selector (i.e. $("#instagram-feed-slider figcaption"), or move that code block inside the init handler for slick.
I have the following code on codesandbox: https://codesandbox.io/s/highlighter-cv2kv?file=/src/index.js
I have a bunch of spans for every word in a phrase. I want to be able to create highlights based on a start and end time (every span has those details in dataset). Highlights need to be laid above the corresponding spans.
So far I've been able to highlight the start and stop word but I need to highlight every word between that interval.
Current state:
Desired state:
Any ideas on how can I do this in the most efficient way?
Using dataset and querySelectorAll
Working Demo
for (let range of ranges) {
parent.querySelectorAll('.will-play').forEach (span => {
if (span.dataset.start < range.start || span.dataset.end > range.end) {
return;
}
let highLightParent = document.createElement("div");
let highlight = document.createElement("div");
let pos = getPos(parent, span);
highlight.style.cssText = `position: absolute; top: ${pos.top}px; left: ${pos.left}px; width: ${span.offsetWidth}px; height: ${span.offsetHeight}px; background-color: yellow; opacity: 0.5; z-index: 1`;
highLightParent.appendChild(highlight);
parent.appendChild(highLightParent);
});
}
i have an i idea for you less js more css, with that you only need to toggle the class playing and will highlight the words:
body {
font-family: sans-serif;
}
.will-play {
position: inherit;
z-index: 1;
position: relative;
}
.will-play.playing::after {
z-index: 200;
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
background-color: yellow;
opacity: 0.5;
content: "";
}
I forgot the JS :
let ranges = { start: "80.9", end: "87.48" };
let spans = [...document.querySelectorAll("span.will-play")];
spans.map((item) => {
if(item.dataset.start>=ranges.start && item.dataset.end<=ranges.end){
item.classList.add('playing')
}
});
I am creating chinese checkers, I use span tag to create circles. Added only left padding to the top corner. I have two questions:
1) Why rows seem to have distance between them, but not columns.
2) To fix 1) I added padding-left, but instead of adding distance the padding became part of the circle, why?
Here's the link how it looks:
Here's part of code:
.player0{
height: 40px;
width: 40px;
padding-right: 5px;
background-color: transparent;
border-radius: 50%;
display: inline-block;
}
divs += "<span class='player"+fullBoardArr[fullArrIter]+" 'onclick='send()'></span>"
divs += "<div class='clear_float'> </div>" //for separation of rows
As I said in comments, you need to use margin instead of padding.
I would not use "clear_float" (I assume this is about the float CSS property). Instead wrap elements that belong in the same row, in a separate div element.
From the image you included, it seems that you have a problem in aligning the cells. You can use many ways to solve this, but as your board is symmetric horizontally (ignoring the colors), you can just use text-align: center.
I had some fun in creating JavaScript logic for the board itself. You may find some aspects interesting to reuse:
class Cell {
constructor(rowId, colId) {
this._value = 0;
this.rowId = rowId;
this.colId = colId;
this.elem = document.createElement("span");
this.elem.className = "cell";
this.selected = false;
}
get value() {
return this._value;
}
set value(value) {
this._value = value;
this.elem.style.backgroundColor = ["", "grey", "blue", "red"][value];
}
toggleSelected() {
this.selected = !this.selected;
this.elem.classList.toggle("selected", this.selected);
}
}
class Board {
constructor() {
this._container = document.createElement("div");
this._container.className = "board";
this.elemMap = new Map;
this.grid = [[0,0,0,0,2,0,0,0,0,0,0,0,0],
[0,0,0,0,2,2,0,0,0,0,0,0,0],
[0,0,0,0,2,2,2,0,0,0,0,0,0],
[0,0,0,0,2,2,2,2,0,0,0,0,0],
[3,3,3,3,1,1,1,1,1,4,4,4,4],
[0,3,3,3,1,1,1,1,1,1,4,4,4],
[0,0,3,3,1,1,1,1,1,1,1,4,4],
[0,0,0,3,1,1,1,1,1,1,1,1,4],
[0,0,0,0,1,1,1,1,1,1,1,1,1]];
// create the data structure for the game and produce the corresponding DOM
this.grid.forEach((row, rowId) => {
let div = document.createElement("div");
row.forEach((value, colId) => {
if (!value--) return;
let cell = row[colId] = new Cell(rowId, colId);
cell.value = value;
div.appendChild(cell.elem);
this.elemMap.set(cell.elem, cell);
});
this._container.appendChild(div);
});
}
set container(elem) {
elem.appendChild(this._container);
}
getEventCell(e) {
return this.elemMap.get(e.target);
}
set selected(cell) {
if (this._selected) {
this._selected.toggleSelected();
this._selected = null;
}
if (!cell) return;
cell.toggleSelected();
this._selected = cell;
}
get selected() {
return this._selected;
}
move(cellFrom, cellTo) {
// TODO: Implement the real move rules here
if (!cellFrom.value) return; // must move a piece
if (cellTo.value) return; // capturing not allowed
cellTo.value = cellFrom.value;
cellFrom.value = 0;
board.selected = null;
}
}
let container = document.querySelector("#container");
let board = new Board();
board.container = container;
container.addEventListener("click", e => {
let cell = board.getEventCell(e);
if (!cell) return; // click was not on a cell
if (!board.selected || cell.value) {
board.selected = cell;
} else {
board.move(board.selected, cell);
}
});
.board {
text-align: center;
margin-left: auto; margin-right: auto;
}
.cell {
height: 15px;
width: 15px;
margin: 0px 2px;
border: 1px solid;
border-radius: 50%;
display: inline-block;
}
.selected {
border-color: orange;
}
<div id="container"></div>
You can click to select a piece and then click again on an empty spot to move it there.
Use margin instead of padding:
.player0{
height: 40px;
width: 40px;
margin-right: 5px;
background-color: transparent;
border-radius: 50%;
display: inline-block;
}
As an easy-to-remember quick reference, margin changes the position starting from outside the element border, padding from the inside
I am writing a simple jQuery plugin for my purpose, which:
creates a background div (for blocking purposes, like a modal dialog). (referenced with backDiv)
shows that background.
shows $(this).
removes background and hides $(this) when background clicked.
I am able to do all of these except 4th one: As I can't save a reference to the background div, I cannot get it back and remove it.
I tried $(this).data('backDiv',backDiv); and $(this)[0].backDiv = backDiv;
I know that there are various plugins that does this including the jQuery's own dialog function, but I want to create my own version.
I cannot keep this variable globally, so, how can I keep a reference to backDiv in a jQuery object, (or DOM object?) if that's even possible at all?
update: I allow multiple of these elements show on top of each other: Nested modal dialogs.
update-2:
(function($) {
$.fn.showModal = function() {
var backDiv = $('<div style="width: 100%; height: 100%; background-color: rgba(55, 55, 55, 0.5); position:absolute;top:0px;left:0px;">This is backDiv</div>');
$(this).data('backDiv', backDiv);
$('body').append(backDiv);
//TODO: bringToFront(backDiv);
$(this).show();
//TODO: bringToFront($(this);
var thisRef = $(this);
backDiv.click(function() {
thisRef.closeModal();
});
return $(this);
};
$.fn.closeModal = function() {
//PROBLEM (null): var backDiv = $(this).data('backDiv');
//backDiv.remove();
$(this).data('backDiv', '');
$(this).hide();
}
}(jQuery));
$(document).ready(function() {
$('#a').showModal();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="a" style="display:none;z-Index:2;background:red; width: 100px; height:50px;position:absolute"></div>
I suggest you to work in terms of complex dom objects, something similar angular directives, basically, you have to work with components that are represented in the dom as Group of Objects.
So, following what I'm saying, your modal component should be something like that:
var Modal = (function($) {
var tpl = '<div style="display:none;" class="modal"><div class="modal-backdrop"></div><div class="modal-content"></div></div>';
function Modal(container) {
var self = this;
this.container = $(container || 'body');
this.tpl = $(tpl).appendTo(this.container);
this.content = $('.modal-content', this.tpl);
this.backdrop = $('.modal-backdrop', this.tpl);
this.isOpened = false;
this.ANIMATION_DURATION = 500;
this.backdrop.click(function(e) { self.toggle(e) });
}
Modal.prototype.show = function(cb) {
var self = this;
cb = $.isFunction(cb) ? cb : $.noop;
this.tpl.fadeIn(this.ANIMATION_DURATION, function() {
self.isOpened = true;
cb();
});
return this;
};
Modal.prototype.hide = function(cb) {
var self = this;
cb = $.isFunction(cb) ? cb : $.noop;
this.tpl.fadeOut(this.ANIMATION_DURATION, function() {
self.isOpened = false;
cb();
});
return this;
};
Modal.prototype.toggle = function() {
if(this.isOpened) {
return this.hide();
}
return this.show();
};
Modal.prototype.setContent = function(content) {
this.content.html($('<div />').append(content).html());
return this;
};
return Modal;
})(window.jQuery);
function ExampleCtrl($) {
var modal = new Modal();
modal.setContent('<h1>Hello World</h1>');
$('#test').click(function() {
modal.show();
});
}
window.jQuery(document).ready(ExampleCtrl);
.modal {
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
.modal .modal-backdrop {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
background: rgba(0, 0, 0, .8);
}
.modal .modal-content {
width: 300px;
height: 150px;
background: #fff;
border: 1px solid yellow;
position: absolute;
left: 50%;
top: 50%;
margin-left: -150px;
margin-top: -75px;
line-height: 150px;
text-align: center;
}
h1 {
line-height: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="test">Test Modal</button>
Add data-backDiv="" into you dynamic modal div
Change below
var backDiv = $('<div data-backDiv="" style="width: 100%; height: 100%; background-color: rgba(55, 55, 55, 0.5); position:absolute;top:0px;left:0px;">This is backDiv</div>');
In order to retrive data attribute value using JQuery use following code
Syntax
$('selector').data('data-KeyName');
Example
1. $(this).data('backDiv'); // use to retrive value or
2. var temp=$(this).data('backDiv'); // use to retrive value and assign into variable
I am creating a learning module for an education company where i create 25 animal sprites (canvas with an image in it) and put them in a farm (div with a background image). I then reorder their z-index according to their location on the background, so that closer sprites will be on top of farther ones (both the background DIV and the sprites are position:absolute;).
This is the function that rearranges the sprites:
Array.prototype.sortIndices = function (func) {
var i = j = this.length,
that = this;
while (i--) {
this[i] = { k: i, v: this[i] };
}
this.sort(function (a, b) {
return func ? func.call(that, a.v, b.v) :
a.v < b.v ? -1 : a.v > b.v ? 1 : 0;
});
while (j--) {
this[j] = this[j].k;
}
}
function rearrangeSprites() {
var zSprites = new Array();
for (var i = 0; i < sprites.length; i++) {
var a = $('#sprite_'+i).css('bottom');
a = a.substr(0, a.length - 2);
zSprites[i] = { b : -a*1 };
}
zSprites.sortIndices(function(a,b) { return a.b - b.b; });
for (var i = 0; i < zSprites.length; i++) {
spriteObjects[zSprites[i]].style.zIndex = (1001 + i) + '';
}
}
It works great in IE and Firefox, but Chrome doesn't respect the z-index order.
any ideas?
Response to answers:
justspamjustin: Tried negative z-indices, as the article seemed to note, at some point. also tried reordering the objects, using this code:
$('.sprite').detach();
for (var i = 0; i < zSprites.length; i++) {
$('#Stage_udi_meadow').append(spriteObjects[zSprites[i]]);
spriteObjects[zSprites[i]].style.zIndex = (i + 1000) + '';
}
nada!
Francis: it would be quite a thing to replace the canvases with, say... DIVs, as a lot of code is built around the canvas features. I also need it to be canvases, because i am using transparency, PNG shadows and doing hit tests for the drag, which will not work with a simple DIV, so I will save this delicious option for last.
apsillers: CSS (as requested):
for the sprites:
element.style {
width: 60.674351585014406px;
height: 60.674351585014406px;
left: 204.55043227665706px;
top: 22.550432276657062px;
cursor: pointer;
z-index: 1003;
}
.sprite {
background-repeat: no-repeat;
margin: 0px;
padding: 0px;
overflow: hidden;
position: absolute;
z-index: 140;
}
.EDGE-122375087, .EDGE-122375087 * {
-webkit-transform: translateX(0px);
}
for the background:
element.style {
position: absolute;
margin: 0px;
left: 0px;
top: 177px;
width: 566px;
height: 347px;
right: auto;
bottom: auto;
background-size: 100%;
background-image: url(http://localhost:9090/cet_html5/publish/images/udi_meadow.png);
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
opacity: 1;
background-position: 0px 0px;
background-repeat: no-repeat no-repeat;
}
#Stage_udi_meadow {
}
.EDGE-122375087, .EDGE-122375087 * {
-webkit-transform: translateX(0px);
}
user agent stylesheetdiv {
display: block;
}
Inherited from body
Style Attribute {
cursor: auto;
}
Sometimes z-index can be a bit tricky. This article from the W3 may be of some help. But that spec may be a bit confusing. If I can't get z-index to work, then I make sure that my elements in the DOM are ordered properly. Generally elements lower in the DOM, have a higher visibility preference. So under some conditions, this might be true:
<div style="z-index:9999">I'm on bottom</div>
<div>I'm on top</div>
Try reordering the elements in the DOM.