I have a bunch of posts and each one has a setting btn and a setting list, so in mobile version, I want to show the setting list from the bottom of the screen wherever the user is rightnow like Youtube, Facebook & Quora.
<button>Click Me 1</button>
<div class="setting">
<ul>
<li>Save</li>
<li>Edit</li>
<li>Delete</li>
<li>Report</li>
<li>Close</li>
</ul>
</div>
<script>
const btns = document.querySelectorAll('button'),
settingLists = document.querySelectorAll('.setting');
for (let i = 0; i < btns.length; i++) {
const btn = btns[i];
const settingList = settingLists[i];
btn.addEventListener('click', ()=>{
settingList.style.position = 'absolute';
settingList.style.display = 'block';
const settingListTop = btn.getBoundingClientRect().top + btn.getBoundingClientRect().height + btn.getBoundingClientRect().bottom - settingList.getBoundingClientRect().height ;
console.log(`${settingListTop}`);
settingList.style.top = `${settingListTop}`; /*******/
settingList.style.width = '99%';
})
}
</script>
the js code above really makes sense, I am getting the bounding dimensions using getBoundingClientRect() and it gives me some right results in the console, but it doesn't assign this variable value to the top of the setting div element in this line of code
settingList.style.top = ${settingListTop};
So how can I assign a variable value to the bottom of an element OR is there another way to make this task in JS?
You can use window.matchMedia() option to check for viewport width and then apply the styles accordingly from js.
Why not just edit css styles from js?
Related
I tried to set the same class imagens-giratorias to two elements or to set imagens-giratorias and imagens-giratorias-2. The class worked in first element, and the same class stopped of animating in the second element.
[I provide the JSFiddle at the end.]
Check the #rafaelcastrocouto's original code at https://stackoverflow.com/a/59524483/8041366. If you prefer reading the complete code here, here is the code taken from there, but with a bit modified:
var counter = 1;
var div = document.querySelector('.imagens-giratorias');
var imagens = document.querySelectorAll('.imagens-giratorias img');
var showNext = function () {
counter++;
if (counter > 3) counter = 1;
div.classList.remove('imagem1', 'imagem2', 'imagem3')
div.classList.add('imagem'+counter);
};
for (var img of imagens) {
img.addEventListener('animationend', showNext);
}
And small CSS snippet:
<div class="section-2">
<div class="item-2">
<div class="imagens-giratorias imagem1">
</div>
</div>
</div>
<div class="section-3">
<div class="item-2">
<div class="imagens-giratorias imagem1">
</div>
</div>
Or
<div class="section-3">
<div class="item-2">
<div class="imagens-giratorias-2 imagem1">
</div>
</div>
1st solution, that same original code above I am referring.
2nd solution:
var div = document.querySelector('.imagens-giratorias, .imagens-giratorias-2');
var imagens = document.querySelectorAll('.imagens-giratorias img, .imagens-giratorias-2 img');
3rd solution
var div = document.querySelector('[class^=imagens-giratorias]');
var imagens = document.querySelectorAll('[class^=imagens-giratorias] img');
4th solution
const contador = 1;
const div = document.querySelector('.imagens-giratorias');
const imagens = document.querySelectorAll('.imagens-giratorias img');
I also tried to use from multiple selectors with document.querySelectorAll. No luck.
But all these solutions did not work.
JSFiddle
Please pay attention to two elements. While one element will always animate, another will stop of animating.
https://jsfiddle.net/gusbemacbe/mbp84u6r/2/
If I understand you correctly you're trying to grab elements that have a class name starting with imagens-giratorias. If that's the case, use the ^ attribute selector as shown below:
document.querySelectorAll("[class^="imagens-giratorias"]")
Update:
Based on your update it appears that only one of your two divs' images is animating but in reality they're stacked on top of each of other. Feel free to use whatever layout method you want but for demonstration's sake I floated one left and the other right. Other that it was a matter of looping through your divs and assigning your function to their child images as so:
var divs = document.querySelectorAll('.imagens-giratórias');
var contador = 1;
var mostrarPróximo = function(div) {
contador++;
if (contador > 3) contador = 1;
div.classList.remove('imagem1', 'imagem2', 'imagem3')
div.classList.add('imagem' + contador);
};
Array.from(divs).forEach(function(div, index) {
var images = div.querySelectorAll('img');
Array.from(images).forEach(function(img) {
img.addEventListener('animationend', mostrarPróximo.bind(null, div));
});
});
https://jsfiddle.net/1r6yjf5s/
I'd like to render the section id="zero" data-section value in the h2 in my footer section dynamically. Since all of my pages will have different data-section values, I'm hoping we can target the section id="zero". This way I can use only one footer across my site. I am just not versed in javascript or jQuery to properly assign and call. I know there is document.getElementById('zero') but then getting the value from data-section and having it appear within my H2 I am not clear on.
<section id="zero" class="section-wrap" data-section="Page Name"></section>
<section id="footer">
<h2></h2>
</section>
Here's some Javascript that should help.
//Get the data-section value
let val = document.getElementById('zero').dataset.section;
//find the first h2 inside footer section
let header = document.getElementById('footer').getElementsByTagName("h2")[0];
//set the value
header.textContent = val;
Vanilla JS way
function start(){
// Find element with id="zero"
const section = document.querySelector('#zero');
// Find the h2 element nested inside an element with id="footer"
const footer = document.querySelector('#footer h2');
// Get value of data-section attribute
const dataSectionValue = section.getAttribute('data-section');
// Set value in your h2 tag
footer.innerText = dataSectionValue;
}
window.onload = start;
jQuery way
$(document).ready(function(){
const section = $('#zero');
$('#footer h2').text(section.data('section'));
});
I have this code for smooth scrolling, it works great but only for one "clickme" id, how could i use this code for multiple tabs whit i++
<div class="navbar">
<button type="button" id="clickme1">Scroll to red section!</button>
<button type="button" id="clickme2">Scroll to blue section!</button>
</div>
<div class="second" id="second">Hello</div>
<div class="tab1" id="tab1">The start of the red section!</div>
<div class="tab2" id="tab2">The start of the blue section!</div>
and here is the pure javascript that i want to use, please do not recommend me jQuery and anchor navigation.
document.getElementById('clickme1').addEventListener('click', function() {
var header = document.querySelectorAll('.navbar');
aim = -header[0].clientHeight;
initial = Date.now();
smoothScroll(document.getElementById('tab1'));
});
*******or more simplified, how can i make this code shorter:*******
document.getElementById('clickme1').addEventListener('click', function() {
var header = document.querySelectorAll('.navbar');
aim = -header[0].clientHeight;
initial = Date.now();
smoothScroll(document.getElementById('tab1'));
});
document.getElementById('clickme2').addEventListener('click', function() {
var header = document.querySelectorAll('.navbar');
aim = -header[0].clientHeight;
initial = Date.now();
smoothScroll(document.getElementById('tab2'));
});
here is JSFIDDLE
You can do something like following
// Get buttons
var buttons = document.getElementsByTagName('button');
for (var i = 0; i < buttons.length; i++) {
// Iterate over buttons and add handler
buttons[i].addEventListener('click', clickHandler, false);
}
// Handler function
function clickHandler(){
var counter = this.id.substring(7); // Substring id to get counter
var header = document.querySelectorAll('.navbar');
aim = -header[0].clientHeight;
initial = Date.now();
smoothScroll(document.getElementById('tab'+counter));
}
Note : As you can have some other buttons on your page and do not want to add this handler to them, so, in place of tag name selector, I will suggest you to add a specific class to the button elements and then use class selector to get elements.
You should consider using proper anchor links with progressive enhancement for smooth scrolling. This would involve either changing the buttons to <a> tags or just wrapping them:
<div class="navbar">
<button type="button">Scroll to red section!</button>
<button type="button">Scroll to blue section!</button>
</div>
You can then use event delegation to trap clicks on any anchor link at the document level:
document.addEventListener('click', function (evt) {
var tgt = evt.target;
if (tgt.tagName === 'A' && tgt.getAttribute('href')[0] === '#') {
smoothScroll(document.getElementById(tgt.hash.slice(1)));
}
});
There are numerous benefits to this approach, including:
Ability to hotlink to a section by copy/pasting the URL
Graceful degrading when JavaScript is not present.
I Have created Custom Alert Box in Javascript . I Have added text with images. but It is not align proberly. It came some thing like this.
I am trying to add the correct mark and text with same line, how can I achieve this. can anyone please help me. I have added my Custom alert box Function below.
function createCustomAlert(txt, string_url,fd) {
// shortcut reference to the document object
d = document;
// if the modalContainer object already exists in the DOM, bail out.
if (d.getElementById("modalContainer")) return;
// create the modalContainer div as a child of the BODY element
mObj = d.getElementsByTagName("body")[0].appendChild(d.createElement("div"));
mObj.id = "modalContainer";
// make sure its as tall as it needs to be to overlay all the content on the page
mObj.style.height = document.documentElement.scrollHeight + "px";
// create the DIV that will be the alert
alertObj = mObj.appendChild(d.createElement("div"));
alertObj.id = "alertBox";
// MSIE doesnt treat position:fixed correctly, so this compensates for positioning the alert
if (d.all && !window.opera) alertObj.style.top = document.documentElement.scrollTop + "px";
// center the alert box
alertObj.style.left = (d.documentElement.scrollWidth - alertObj.offsetWidth) / 2 + "px";
// create an H1 element as the title bar
h1 = alertObj.appendChild(d.createElement("h1"));
h1.appendChild(d.createTextNode(ALERT_TITLE));
btn2 = alertObj.appendChild(d.createElement("img"));
btn2.id = "fd";
btn2.src = fd;
// create a paragraph element to contain the txt argument
msg = alertObj.appendChild(d.createElement("p"));
msg.innerHTML = txt;
// create an anchor element to use as the confirmation button.
//btn = alertObj.appendChild(d.createElement("a"));
//btn.id = "closeBtn";
//btn.appendChild(d.createTextNode(ALERT_BUTTON_TEXT));
//btn.href = "";
btn = alertObj.appendChild(d.createElement("img"));
btn.id = "closeBtn";
btn.src = 'new-go-next2.png';
btn.href="#ss";
//btn.height="30px";
//btn.width="30px";
//btn.href="#";
// set up the onclick event to remove the alert when the anchor is clicked
btn.onclick = function () { removeCustomAlert(); window.location = string_url; return false; }
}
well yes creating a table would be a great approach to solve your problems , btw u can also try some internal divs with proper position anf the element having correct float attribute
Rather creating div element create table with two Columns. First of which will contain 'Image' for OK and Second one will contain your 'Text'.
Check if this helps.
I have a inline list of pictures that I want to be able to rotate through. I only ever display five at a time, and if you click on any besides the center one that one moves to the center and the others move on and off screen.
I wrote a function to use the .offsetLeft to get where one button was in relation to another and determine which way the container should move. I was hoping that I could just change the offset of the buttons and move them within the container, but sadly you can't do that with just JavaScript.
So I determined that it would be best to have a window and change the margin on the container behind by the offset difference, and this works well. The first time after that it goes each time I click a picture, and it acts like it goes through the code, but it does not change the margin of the container.
Here is the code:
var cur_position;
function set_variables()
{
cur_position = document.getElementById("button3");
}
function carousel(Event)
{
console.log(cur_position);
var clicked_element = Event.target;
var tray_bar = document.getElementById("button_tray");
var num = 0;
console.log(clicked_element.offsetLeft);
clicked_element.offsetLeft = cur_position.offsetLeft - clicked_element.offsetLeft;
console.log(clicked_element.offsetLeft);
console.log(cur_position.offsetLeft);
console.log(clicked_element.offsetLeft);
if (clicked_element.offsetLeft < cur_position.offsetLeft)
{
num = cur_position.offsetLeft - clicked_element.offsetLeft;
console.log(cur_position.offsetLeft - num);
document.getElementById("button_tray").style.marginLeft += num;
cur_position = clicked_element;
console.log(cur_position);
}
else
{
num = clicked_element.offsetLeft - cur_position.offsetLeft;
console.log(num);
tray_bar.style.marginLeft = tray_bar.style.marginLeft - num;
cur_position = clicked_element;
console.log(cur_position);
}
}
<div class="button-wrapper">
<ul id="button_tray" class="buttons">
<li id="button1" class="message-button" onclick="carousel(event)"><div></div></li>
<li id="button2" class="link-button" onclick="carousel(event)"><div></div> </li>
<li id="button3" class="live-button" onclick="carousel(event)"><div></div> </li>
<li id="button4" class="social-button" onclick="carousel(event)"><div></div></li>
<li id="button5" class="ppt-button" onclick="carousel(event)"><div></div> </li>
<li id="button6" class="test-1" onclick="carousel(event)"><div></div></li>
<li id="button7" class="test-2" onclick="carousel(event)"><div></div></li>
<li id="button8" class="test-3" onclick="carousel(event)"><div></div></li>
</ul>
</div>
</div>
I would really like to figure out why it's only working the first time or even better be able to move the pictures inside in relation to one another. Please keep answers in JavaScript instead of jQuery.
I don't know if this is the only issue, but when you're setting your margins, you're not taking units or the data type of styles into account. With this line:
document.getElementById("button_tray").style.marginLeft += num;
Your first access of marginLeft may be a blank string, so += num would work properly. If num was set to 20, browser may convert the style property to 20px. The next time around, when you accessed marginLeft, you'd get back "20px"; adding 20 to that would result in "20px20", which is obviously not a good value.
I'd suggest that when you want to add to or remove from the margin property, you should do it like this instead:
var tray_bar = document.getElementById("button_tray");
var pixelMargin = parseInt(tray_bar.style.marginLeft, 10);
pixelMargin += num;
tray_bar.style.marginLeft = pixelMargin.toString() + 'px';