javascript, tree scrollIntoView won't scroll - javascript

I need to get all the links in a page, and i do get them, the problem is the href exist twice in the website, to not get the link twice i did a little trick with the variables :
getAlllinks: function()
{
var links = content.document.getElementsByTagName("a");
var entries = new Array;
var liens = new Array;
for(var i = 0; i<links.length; i++)
{
if(entries.indexOf(links[i].href) == -1)
{
entries.push(links[i].href);
liens.push(links[i]);
}
}
return links;
}
ok till now everything is fine, i put the links in a tree (Xul) and all, but my problem starts from here on, i use scrollIntoView to scroll to the link
var tree = document.getElementById("Tree_links");
var tbo = tree.boxObject;
var row = { }, col = { }, child = { };
tbo.getCellAt(event.clientX, event.clientY, row, col, child);
var cellText = tree.view.getCellText(row.value, col.value);
var links = new Array;
links = cleanLinks();
for (var i = 0; i < links.length; i++)
{
if (links[i].href === cellText.toString())
{
links[i].scrollIntoView("true");
if(links[i].style.backgroundColor == "rgb(255, 255, 0)")
{
links[i].style.backgroundColor='transparent';
}
else
{
links[i].style.backgroundColor='#ffff00';
}
}
}
it won't scroll for the links that are twice in the page, BUT if i put all the links (twice or single) in the tree it does scroll.
thanks in advance.

Well I figured it out,
the trick i was doing with the variables i did it when filling the tree

Related

First accordion to be made open by default either by JavaScript or CSS

I got 3 accordions in a Shopify product page out of which I intend to keep the first one expanded by default on page load. Once the page loaded, clicking other accordions should close all previously opened ones. I want to do it only with pure JavaScript(no libraries like jQuery) or CSS. My code below just ensures the first accordion is shown expanded. Could you please help correct my code after having a look at the accordions in the page https://wv3yau73hiyf9fhv-458195004.shopifypreview.com?
window.onload = function() {
var accItem = document.getElementsByClassName('accordion__item');
// Keep the first accordion open by default.
for (i = 0; i < accItem.length; i++) {
console.log("Within first for loop");
accItem[0].click();
accItem[i].addEventListener('click', toggleItem, false);
}
function toggleItem() {
var itemClass = this.parentNode.className;
for (i = 0; i < accItem.length; i++) {
console.log("Within second for loop");
accItem[i].className = 'accordion__item close';
}
if (itemClass == 'accordion__item close') {
this.parentNode.className = 'accordion__item open';
}
}
};
Using the browser's console on the page, I used the following to open the first accordion:
let allAccordions = document.querySelectorAll(".accordion__item");
allAccordions[0].click();
Yes, a loop is possible too:
for (var i = 0; i < allAccordions.length; i++) {
if (i == 0) {
allAccordions[i].click();
break; // only the first, can stop looping.
}
}
Finally, the solution is below:
// Keep the first accordion open by default.
let allAccordions = document.querySelectorAll(".accordion__item");
if (allAccordions.length > 0) {
allAccordions[0].querySelector("input[type=radio]").checked = true;
}
// Capture click event for the accordions
allAccordions.forEach(element => {
element.addEventListener('click', function() {
let radioBtn = this.querySelector("input[type=radio]");
let clickedRadioName = radioBtn.getAttribute("name");
allAccordions.forEach(element => {
let elementRadioBtn = element.querySelector("input[type=radio]");
let elementRadioName = elementRadioBtn.getAttribute("name");
if ((elementRadioName != clickedRadioName) && elementRadioBtn.checked) {
element.querySelector("input[type=radio]").checked = false;
}
});
});
});

Instigating CSS animation with Javascript

I currently have it so my titles slide in when the link is clicked.
How do I make it so that (when the link is clicked) the current title will slide out before the new one slides in?
This is the clicked event I have been using. It might be all wonky, I have been adding different things to it to try and get it to work.
// list of sections. the first section contains only the h1.
var sections = document.querySelectorAll("section");
function hideSections() {
for (var i = 0; i < sections.length; i++) {
sections[i].className = "hidden";
}
}
// list of links in the nav.
var links = document.querySelector("nav").querySelectorAll("a");
// add listeners to those links
for (var i = 0; i < links.length; i++) {
links[i].addEventListener("click", clicked);
}
function clicked(event) {
var target = document.querySelector('h2');
target.className = "slideout";
event.preventDefault();
hideSections();
var current = event.target.hash;
// "show" appropriate selection, based on id from link
document.querySelector(current).className = "";
// modify URL to reflect current location
location.hash = current;
target.addEventListener("animationend", newfile);
function newfile() {
target.removeEventListener("animationend", newfile);
}
target.addEventListener("animationstart", newfile);
}
// when page loads...
hideSections();
if (location.hash == "") {
sections[0].className = "";
} else {
document.querySelector(location.hash).className = "";
}
https://jsfiddle.net/yk7w2zt2/
Here is my full code.
You need you delay showing the next section until after the h2 has slid off the screen.
See JSFiddle using setTimeout():
https://jsfiddle.net/w9uypaae/

Illustrator ExtendScript hiding paths

I am trying to write a script (because I can't find one that works) that will export all my separate layers, paths, etc to transparent png files. I have seen many scripts, but all of them do not export all the layers, etc. They seem to just try and export parent layers. So if there are sub layers, these are missed.
Here is my script:
var doc = app.activeDocument;
var counter = 0;
hideOrShowItems(doc, false);
// processLayers(doc);
// displayLayer(doc, true);
function hideOrShowItems(root, show) {
for(var i = 0; i < root.layers.length; i++) {
var layer = root.layers[i];
var pathCount = layer.pathItems.length;
var layerCount = layer.layers.length;
if (pathCount > 0) {
hideOrShowPaths(layer, show);
}
if (layerCount > 0) {
hideOrShowItems(layer, show);
}
layer.visible = show;
}
}
function hideOrShowPaths(root, show) {
for(var i = 0; i < root.pathItems.length; i++) {
root.pathItems[i].visible = show;
}
}
// -- Removed for brievety
When I run the script, the only thing that gets hidden is the top layer
All of the rest are untouched.
I put a counter in and did counter++ in the for loop of hideOrShowPaths and it counts 246, so I know it can see the paths and is actually trying to hide them, but they stay visible.
Has anyone done this before? Can I hide paths, groups, clips and export them all as pngs? or will I have to do this manually?
Looks like the flag you are looking for is hidden not visible.
var doc = app.activeDocument;
var root = doc.layers[0];
// just for testing purpose. Change the color
var newRGBColor = new RGBColor();
newRGBColor.red = 255;
newRGBColor.green = 255;
newRGBColor.blue = 255;
// make all items hidden
for (var i = 0; i < root.pathItems.length; i++) {
var item = root.pathItems[i];
item.hidden = true;
item.fillColor = newRGBColor; // just for testing
}
// now loop all pathItems
for (var i = 0; i < root.pathItems.length; i++) {
var item = root.pathItems[i];
item.hidden = !item.hidden; //make one visible
// export visible part
redraw();
item.hidden = !item.hidden; // hide it again
}
In your script you will need to hide every item first, then unhide one, export and hide it again.
I Hope that snippet helps with your problem

Extracting a DOM element into an array of lines

I'm working on a page that includes a div with contenteditable="true" and I need to extract the text typed by the user as plain text to be later processed by some other javascript code. I then wrote this function:
function extractLines(elem) {
var nodes = elem.childNodes;
var lines = [];
for (i = 0; i < nodes.length; ++i) {
var node = nodes[i];
if (node.nodeType == 3) {
if (node.nodeValue.length > 0) {
lines.push(node.nodeValue);
}
}
if (node.nodeType == 1) {
if (node.nodeName == "BR") {
lines.push("");
}
else {
lines = lines.concat(extractLines(node));
}
}
}
return lines;
}
This takes an element and should return an array of lines. I don't expect it to work for any HTML, but it should be able to process what the browser generates on the div. Currently I'm testing on Chrome only (later I'll expand the idea to other browsers as they format of generated html is different on contenteditable divs).
Given this HTML:
<div id="target">aaa<div><br></div></div>
It correctly produces:
["aaa", ""]
But my problem is when the user insert two consecutive line breaks (EnterEnter). Chrome produces this:
<div id="target">aaa<div><br></div><div><br></div></div>
And my code gets stuck into an infinite loop. Why?
You can try with this:
console.log(extractLines(target));
Note: you might need to force-kill the tab (use Shift+Esc)
Live demo here (click).
var myElem = document.getElementById('myElem');
var myBtn = document.getElementById('myBtn');
myBtn.addEventListener('click', function() {
var results = [];
var children = myElem.childNodes;
for (var i=0; i<children.length; ++i) {
var child = children[i];
if (child.nodeName === '#text') {
results.push(child.textContent);
}
else {
var subChildren = child.childNodes;
for (var j=0; j<subChildren.length; ++j) {
var subChild = subChildren[j];
results.push(subChild.textContent);
}
}
}
console.log(results);
});
Old Answer
How about this? Live demo here (click).
var myElem = document.getElementById('myElem');
var myBtn = document.getElementById('myBtn');
myBtn.addEventListener('click', function() {
var results = [];
var children = myElem.childNodes;
for (var i=0; i<children.length; ++i) {
var text = children[i].textContent;
if (text) { //remove empty lines
results.push(text);
}
}
console.log(results);
});
You can remove that if (text) statement if you want to keep the empty lines.

div onclick issue with basic "LightsOut" script

I'm just developing my skills and trying to create a js app to do the "Lights Out game" type of script that you might have seen before. Nothing complicated. Or so I thought. The idea is you start out with a grid of darkened lights, and if you click one button it toggles the state of the clicked button as well as those to the NSEW of that button. Once you click the correct sequence, all the lights are lit. My problem is basically that the divs I created are not registering a click event.
function lightUp(){
$("div.light").click(function(){
var thisDiv = $(this).attr("id");
var topDiv = null;
var bottomDiv = null;
var leftDiv = null;
var rightDiv = null;
for (i= 1; 4; i++){
for (j=1; 4; j++){
var testDiv = "r"+i+"c"+j;
if (testDiv === thisDiv) {
if (i > 1) {
topDiv = "r"+(i-1)+"c"+j;
}
if (i < 4) {
bottomDiv = "r"+(i+1)+"c"+j;
}
if (j > 1) {
leftDiv = "r"+i+"c"+(j-1);
}
if (j < 4) {
rightDiv = "r"+i+"c"+(j+1);
}
}
}
}
$("#"+thisDiv, "#"+topDiv, "#"+bottomDiv, "#"+leftDiv, "#"+rightDiv).toggleClass("on").toggleClass("off");
});
}
is not registering the clicks on the divs.
<div id="r2c3" class="light off" onclick="lightUp();"></div>
It's possible this kind of script has to be much more complex, but I'm trying it out. Input is appreciated.
http://jsfiddle.net/4bUnt/3/
Ok, got it working for you. Check it out here:
http://jsfiddle.net/4bUnt/6/
Normally when giving an answer I would propose the solution and let the person re-work their code, however in this case their were quite a few syntax errors and various problems with the code, that to try to point them out one by one, step by step would have been quite cumbersome and the back and forth dialog in comments would have been too much. Maybe is why there is no other answers to this question so far.. anyway, check it out and learn from it and if you found this and a solution and/or helpful answer, please select this as the answer or up-vote it. thank you. Carry on. Good luck! :)
$( document ).ready(function() {
$("div.light").click(function(){
var thisDiv = $(this).attr("id");
var topDiv = null;
var bottomDiv = null;
var leftDiv = null;
var rightDiv = null;
for (var i= 1; i<5; i++){
for (var j=1; j<5; j++){
var testDiv = "r"+i+"c"+j;
if (testDiv === thisDiv) {
if (i > 1) {
topDiv = "r"+(i-1)+"c"+j;
}
if (i < 4) {
bottomDiv = "r"+(i+1)+"c"+j;
}
if (j > 1) {
leftDiv = "r"+i+"c"+(j-1);
}
if (j < 4) {
rightDiv = "r"+i+"c"+(j+1);
}
}
}
}
if ($("#"+thisDiv).hasClass("off")) {
$("#"+thisDiv).removeClass("off").addClass("on");
$("#"+topDiv).removeClass("off").addClass("on");
$("#"+bottomDiv).removeClass("off").addClass("on");
$("#"+leftDiv).removeClass("off").addClass("on");
$("#"+rightDiv).removeClass("off").addClass("on");
} else {
$("#"+thisDiv).removeClass("on").addClass("off");
$("#"+topDiv).removeClass("on").addClass("off");
$("#"+bottomDiv).removeClass("on").addClass("off");
$("#"+leftDiv).removeClass("on").addClass("off");
$("#"+rightDiv).removeClass("on").addClass("off");
}
});
});

Categories