Load a script using nodes included by another script - javascript

I need to make a web page with a lot of content. In order to be more efficient when modifying this content, I decided to put it in separate files and then include these files, following this tutorial: https://www.w3schools.com/howto/howto_html_include.asp.
For example one of these files may contain some clickable links to book descriptions, which are modal boxes. So I need to get them in a loading script to get these clickable links and make them trigger some events. But it seems this loading script is called before JavaScript gets the included nodes, even if I add an event listener after reading some threads (I tried to run it at 'DOMContentLoaded' or 'load') : document.getElementById or document.getElementsByClassName still returns null so it fails to define an onclick function. Let me show an example code:
script.js
function includeHTML() { /* Some code replacing the div by some-content.html, which is : <a id="clickable">Hello</a> */}
var button = null
window.addEventListener('load', function() {
button = document.getElementById("clickable");
button.onclick = function() { alert('Hello'); }
});
index.html
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="script.js"></script>
</head>
<body>
<p>Here is a trigger button : </p>
<div include-html="some-content.html"></div>
<script>includeHTML();</script>
</body>
</html>
On Firefox, this will fail on defining button.onclick as button is still null.
Any idea on how to fix it?
Not only should I be adding links, but also modal boxes. Here is a script code, more complete, for what my guess was:
script.js
var boxNames = ["bibliography", "about", "book1", "book2" ];
var boxes = null /* Contains the boxes to be displayed */
var trigs = null /* Contains the trigger buttons for each box */
var close = null /* Contains the close buttons for each box */
function setTrigger(i) {
trigs[i].onclick = function() { setBoxVisible(true, i); }
}
function setClose(i) {
trigs[i].onclick = function() { setBoxVisible(false, i); }
}
function load() {
boxes = new Array(4);
trigs = new Array(4);
close = new Array(4);
for(var i = 0; i < boxNames.length; i++) {
boxes[i]=document.getElementById(boxNames[i]+"-box");
trigs[i]=document.getElementById(boxNames[i]+"-trig");
close[i]=document.getElementById(boxNames[i]+"-close");
setTrigger(i); setClose(i);
}
}
window.onload = function() { load(); }
For the code of includeHTML(), you can have a look at the tutorial I shared, I copy/pasted.
I think this kind of function would be more elegant if dealing with such stuff, but I would need it to be launched once everything is loaded, as if I was running it manually.

Your code only added the event listener when the page was loading, likely before the link existed.
You need to delegate from the nearest static container.
Here in your code it is document
Give the link a class instead of ID and do
window.addEventListener('load', function(e) {
document.addEventListener('click', function(e) {
const tgt = e.target;
if (tgt.classList.contains("clickable")) {
e.preventDefault(); // because it is a link
alert('Hello');
}
});
});
<a class="clickable" href="#">Click</a>
Update after new code
You overwrite the trigs code
You can very simply extend my code so you do not need to loop
window.addEventListener('load', function(e) {
document.addEventListener('click', function(e) {
const tgt = e.target;
if (tgt.classList.contains("clickable")) {
e.preventDefault(); // because it is a link
alert('Hello');
}
else if (tgt.classList.contains("box")) {
e.preventDefault(); // because it is a link
const [id, what] = tgt.id.split("-")
console.log(id)
if (what === "trig") {
document.getElementById(id).classList.remove("hide")
}
else if (what === "close") {
document.getElementById(id).classList.add("hide"); // or tgt.closest("div").classList.add("hide")
}
}
});
});
.hide { display:none; }
<a class="clickable" href="#">Click</a>
<hr/>
<a class="box" id="bibliography-trig" href="#">Trigger Biblio</a>
<a class="box" id="about-trig" href="#">Trigger About</a>
<div id="bibliography" class="hide">Biblio
<a class="box" id="bibliography-close" href="#">Close</a>
</div>
<div id="about" class="hide">About
<a class="box" id="about-close" href="#">Close</a>
</div>

Related

trying to get my button to change text without user interaction javascript

i made a button function that has a button with a word and when its clicked the definition shows. but now i'm trying to make it so that the buttons shows the definition every couple seconds with "SetInterval" without needing to be clicked and i don't know how to go about doing so can you please help.
'use strict';
//below is the function for the even
$(document).ready(function() {
//
function salutationsHandler(evnt) {
let box = $("#message-box");
if (box.hasClass("hidden")) {
box.attr("class", "");
$(evnt.target).text("1.Salutation");
} else {
box.attr("class", "hidden");
$(evnt.target).text('a greeting in words or actions');
}
}
//end of function
setInterval(salutationsHandler, 1000);
//start of another
function DiffidenceHandler(evnt2) {
let box2 = $("#message-box2");
if (box2.hasClass("hidden")) {
box2.attr("class", "");
$(evnt2.target).text("2.Diffidence");
} else {
box2.attr("class", "hidden");
$(evnt2.target).text("the quality of being shy");
}
console.log(evnt2);
}
//lets me target id
let salutationsGrab = $('#Salutations');
// adds event to said id
// event listeners grab events from functions
salutationsGrab.on('click', salutationsHandler);
let DiffidenceGrab = $("#Diffidence");
DiffidenceGrab.on("click", DiffidenceHandler);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>hello welcome to our dictionary</h1>
<h2>Click on button to reveal definition of word shown</h2>
<button id="Salutations">1.Saluation</button>
<div id="message-box"></div>
<br>
<button id="Diffidence">2.Diffidence</button>
<div id="message-box2"></div>
<br>
The function salutationsHandler needs the event object generated by an event to work. Instead of calling the function directly, you can use jQuery's .trigger() to "click" the button.
function salutationsHandler(evnt) {
const box = $("#message-box");
const target = $(evnt.target);
if (box.hasClass("hidden")) {
box.removeClass("hidden");
target.text("1.Salutation");
} else {
box.addClass("hidden");
target.text('a greeting in words or actions');
}
}
let salutationsGrab = $('#Salutations');
salutationsGrab.on('click', salutationsHandler);
setInterval(() => salutationsGrab.trigger('click'), 1000);
.hidden {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>hello welcome to our dictionary</h1>
<h2>Click on button to reveal definition of word shown</h2>
<button id="Salutations">1.Saluation</button>
<div id="message-box">a greeting in words or actions</div>

JavaScript on body click work 1 time

This is my script -
my script alert when someone touch on any place on the page .
I am trying to execute alert only one time and not on every click.
This is the code i built which alert any time .
$( document ).ready(function() {
var click_count = 0;
if (click_count == 0){
$('body').click(function(){
alert();
var click_count = 1;
});
}
});
You have your if in the wrong place. You want it inside the click handler (the code that runs when the click occurs), not outside it. You also need to remove the var from var click_count = 1; so you 're using the one declared in the ready callback, not the one declared in the click handler:
$(document).ready(function() {
var click_count = 0;
$('body').on("click", function() {
if (click_count == 0) {
alert("Hi there");
click_count = 1;
}
});
});
Testing 1 2 3
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
(Here's a runnable version for mobiles where Stack Snippets aren't rendered: http://output.jsbin.com/taropelopu)
But, rather than using click_count, I'd suggest removing the event handler after the first click. You could do that with off, but jQuery even has a function specifically for adding a handler you remove the first time it's called: one (rather than on):
$(document).ready(function() {
$('body').one("click", function() {
alert("Hi there");
});
});
Testing 1 2 3
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
(Runnable version for devices where Stack Snippets don't render: http://output.jsbin.com/wivoroluzu)
With plain JavaScript you can do
let clicked = false;
const clickOnce = () => {
if (!clicked) {
alert('clicked');
clicked = true;
}
};
document.body.addEventListener('click', clickOnce);
some body content
And you don't even need a clicked variable to store the state. Just remove the event listener once it is triggered.
const clickOnce = () => {
alert('clicked');
document.body.removeEventListener('click', clickOnce)
};
document.body.addEventListener('click', clickOnce);
some body content

How do I add a button to a div class on load from Javascript? [duplicate]

This question already has answers here:
How to add onload event to a div element
(26 answers)
Closed 5 years ago.
For an assignment, I cannot touch the HTML code and am editing an external JS file. I have to refer the code to an existing class and turn that into a button to run a script.
The has to be ran on load to transform an element with a given id into a button that can also run a function on click.
So let's say the we have id="bar",
how do I go about it?
My code doesn't work at all.
document.getElementById("bar").onload = function () { myFunction() };
function myFunction() {
document.getElementById("bar").innerHTML = "<button></button>";
}
Why don't you just execute your script as the DOM is ready? To do so,
document.addEventListener('DOMContentLoaded', function () {
document.getElementById("bar").innerHTML = "<button></button>";
}, false);
You just need a createElement function.
This works:
document.addEventListener("DOMContentLoaded", function(){
var button = document.createElement("button");
button.innerHTML = "This is a button";
// assuming the Div's ID is bar
var div = document.getElementById('bar');
div.appendChild(button);
//the following function will alert a window when the button is clicked
button.addEventListener ("click", function() {
alert("Button was clicked");
});
});
Updated Codepen
I think this is bit tha you needed
var bar = document.getElementById('bar');
window.onload = function() {
var barInner = bar.innerHTML;
bar.innerHTML = '<button>' + barInner + '</button>';
}
bar.onclick = function() {
alert("Hello\nHow are you?");
};
document.getElementById("bar").onload = myFunction();
function myFunction() {
document.getElementById("bar").innerHTML = "<button>Button</button>";
}
There you go!
Not every single HTML element has a load event.
Only some of them are concerned, such as the window, an image... etc
Have a look here on MDN to learn more about this.
Here is a simple snippet resolving all what you mentioned.
window.addEventListener("load", () => {
// you can put your entire script in here.
var elt = document.getElementById("bar"),
button = document.createElement("button");
button.textContent = elt.textContent;
button.onclick = callback;
elt.textContent = '';
elt.appendChild(button);
function callback() {
console.log("The button has been clicked");
}
});
<div id="bar" style="background: beige; height: 2em">Click me</div>
In the previous snippet, I am appending the button in the element. But if the matter is really to transform it into a button, there we go:
window.addEventListener("load", () => {
// you can put your entire script in here.
var elt = document.getElementById("bar"),
container = elt.parentNode,
button = document.createElement("button");
button.id = elt.id; // if you want to keep the id
button.textContent = elt.textContent;
button.onclick = callback;
container.removeChild(elt);
container.appendChild(button);
function callback() {
console.log("The button has been clicked");
}
});
<div style="background: #fee; height: 2em">
<div id="bar" style="background: beige; height: 2em">Click me</div>
</div>

Heading Expand/Collapse Jquery Working but is Expanded by Default, I need it collapsed by default

So I'm working on a sharepoint site.. I'm completely new to javascript. I have been using a jquery I found to enable an expand/collapse feature that is tied to a heading type. When a heading is clicked, all of the paragraph content beneath the heading expands or collapses.
It works well, the only problem is that when the page loads, all of the content is expanded by default, and then collapses a moment later after the page finishes loading. It looks sloppy when loading so I want to have everything collapsed by default.
I also do not need the function that disables expand/collapse while in edit mode or a wikipage, if that makes this issue any simpler.
Here is the script I'm using:
<script language="javascript" type="text/javascript"
src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.0.2.min.js"></script>
<script language="javascript" type="text/javascript">
$(document).ready(function () {
var inEditMode = Utils.checkPageInEditMode();
// Prevent the collapsing of <h2> blocks when in SharePoint's [Edit Mode]
if (!inEditMode) {
UI.collapseContentHeaders();
UI.toggleContentHeaders();
}
});
var UI = {
collapseContentHeaders: function () {
$('#DeltaPlaceHolderMain h2').each(function (index, value) {
// Collapses all <h2> blocks
{
$(this).toggleClass('expand').nextUntil('h2').slideToggle(100);
}
});
},
toggleContentHeaders: function () {
// Toggles the accordion behavior for <h2> regions onClick
$('#DeltaPlaceHolderMain h2').click(function () {
$(this).toggleClass('expand').nextUntil('h2').slideToggle(100);
});
}
}
var Utils = {
checkPageInEditMode: function () {
var pageEditMode = null;
var wikiPageEditMode = null;
// Edit check for Wiki Pages
if (document.forms[MSOWebPartPageFormName]._wikiPageMode) {
wikiPageEditMode =
document.forms[MSOWebPartPageFormName]._wikiPageMode.value;
}
// Edit check for all other pages
if (document.forms[MSOWebPartPageFormName].MSOLayout_InDesignMode) {
pageEditMode =
document.forms[MSOWebPartPageFormName].MSOLayout_InDesignMode.value;
}
// Return the either/or if one of the page types is flagged as in Edit Mode
if (!pageEditMode && !wikiPageEditMode) {
return false;
}
return pageEditMode == "1" || wikiPageEditMode == "Edit";
}
}
</script>
Just delete if statement
if (index > 0) {
So i has to be olny $(this).toggleClass('expand').nextUntil('h2').slideToggle(100);

onscroll div in a JavaScript object

i want to build a div with scroll, that when you scroll this div, it will active anothe function.
i need to build this in a Object.
there is any way to do this?
i write here an example source (that not work) of what i want.
<script type="text/javascript">
function onsc(divName, divChange) {
this.play = function() {
window.onload = function() {
document.getElementById(divName).onscroll = function() {
this.scroll(n)
}
};
}
this.scroll = function(n) {
document.getElementById(divChange).innerHTML = "you scroll!";
}
}
c[1] = new onsc("div1", "div1_i").play();
</script>
<div id="div1_i">this div will change when you scroll</div>
<div id="div1" style="background:#C6E2FF; width:300px; height:200px; overflow-y:scroll;">
<p style="height:800px;">txt</p>
</div>
Your code was nearly there. I made a few changes and put into a JSFiddle for you.
I added comments at what you missed. Most importantly the context of this changes when you entered into that function on the onscroll event.
JavaScript
function onsc(divName, divChange) {
// First of all make `this` inherit to below functions
var self = this;
this.play = function () {
document.getElementById(divName).onscroll = function() {
// Changed this to call the parent and place the correct DIV
self.scroll(divChange)
}
}
this.scroll = function (n) {
document.getElementById(divChange).innerHTML = "you scroll!";
}
}
c = new onsc("div1", "div1_i").play();
Demo
Have a look at my JSFiddle: http://jsfiddle.net/bJD8w/2/

Categories