I have a JavaScript Slideshow that only changes image when you refresh the page. I've tried adding
setInterval("printImage1()", 4000);
But then I get multiple images underneath eachother.
JavaScript
NumberOfImagesToRotate1 = 10;
FirstPart1 = '<a href="';
MiddlePart1 = '.htm"><img src="img/';
LastPart1 = '.jpg" border="0" height=”450” width="800"></a>';
function printImage1() {
var r = Math.ceil(Math.random() * NumberOfImagesToRotate1);
document.write(FirstPart1 + r + MiddlePart1 + r + LastPart1);
}
HTML
<script>printImage1()</script;
If I understand "But then I get multiple images underneath eachother" correctly, then every 4 seconds, you get another image printed under the previous.
in your HTML you should add something like:
<div id="spaceForImage"><div>
Then, in your javascript, include jQuery and replace the document.write(...) line with:
$('#spaceForImage').html(FirstPart1 + r + MiddlePart1 + r + LastPart1);
That should do what you want.
EDIT:
Using Mijago's idea, you'll need to have something like
<a id="slideLink" href="1.htm"><img id="slideImage" src="img/q1.jpg"></img></a>
in your HTML by default, then in your javascript, change document.write() to
$('#slideLink').attr('href',r + '.htm');
$('#slideImage').attr('src','img/' + r + '.jpg');
This is fine too. Changes the DOM less, but has an extra line of code.
Related
I have spent long, too long, trying to make all of the directory components work. They took something that could have been super simple and made it complex and difficult.
I finally buckled and tried to copy a javascript function into my project and it worked with a simple method. The method, like all others need to be initiated by some other component. But do that in any way you want it.
All I'll leave here is the code. And the hope that somebody else will find this and use less time than I did.
void copyText(String text){
Page page = UI.getCurrent().getPage();
page.executeJavaScript(
"var el = document.createElement('textarea');" +
"el.value = $0;" +
"el.setAttribute('readonly', '');" +
"el.style = {" +
" position: 'absolute'," +
" left: '-9999px'" +
"};" +
"document.body.appendChild(el);" +
"el.select();" +
"document.execCommand('copy');" +
"document.body.removeChild(el);",
text);
}
void copyText(String text){
Page page = UI.getCurrent().getPage();
page.executeJavaScript(
"var el = document.createElement('textarea');" +
"el.value = $0;" +
"el.setAttribute('readonly', '');" +
"el.style = {" +
" position: 'absolute'," +
" left: '-9999px'" +
"};" +
"document.body.appendChild(el);" +
"el.select();" +
"document.execCommand('copy');" +
"document.body.removeChild(el);",
text);
}
Just to further explain the code. We need to initialize the page and then execute plain javascript-code. In this code, I pass the String text as a parameter and the utilize it in the code as "$0".
The code creates a textarea, which most of the addons in the directory also does. It then sets the text-string, it hide it from the ui with some styling. Then the textarea gets added to our file, because you are only allowed to copy a value that is visible. Then the text is selected, copied, and lastly the textarea is removed. Fast and clean.
You can also add the following line:
el.setSelectionRange(0, 99999);
Add it after the el.select(); line. According to W3, it should work better on phones with this line, but I have not tested it.
I have a js code that adds margin-top to a row with a specific class name (page with id=3) . I would like this code runs before page load because now it instantly displays the row without margin-top and then add it. The row should be displayed with the margin-top already be added.
My site is on wordpress and i added the js script on head.
I have tried
window.onpaint = checkMargin();
but it did not work. Any idea?
This is my js code
<script type="text/javascript">
//sets margin-top in serv-col --- IF not mobile version
function addServMargin() {
containers = document.getElementsByClassName('serv-cont');
titles = document.getElementsByClassName('serv-col-title');
texts = document.getElementsByClassName('serv-col-text');
links = document.getElementsByClassName('serv-col-link');
col_pad = '0px';
if ( window.innerHeight > 800) { col_pad = '8.3vh'; }
for (var i = 0; i < titles.length; i++) {
title_height = titles[i].offsetHeight;
text_height = texts[i].offsetHeight;
style = window.getComputedStyle(containers[i], '');
cont_height = style.getPropertyValue('height');
cont_padd = style.getPropertyValue('padding-top');
links[i].style.marginTop = 'calc(' + cont_height + ' - ' +
cont_padd + ' - ' + col_pad + ' - ' + title_height + 'px - 1.48vh - ' +
text_height + 'px - 127px - 5vh)';
}
}
function checkMargin() {
if (document.getElementsByClassName('page-id-13')[0] && window.innerWidth > 900) { addServMargin(); }
}
window.onresize = checkMargin;
</script>
I don't think making it run first will solve anything. The first thing the code does is get the containers, titles, texts, and links... which it does by searching the DOM. It then loops through the titles array and does the adjusting as needed. If the script runs before any rendering is done, the DOM elements won't exist. It 1) won't be able to find them, and 2) can't loop through them because the array will be empty.
Actually even before that, it checks for the existence of the elements it's looking for, and the screen size. I think the only way to get it to work w/o making it look like an after thought adjustment, would be to use CSS and media sizing to set the styles in the first place.
As I know JS is executed as the script tag is reached by Browser html interpreter. So putting it in the head tag on the first position may guarantee that it strats first, but can't guarantee that it ends execution before page loads, because the page loads asynchroniously.
Hello I am relatively new and have never coded before a month ago but I am slowly teaching myself the structure and inner workings of a website though html, css, and javascript. I am trying to modify a specific script within a website. This website is
https://www.wizards.com/dnd/dice/dice.htm
My goal is to make it so that I can manipulate a dice roll to give me an altered range for example instead of 1-4, maybe 1-10 and to also perhaps give me a number I specify. I also want to leave the general aesthetic of the site as unchanged as possible.
So first off I put this handy piece of code within the URL
javascript:document.body.contentEditable='true'; document.designMode='on'; void 0
and it allowed me to make the content within the body editable.
I wanted to be simple and just change the D4 dice element https://gyazo.com/adf563827f63edd37264882e90fd5f85 so it would give give me numbers in a range of 1-20.
The HTML code for this element is
<img src="https://www.wizards.com/dnd/dice/images/d4a.jpg" alt="d4" name="d4" onmouseout="MM_swapImgRestore()" onmouseover="MM_swapImage('document.d4','document.d4','images/d4b.jpg')" width="38" border="0" height="37">
I noticed the onclick="rolld4()" So I looked within the head of the website and noticed within <script language="JavaScript1.2"></script> these lines of code.
function rolld4() {
d4rolls = parseInt(document.form1.d4n.value);
d4mod = parseInt(document.form1.d4mo.value);
dtotal = "";
d4res = 0;
rtotal = document.form1.runningtotal.value;
for (i=0; i<2; i++) {
if (document.form1.d4m[i].checked) {
d4pm = i }
}
if (d4pm == 0) {
dtotal = dtotal + "Roll(" + d4rolls.toString() + "d4" + ")+" + d4mod.toString() + ":\n"
}
if (d4pm == 1) {
dtotal = dtotal + "Roll(" + d4rolls.toString() + "d4" + ")-" + d4mod.toString() + ":\n"
}
for (r=0; r<d4rolls; r++) {
var d4 = Math.floor((Math.random() * 4) + 1);
d4res = d4res + d4;
dtotal = dtotal + d4.toString() + ","
}
if (d4pm == 0) {
d4res = d4res + d4mod;
dtotal = dtotal + "+" + d4mod + "\n" + "Total:" + d4res
}
if (d4pm == 1) {
d4res = d4res - d4mod;
if (d4res <= minimumvalue) {
d4res = minimumvalue;
}
dtotal = dtotal + "-" + d4mod + "\n" + "Total:" + d4res
}
document.form1.d4r.value = d4res;
rtotal = dtotal + "\n\n" + rtotal;
document.form1.runningtotal.value = rtotal;
}
I altered above line Math.floor((Math.random() * 4) + 1) to Math.floor((Math.random() * 20) + 1)
I then created a new script with the modified code and placed it below the D4 dice element which should alter the output to give me my range from 1-20. I was able to achieve a bit of success and did in fact mimic a roll range of 1-20. However this has only worked for me once and I have been unable to replicate it even going through the exact same process.
I also saw that within the <script language="JavaScript1.2"></script>scripts that it was one large comment. This is what confuses me because if the javascript functions within the code are turned to comments where is the javascript being pulled from when the dice is clicked and "rolled". I cant seem to find the source.
I am a total novice when it comes to javascript I have mostly been delving into HTML and CSS for designing websites so I have practically zero knowledge of javascript beside the general format.
You cannot alter (change) or delete any javascript on a loaded website. It's not possible as web browsers first compile the javascript when website is loading and prepare it for execution.
Even if you delete a script tag, that piece of code exists somewhere in the memory.
BUT, you can add pieces of javascript code to a webpage (think of it as it is adding itself to the end of the page in a separate script tag) via web console or Scratchpad in Mozilla Firefox OR developer tools > console in Google Chrome.
With that and some clever thinking (depending on the existing code on the website) you can do the stuff you want.
Why Can’t I Read the object.style.left & object.style.top values ?
I’m trying to dynamically move a button.
I can use javascript to reset the style.left & style.top values by doing this :
document.getElementById(theButton_ID).style.left = "128px";
document.getElementById(theButton_ID).style.top = "64px";
But my problem is that I need to dynamically reset the ‘style.left’ & ‘style.top’ values, using a scaling factor that needs to be dynamically determined when the web page loads.
To my novice way of thinking this means that I need to :
• Get the style.left & style.top values
• Multiply them by the scaling factor
• Assign those modified values to style.left & style.top values.
The problem is that I can’t get the style.left & style.top values in the 1st place so I can’t modify them, much less write them back.
So obviously, I’m both doing something wrong & I'm not understanding something I should understand.
So what am I doing wrong ?
What is it that I’m missing ?
And Most importantly, how do I get the value of style.left & style.top so that I can use them to dynamically modify the position of the button ?
Thanks everyone for all your help & suggestions.
Here’s the actual HTML / CSS/ Javascript code …
<html>
<head>
<title>Button Dynamic Move Test</title>
<style type="text/css">
#MoveButton
{
position : absolute;
left : 8px;
top : 16px;
}
</style>
<script>
// var X_Index_Move_Factor = 1.25;
// var Y_Index_Move_Factor = 1.50;
function Move_A_Button (theButton_ID)
{
alert ( "We're in 'Move_A_Button'"
+ "\n"
+ " The Button Id = "
+ theButton_ID
);
var the_Old_Button_X_Offset = document.getElementById(theButtonId).style.left;
var the_Old_Button_Y_Offset = document.getElementById(theButtonId).style.top;
alert ( "the_Old_Button_X_Offset = "
+ "\n"
+ the_Old_Button_X_Offset
+ "the_Old_Button_Y_Offset = "
+ "\n"
+ the_Old_Button_Y_Offset
);
}
</script>
</head>
<body>
<button type = "button"
id = "MoveButton"
onclick = "Move_A_Button ('MoveButton')">
About Us
</button>
</body>
</html>
Actually, if you don't need to support IE6 or IE7 (or FireFox from ~17 versions ago), then the best way to go about getting the internal data is something like this:
// inside of your function:
var el = document.getElementById(button_id),
dimensions = el.getBoundingClientRect();
console.log("old x: " + dimensions.left, "old y: " + dimensions.top);
console.log("new x: " + dimensions.left * scale_X, "new y: " + dimensions.top * scale_Y);
Just remember that when you set them, afterward, you have to add the measurement, as well:
el.style.top = (dimensions.top * scale_Y) + "px";
el.style.left = (dimensions.left * scale_X) + "px";
And that using the getBoundingClient function will give you measurements as numbers, but .style.top / .style.left will give you measurements as strings ("112px") which you then have to pull the numbers out of, and then modify, and then when you add them back, you add the measurement type back on... ...hooray
theButton_ID is the name of an argument
function Move_A_Button (theButton_ID)
{
When you try to get the style you write
document.getElementById(theButtonId).style.left;
You forgot a underscore
Even with the typos corrected, the element doesn't initially have top or left styles, since none are set on the element itself.
element.offsetLeft and element.offsetTop are your best bets as starting points.
I am trying to integrate a sticky headers technique like the one shown here... Persistent Headers.
I have tried to integrate it into my code and for the most part have been successful, however it isn't behaving correctly and I REALLY can't figure it out.
I'll try to explain in a nutshell what the page it is being used on does. I have a database with a table of students and another table of assessments. This page loops through a JSON object (recieved from the database via a PHP script) and then for each student in that first object fetches another JSON with their assessments. This all works fine. It does however create a fairly long page. Visually it looks like this...
Code rendered in Chrome
The code I have written based on that tutorial I posted above is supposed to clone headers specified by a class and then hide or show them based on some logic involving scrollTop the position of the element and the length of the element. This having the effect of the header sticking to the top of the page while the container it belongs to is still visible.
The problem is something is going wrong and although all the headers are shown in sequence they are way too early, they seem to hang about for different lengths of time, and these lengths do seem to correlate to how long the container it belongs to is.
So my code...
Firstly the function used to update the headers...
containerArray = new Array;
positionArray = new Array;
floatingHeaderArray = new Array;
function updateTableHeaders() {
$(".studentContainer").each(function(i) {
containerArray[i] = $(this);
var position = containerArray[i].position();
positionArray[i] = position.top;
var scrollTop = $("#main").scrollTop();
floatingHeaderArray[i] = $(".floatingHeader", this);
if ((scrollTop > positionArray[i]) && (scrollTop < positionArray[i] + containerArray[i].outerHeight(true))) {
floatingHeaderArray[i].css({
"visibility": "visible"
});
} else {
floatingHeaderArray[i].css({
"visibility": "hidden"
});
};
});
}
Now the code that generates the containers, headers and tabs.
$("#mainContent").fadeIn(0);
loadMessage = "Loading data for " + event.target.id;
$.getJSON('php/oneFullClass.php?techClass=' + event.target.id, function(data) {
$('#mainTitle').fadeOut(0);
$('#action').html('You are ' + actionIntent + 'ing ' + event.target.id);
$('#action').fadeIn(300);
$('#mainTitle').fadeIn(300);
$('#mainContent').append('<div id="scrollTopDisplay"></div>')
dynamicPositioning();
$.each(data, function(key, val) {
var thisPosition = positionArray[0]
$('#mainContent').append(
'<div class="studentContainer studentView" id="' + val.idStudent + '">' +
'<div class="studentName">' + val.name + ' ' + val.surname + ' - (' + val.form.substr(0, 1) + '/' + val.form.substr(1, 2) + ')</div>' +
'<div class="floatingHeader">' + val.name + ' ' + val.surname + ' - (' + val.form.substr(0, 1) + '/' + val.form.substr(1, 2) + ')</div>' +
'<div class="studentTarget"> Target: <strong>' + val.target + '</strong></div>' +
'</div>');
$(".studentContainer").hide().each(function(i) {
//$(this).slideDown(0);
$(this).delay(i * 50).slideDown(300).fadeIn(500);
})
//Get previous assessments for this student and build tabs
buildTabs('php/allPreviousAssess.php?sid=' + val.idStudent, val.idStudent);
});
});
$('#mainContent').append('<div id="expandAll" onClick="expandAll()">Expand</div>');
$('#mainContent').append('<div id="collapseAll" onClick="collapseAll()">Collapse</div>');
dynamicPositioning();
$('#expandAll').delay(300).fadeIn(300);
$('#collapseAll').delay(300).fadeIn(300);
$("#main").scroll(updateTableHeaders);
I think that's all the info you'll need but I'll post any other code that may be referenced in this code if you think it'll help figure it out.
I have a suspicion that the problem is something to do with the animated slide in effect I am using on the 'assessment cards' messing with the position values, or possible position()'s inability to get positions of hidden elements. However, as I call updateTableHeaders() with every scroll event, this shouldn't be an issue as all animation is over by the time you are given access to the layout (there is a modal shade effect that only dissapears once all AJAX requests are complete.
I hope someone can help, this one is making me unhappy! :(
Balloon, a library I wrote for easily making your headers stick, is pretty hassle-free. You simply make a Balloon object instance, specifying if you want your sticky headers to be stacked or replaced, and then inflate the headers by passing in the strings of their ids. Give it a try and let me know if it helped you:
https://github.com/vhiremath4/Balloon
If you find any issues with it, file a bug report on the repository, but I feel like it should do its job in your case.