Trigger an event by the execution of another one - javascript

I want to integrate the last two loops into the first two loops in order to trigger the events from the last ones when the first ones fire.
function expand() {
var coll = document.querySelectorAll(".grid-item");
for (x = 0; x < coll.length; x++) {
coll[x].addEventListener("mouseenter",
function () {
event.target.style.width = "480px";
});
}
for (x = 0; x < coll.length; x++) {
coll[x].addEventListener("mouseleave",
function () {
event.target.style.width = null;
});
}
var coll1 = document.querySelectorAll(".collapsing");
for (x = 0; x < coll1.length; x++) {
coll1[x].addEventListener("mouseenter",
function () {
event.target.style.maxHeight = "480px";
});
}
for (x = 0; x < coll1.length; x++) {
coll1[x].addEventListener("mouseleave",
function () {
event.target.style.maxHeight = null;
});
}
Maybe this helps you more than me as I am a js beginner...

With your for loop, you have the index of the .grid-items - simply select the item in the .collapsing nodeList at the same index, and then you can set its style as well:
const gridItems = document.querySelectorAll(".grid-item");
const collapsings = document.querySelectorAll(".collapsing");
for (let i = 0; i < gridItems.length; i++) {
gridItems[i].addEventListener("mouseenter", () => {
gridItems[i].style.width = "480px";
collapsings[i].style.maxHeight = "480px";
});
gridItems[i].addEventListener("mouseleave", () => {
gridItems[i].style.width = null;
collapsings[i].style.maxHeight = null;
});
}
(note the use of let i, that's very important - best to avoid implicitly creating global variables, and use const or let instead of var to avoid unintuitive behavior from hoisting/function scope)
Another option to consider, rather than changing styles manually like this, would be to toggle classes on and off instead. Also, if these elements are all in a container, you might think about using event delegation, that way you only ever add two events overall, rather than two events for every element.

Something like this?
function expand() {
var coll = document.querySelectorAll(".grid-item");
for (x = 0; x < coll.length; x++) {
coll[x].addEventListener("mouseenter",
function() {
event.target.style.width = "480px";
loop3(true);
});
}
for (x = 0; x < coll.length; x++) {
coll[x].addEventListener("mouseleave",
function() {
event.target.style.width = null;
loop4(true);
});
}
loop3(false);
function loop3(auto_trigger) {
var coll1 = document.querySelectorAll(".collapsing");
for (x = 0; x < coll1.length; x++) {
coll1[x].addEventListener("mouseenter",
function() {
event.target.style.maxHeight = "480px";
});
if (auto_trigger) coll1[x].style.maxHeight = "480px";
}
}
loop4(false);
function loop4(auto_trigger) {
var coll1 = document.querySelectorAll(".collapsing");
for (x = 0; x < coll1.length; x++) {
coll1[x].addEventListener("mouseleave",
function() {
event.target.style.maxHeight = null;
});
if (auto_trigger) coll1[x].style.maxHeight = null;
}
}
}

Related

Javascript drag and drop with one elemant

I'm currently learning JavaScript and have created code allowing a user to drag and drop an item. However, this code requires there to be two objects in the list of objects when I want there only to be one. I believe the issue is due to using for loops which start from 0 and require the length of the list of items to be greater than 0. But due to lists starting from a 0 index, this doesn't happen. My code is:
const list_items = document.querySelectorAll('.list-item');
const lists = document.querySelectorAll('.list');
let draggedItem = null;
for (let i = 0; i < list_items.length; i++) {
const item = list_items[i];
item.addEventListener('dragstart', function () {
draggedItem = item;
setTimeout(function () {
item.style.display = 'none';
}, 0)
});
item.addEventListener('dragend', function () {
setTimeout(function () {
draggedItem.style.display = 'block';
draggedItem = null;
}, 0);
})
for (let j = 0; j < lists.length; j ++) {
const list = lists[j];
list.addEventListener('dragover', function (e) {
e.preventDefault();
});
list.addEventListener('dragenter', function (e) {
e.preventDefault();
});
list.addEventListener('drop', function (e) {
console.log('drop');
this.append(draggedItem);
});
}
}
Just an idea, so it might not work: have you tried changing your for loops from
(let j = 0; j < lists.length; j ++)
to
(let j = 0; j <= lists.length; j ++)
<= in JS is less than or equal to

Problem with showing the results in my Calculator app with this.id

im having trouble using this.id as it doesnt return any value.
https://jsfiddle.net/o432v0L5/
I'm at the point where I want the number to be shown when I press it but it just doesnt work.
for (var i = 0; i < operator.length; i++) {
operator[i].addEventListener('click', function (e) {
alert(this.id)
})
}
var number = document.getElementsByClassName('number')
for (var i = 0; i < number.length; i++) {
number[i].addEventListener('click', function () {
var output = getOutput()
if (output != NaN) {
output = output + this.id;
printOutput(output)
}
})
}```
Have you tried
for (var i = 0; i < operator.length; i++) {
operator[i].addEventListener('click', function (e) {
alert(this.innerText);
})
}

execute js code on window resize breakpoint

I have some js code that I would like to run only when the window is at a "large" screen size, let's say 900px. I want to use it like a media query in css, so the code can toggle on and off at a specific break point. So I'm assuming I need some sort of condition with the resize function like this:
$(window).resize(function () {
var viewportWidth = $(window).width();
if (viewportWidth < 900) {
}
});
And then put the code I want to execute between the curly brackets, but its not working.
This is the code that I would like to execute when the screen is resized to 900px:
function makeRowDiv(buildRow) {
var row = document.createElement('div');
row.className = 'row expanded row-spacing';
for (var i = 0; i < buildRow.length; ++i) {
row.appendChild(buildRow[i]);
}
return row;
}
window.onload = function () {
var work = document.getElementById('work'),
items = work.getElementsByTagName('div'),
newWork = document.createElement('div');
var buildRow = [],
count = 0;
for (var i = 0; i < items.length; ++i) {
var item = items[i];
if (item.className.indexOf('columns') == -1) {
continue;
}
// Extract the desired value.
var matches = /large-(\d+)\s* large-offset-(\d+)/.exec(item.className),
delta = parseInt(matches[1], 10) + parseInt(matches[2], 10);
if (count + delta > 12 && buildRow.length != 0) {
newWork.appendChild(makeRowDiv(buildRow));
count = 0;
buildRow = [];
}
buildRow.push(item.cloneNode(true));
count += delta;
}
if (buildRow.length != 0) {
newWork.appendChild(makeRowDiv(buildRow));
}
// Replace work with newWork.
work.parentNode.insertBefore(newWork, work);
work.parentNode.removeChild(work);
newWork.id = 'work';
};
I'm assuming that its possible to so with the
you can use a media query in javascript as well and use that as your condition
var mq = window.matchMedia( "(max-width: 900px)" );
if (mq.matches) {
// window width is less than 900px
} else {
// window width is more than 900px
}
Try this:
$(window).on('resize',function () {
var $width = $(window).width();
console.log($width);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
You could do something like this
function makeRowDiv(buildRow) {
var row = document.createElement('div');
row.className = 'row expanded row-spacing';
for (var i = 0; i < buildRow.length; ++i) {
row.appendChild(buildRow[i]);
}
return row;
}
function loadData() {
var work = document.getElementById('work'),
items = work.getElementsByTagName('div'),
newWork = document.createElement('div');
var buildRow = [],
count = 0;
for (var i = 0; i < items.length; ++i) {
var item = items[i];
if (item.className.indexOf('columns') == -1) {
continue;
}
// Extract the desired value.
var matches = /large-(\d+)\s* large-offset-(\d+)/.exec(item.className),
delta = parseInt(matches[1], 10) + parseInt(matches[2], 10);
if (count + delta > 12 && buildRow.length != 0) {
newWork.appendChild(makeRowDiv(buildRow));
count = 0;
buildRow = [];
}
buildRow.push(item.cloneNode(true));
count += delta;
}
if (buildRow.length != 0) {
newWork.appendChild(makeRowDiv(buildRow));
}
// Replace work with newWork.
work.parentNode.insertBefore(newWork, work);
work.parentNode.removeChild(work);
newWork.id = 'work';
};
window.onload = loadData;
window.onresize = function(){
if(window.innerWidth < 900){
loadData();
makeRowDiv(buildRow)
}
}
Assuming you want to call the function that you added on window.onload for window resize event also.

avoid sorting in the JSP pages

var sortitems = 1;
function move(fbox, tbox, all)
{
for ( var i = 0; i < fbox.options.length; i++)
{
if (!all && fbox.options[i].selected && fbox.options[i].value != "")
{
var no = new Option();
no.value = fbox.options[i].value;
no.text = fbox.options[i].text;
tbox.options[tbox.options.length] = no;
fbox.options[i].value = "";
fbox.options[i].text = "";
}
else
{
if (all && fbox.options[i].value != "")
{
var no = new Option();
no.value = fbox.options[i].value;
no.text = fbox.options[i].text;
tbox.options[tbox.options.length] = no;
fbox.options[i].value = "";
fbox.options[i].text = "";
}
}
}
BumpUp(fbox);
if (sortitems)
SortD(tbox);
checkSelectAll();
}
This move function is getting called after clicking on the button, then it will call the sort method where sorting is happening by alphabetically. So we dont need to sort we need to populate the data as it is from the left side box to right side box and vice versa, but sorting is happening. Please help out be here.
function SortD(box)
{
var temp_opts = new Array();
var temp = new Object();
for ( var i = 0; i < box.options.length; i++)
{
temp_opts[i] = box.options[i];
}
for ( var x = 0; x < temp_opts.length - 1; x++)
{
for ( var y = (x + 1); y < temp_opts.length; y++)
{
if (temp_opts[x].value > temp_opts[y].value)
{
temp = temp_opts[x].text;
temp_opts[x].text = temp_opts[y].text;
temp_opts[y].text = temp;
temp = temp_opts[x].value;
temp_opts[x].value = temp_opts[y].value;
temp_opts[y].value = temp;
}
}
}
for ( var i = 0; i < box.options.length; i++)
{
box.options[i].value = temp_opts[i].value;
box.options[i].text = temp_opts[i].text;
}
}
Depends on the bumpup box function. The elements are moving from one box to another. It will replace the element with empty space and move to top and do for all the elements. Please help out me here
Thanks in advance
function BumpUp(box)
{
for ( var i = 0; i < box.options.length; i++)
{
if (box.options[i].value == "")
{
for ( var j = i; j < box.options.length - 1; j++)
{
box.options[j].value = box.options[j + 1].value;
box.options[j].text = box.options[j + 1].text;
}
var ln = i;
break;
}
}
if (ln < box.options.length)
{
box.options.length -= 1;
BumpUp(box);
}
}
Maybe it's just me, but it's hard to see what the issue is here.
If it is simply that SortD(tbox) is being called within the move() function, that's because
sortitems is set to 1 right at the top of the code. The value of sortitems is never changed anywhere else, so this conditional is always true and SortD is always called.
if (sortitems)
SortD(tbox);

Multiple click listeners - java script

I am working on a project that imports some javascript rules from a file myjs.js, which is called (on all the web page of the project) in the header.
This files manages the behavior of checkboxes, and in fact toggling the checks of every checkbox pairs. The problem is that in some case, this behavior is wrong but I can't change anything in this js file because it is too complex.
So, on some page, I decided to listen to the click event on some checkbox to correct the behavior : the problem is that there is a conflict of script and I can't trigger my script (put on this very page). How can I force it to make my java script listened first ?
In fact the checkbox are constructed by myjs.js, applying to the html sequece
<div class="left">
<input type="radio" name="isPubOk" id="pubOk" checked="checked" />
<label for="pubOk"><?php echo _("Oui"); ?></label>
</div>
<div class="left">
<input type ="radio" name="isPubNok" id="pubNok" checked="" />
<label for="pubNok"><?php echo _("Non"); ?></label>
</div>
Here's a sample of the js file :
function initCustomForms() {
getElements();
separateElements();
replaceRadios();
replaceCheckboxes();
replaceSelects();
// hide drop when scrolling or resizing window
if (window.addEventListener) {
window.addEventListener("scroll", hideActiveSelectDrop, false);
window.addEventListener("resize", hideActiveSelectDrop, false);
}
else if (window.attachEvent) {
window.attachEvent("onscroll", hideActiveSelectDrop);
window.attachEvent("onresize", hideActiveSelectDrop);
}
}
function refreshCustomForms() {
// remove prevously created elements
if(window.inputs) {
for(var i = 0; i < checkboxes.length; i++) {
if(checkboxes[i].checked) {checkboxes[i]._ca.className = "checkboxAreaChecked";}
else {checkboxes[i]._ca.className = "checkboxArea";}
}
for(var i = 0; i < radios.length; i++) {
if(radios[i].checked) {radios[i]._ra.className = "radioAreaChecked";}
else {radios[i]._ra.className = "radioArea";}
}
for(var i = 0; i < selects.length; i++) {
var newText = document.createElement('div');
if (selects[i].options[selects[i].selectedIndex].title.indexOf('image') != -1) {
newText.innerHTML = '<img src="'+selects[i].options[selects[i].selectedIndex].title+'" alt="" />';
newText.innerHTML += '<span>'+selects[i].options[selects[i].selectedIndex].text+'</span>';
} else {
newText.innerHTML = selects[i].options[selects[i].selectedIndex].text;
}
document.getElementById("mySelectText"+i).innerHTML = newText.innerHTML;
}
}
}
// getting all the required elements
function getElements() {
// remove prevously created elements
if(window.inputs) {
for(var i = 0; i < inputs.length; i++) {
inputs[i].className = inputs[i].className.replace('outtaHere','');
if(inputs[i]._ca) inputs[i]._ca.parentNode.removeChild(inputs[i]._ca);
else if(inputs[i]._ra) inputs[i]._ra.parentNode.removeChild(inputs[i]._ra);
}
for(i = 0; i < selects.length; i++) {
selects[i].replaced = null;
selects[i].className = selects[i].className.replace('outtaHere','');
selects[i]._optionsDiv._parent.parentNode.removeChild(selects[i]._optionsDiv._parent);
selects[i]._optionsDiv.parentNode.removeChild(selects[i]._optionsDiv);
}
}
// reset state
inputs = new Array();
selects = new Array();
labels = new Array();
radios = new Array();
radioLabels = new Array();
checkboxes = new Array();
checkboxLabels = new Array();
for (var nf = 0; nf < document.getElementsByTagName("form").length; nf++) {
if(document.forms[nf].className.indexOf("default") < 0) {
for(var nfi = 0; nfi < document.forms[nf].getElementsByTagName("input").length; nfi++) {inputs.push(document.forms[nf].getElementsByTagName("input")[nfi]);
}
for(var nfl = 0; nfl < document.forms[nf].getElementsByTagName("label").length; nfl++) {labels.push(document.forms[nf].getElementsByTagName("label")[nfl]);}
for(var nfs = 0; nfs < document.forms[nf].getElementsByTagName("select").length; nfs++) {selects.push(document.forms[nf].getElementsByTagName("select")[nfs]);}
}
}
}
// separating all the elements in their respective arrays
function separateElements() {
var r = 0; var c = 0; var t = 0; var rl = 0; var cl = 0; var tl = 0; var b = 0;
for (var q = 0; q < inputs.length; q++) {
if(inputs[q].type == "radio") {
radios[r] = inputs[q]; ++r;
for(var w = 0; w < labels.length; w++) {
if((inputs[q].id) && labels[w].htmlFor == inputs[q].id)
{
radioLabels[rl] = labels[w];
++rl;
}
}
}
if(inputs[q].type == "checkbox") {
checkboxes[c] = inputs[q]; ++c;
for(var w = 0; w < labels.length; w++) {
if((inputs[q].id) && (labels[w].htmlFor == inputs[q].id))
{
checkboxLabels[cl] = labels[w];
++cl;
}
}
}
}
}
//replacing radio buttons
function replaceRadios() {
for (var q = 0; q < radios.length; q++) {
radios[q].className += " outtaHere";
var radioArea = document.createElement("div");
if(radios[q].checked) {
radioArea.className = "radioAreaChecked";
}
else
{
radioArea.className = "radioArea";
}
radioArea.id = "myRadio" + q;
radios[q].parentNode.insertBefore(radioArea, radios[q]);
radios[q]._ra = radioArea;
radioArea.onclick = new Function('rechangeRadios('+q+')');
if (radioLabels[q]) {
if(radios[q].checked) {
radioLabels[q].className += "radioAreaCheckedLabel";
}
radioLabels[q].onclick = new Function('rechangeRadios('+q+')');
}
}
return true;
}
//checking radios
function checkRadios(who) {
var what = radios[who]._ra;
for(var q = 0; q < radios.length; q++) {
if((radios[q]._ra.className == "radioAreaChecked") && (radios[q]._ra.nextSibling.name == radios[who].name))
{
radios[q]._ra.className = "radioArea";
}
}
what.className = "radioAreaChecked";
}
//changing radios
function changeRadios(who) {
if(radios[who].checked) {
for(var q = 0; q < radios.length; q++) {
if(radios[q].name == radios[who].name) {
radios[q].checked = false;
}
radios[who].checked = true;
checkRadios(who);
}
}
}
//rechanging radios
function rechangeRadios(who) {
if(!radios[who].checked) {
for(var q = 0; q < radios.length; q++) {
if(radios[q].name == radios[who].name) {
radios[q].checked = false;
}
if(radioLabels[q]) {
radioLabels[q].className = radioLabels[q].className.replace("radioAreaCheckedLabel","");
}
}
radios[who].checked = true;
if(radioLabels[who] && radioLabels[who].className.indexOf("radioAreaCheckedLabel") < 0) {
radioLabels[who].className += " radioAreaCheckedLabel";
}
checkRadios(who);
if(window.$ && window.$.fn) {
$(radios[who]).trigger('change');
}
}
}
//replacing checkboxes
function replaceCheckboxes() {
if (replaceCheckBoxes == 0)
return;
for (var q = 0; q < checkboxes.length; q++) {
// checkboxes[q].className += " outtaHere";
var checkboxArea = document.createElement("div");
if(checkboxes[q].checked) {
checkboxArea.className = "checkboxAreaChecked";
if(checkboxLabels[q]) {
checkboxLabels[q].className += " checkboxAreaCheckedLabel"
}
}
else {
checkboxArea.className = "checkboxArea";
}
checkboxArea.id = "myCheckbox" + q;
checkboxes[q].parentNode.insertBefore(checkboxArea, checkboxes[q]);
checkboxes[q]._ca = checkboxArea;
checkboxArea.onclick = new Function('rechangeCheckboxes('+q+')');
if (checkboxLabels[q]) {
checkboxLabels[q].onclick = new Function('changeCheckboxes('+q+')');
}
checkboxes[q].onkeydown = checkEvent;
}
return true;
}
//checking checkboxes
function checkCheckboxes(who, action) {
var what = checkboxes[who]._ca;
if(action == true) {
what.className = "checkboxAreaChecked";
what.checked = true;
}
if(action == false) {
what.className = "checkboxArea";
what.checked = false;
}
if(checkboxLabels[who]) {
if(checkboxes[who].checked) {
if(checkboxLabels[who].className.indexOf("checkboxAreaCheckedLabel") < 0) {
checkboxLabels[who].className += " checkboxAreaCheckedLabel";
}
} else {
checkboxLabels[who].className = checkboxLabels[who].className.replace("checkboxAreaCheckedLabel", "");
}
}
}
//changing checkboxes
function changeCheckboxes(who) {
setTimeout(function(){
if(checkboxes[who].checked) {
checkCheckboxes(who, true);
} else {
checkCheckboxes(who, false);
}
},10);
}
Please see the jquery stopImmediatePropagation() function here: http://docs.jquery.com/Types/Event#event.stopImmediatePropagation.28.29
I believe this will achieve what you are looking to do.
Edit: With more detail I may be able to provide a better answer.
Edit 2: It appears that there is no guarantee'd order of execution in Javascript, so inline code may not run before dynamically added code. In addition this particular function may only work if the other handlers are added using jQuery.
Edit 3:
A quick and dirty fix would be to add
<script type="text/javascript">var executeHandlers = false;</script>
to the top of the one html file.
Then edit the javascript file such that the event handlers have
if (executeHandlers !== false) { ... do the logic you normally would here ... }
as the body
This would add one line to the html file that needs to be treated differently, and should not impact the execution on the other pages.
Please note that this is a quick and dirty fix, and there are better ways to do this. Working with the constraints of an existing .js file, and only one file that needs to be treated differently, this seems to be the fastest / easiest way to the desired outcome, not necessarily the best.

Categories

Resources