How can target class="a-2" inside id="b" by clicking on class="a-1" also inside id="b"?
<div id="a">
<div class="a-1"></div>
<div class="a-2"></div>
</div>
<div id="b">
<div class="b-1"></div>
<div class="b-2"></div>
</div>
<div id="c">
<div class="c-1"></div>
<div class="c-2"></div>
</div>
You can always go through the parent:
element.parentNode.querySelector('.a-2')
You can select all sibling nodes by selecting all children of the parent of the clicked node and then filter out the node that is clicked.
const el = document.querySelectorAll('div > div');
const siblings = function(el) {
const nodes = el.parentNode.children;
return [...nodes].filter(node => node !== el)
}
el.forEach(function(e) {
e.addEventListener('click', function() {
siblings(this).forEach(node => {
console.log(node.textContent)
})
})
})
<div id="a">
<div class="a-1">a</div>
<div class="b-2">b</div>
<div class="c-2">c</div>
</div>
<div id="b">
<div class="a-1">a</div>
<div class="b-2">b</div>
</div>
<div id="c">
<div class="a-1">a</div>
<div class="b-2">b</div>
</div>
Related
Hello I would like to reach a level 3 div and change the style of this div
in my example I would therefore like to be able to apply disply:none on style color red
to make the word Warning invisible
<div id="Zone">
<div class="MR-Widget ">
<div class="Title"> </div>
<div class="Errors" style="display: none"></div>
<div class="Content">
<div class="search"> </div>
<div class="resultat" style="width: 120px;"></div>
<div class="MR" id="Lock" style="display: none;"> </div>
<div style="color: red"> Warning </div>
</div>
</div>
</div>
To select 3rd level div:
document.querySelector('#Zone > div > div > div')
Now the problem is you have 4 div at 3rd level. So needed to select all and check style color. That gives:
const warningNone = () => {
Array.from(document.querySelectorAll('#Zone > div > div > div')).forEach(el => {
if (el) {
if (el.style.color === 'red') {
el.style.display = 'none';
}
}
})
}
window.addEventListener('load', warningNone);
<div id="Zone">
<div class="MR-Widget ">
<div class="Title"> </div>
<div class="Errors" style="display: none"></div>
<div class="Content">
<div class="search"> </div>
<div class="resultat" style="width: 120px;"></div>
<div class="MR" id="Lock" style="display: none;"> </div>
<div style="color: red"> Warning </div>
</div>
</div>
</div>
I modified the snippet to check the >div>div>div existence
By the way, I put the function to be fired when document loaded, otherwise your red will not apply
3...
try to split the query line in 2:
const warningNone = () => {
const els = document.querySelectorAll('#Zone > div > div > div');
els.forEach(el => {
if (el.style.color === 'red') {
el.style.display = 'none';
}
})
}
window.addEventListener('load', warningNone);
now in dev tools check which line fire the error
My document structure is:
<div id="mainWindow">
<div id="subele1"></div>
</div>
<div id="subWindow">
<div id="subele2"></div>
</div>
I want to create a button so that the children subele1 and subele2 are interchanged every time the button is clicked.
UPD
function handleButtonClicked() {
const mainElement = document.getElementById('subele1')
const subElement = document.getElementById('subele2')
const mainElementValue = mainElement.innerHTML
mainElement.innerHTML = subElement.innerHTML
subElement.innerHTML = mainElementValue
}
<div id="mainWindow">
<div id="subele1">main Window!</div>
</div>
<div id="subWindow">
<div id="subele2">sub Window?</div>
</div>
<button id='main' onclick={handleButtonClicked()}>switch</button>
Question correction:
I am trying to hide the entire 'li' block if the ptag inside of the 'li' is empty.
The p tag resides inside of the 'li' in a div with the class of
aaProfileDataWrapper
So if that p tag has no text inside of it then the entire 'li' need to hide including the labels and anything else it holds.
var divs = $(".aaProfileDataWrapper");
divs.each(function () {
var div = $(this);
if (div.next().html() === "<p></p>") {
div.hide();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<li id="aaProfilePhone">
<label>Office 2 Phone:</label>
<div class="aaProfileDataWrapper">
<p></p>
</div>
<div class="aaInlineValidationWrapper">
<div class="aaValidationWrapper-Inner">
<span class="aaInlineValidationIcon"></span>
<span class="aaValidationTxt"></span>
</div>
</div>
</li>
All you need to do is query for al the p elements within any div element that has the aaProfileDataWrapper class that, themselves, are children of a li element. Then, you can loop over those p elements and, if they are empty, hide the li ancestor.
// Loop over all the p elements within the div elements that
// have the right class, that are inside of li elements
$("li div.aaProfileDataWrapper p").each(function (idx, el) {
// Check the p to see if it's empty
if ($(el).html() === "") {
$(el).closest("li").hide(); // Hide the nearest li ancestor
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li id="aaProfilePhone">
<label>Office 1 Phone:</label>
<div class="aaProfileDataWrapper">
<p></p>
</div>
<div class="aaInlineValidationWrapper">
<div class="aaValidationWrapper-Inner">
<span class="aaInlineValidationIcon"></span>
<span class="aaValidationTxt"></span>
</div>
</div>
</li>
<li id="aaProfilePhone">
<label>Office 2 Phone:</label>
<div class="aaProfileDataWrapper">
<p>something</p>
</div>
<div class="aaInlineValidationWrapper">
<div class="aaValidationWrapper-Inner">
<span class="aaInlineValidationIcon"></span>
<span class="aaValidationTxt"></span>
</div>
</div>
</li>
</ul>
Plain old JavaScript to the rescue. Pleas let me know if there is any doubt.
const divs = document.getElementsByClassName('some-class');
Array.from(divs).forEach((div) => {
const p = div.querySelector('p');
if (p && !p.innerText) {
div.style.display = 'none';
} else {
div.style.display = null;
}
});
<div class='some-class'>
<p>Show</p>
</div>
<div class='some-class'>
<p></p>
Hide
</div>
<div class='some-class'>
<p>Show</p>
</div>
<div class='some-class'>
<p></p>
Hide
</div>
<div class='some-class'>
<p>Show</p>
</div>
You can use find() to search for a <p> and then use text().length to see if it's empty.
var divs = $(".aaProfileDataWrapper");
divs.each(function () {
var p = $(this).find("p")
if (!p.text().length > 0) {
p.hide();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="aaProfileDataWrapper">
<p>hello world</p>
</div>
<div class="aaProfileDataWrapper">
<p>hello world</p>
</div>
<div class="aaProfileDataWrapper">
<p></p>
</div>
I am trying to build a bookmarklet that will hide all data-agentid selectors that have a data-color selector = 30. so I have a list on the website that look something like this
<div class="sch" data-agent-id=1></div>
<div data-agentid="1" data-color="30">
<div data-agentid="1" data-color="20">
...
<div class="sch" data-agent-id=2></div>
<div data-agentid="2" data-color="10">
<div data-agentid="2" data-color="20">
...
...
edited
There is a lot more code but I figure this is the important part.
I am thinking I can just build an array of ids where their color is 30 and then hide all of the ids in the array. My code is below but I don't think it is even building the array at this point.
(function() {
var arr = $('*[data-color="30"]').map(function() {
return $(this).data("data-agentid");
}).get().join();
$('*[data-agent-id=arr]').hide();
})();
Seems like you would just do this directly:
$('[data-color="30"]').hide()
Edit: Now that you've clarified what you're trying to do, it'll be more performant to select the elements once and iterate over them calling hide on the matching ones:
const agentsToHide =
Array.from(document.querySelectorAll('[data-color="30"'))
.reduce((agents, el) => {
const agentId = el.getAttribute("data-agentid")
if (!agents.includes(agentId)) agents.push(agentId)
return agents
}, [])
.forEach(agentId => {
document.querySelectorAll(`[data-agent-id="${agentId}"]`)
.forEach(el => {
el.style.display = "none"
})
})
<div class="sch" data-agent-id=1>Agent 1</div>
<div data-agentid="1" data-color="30">30</div>
<div data-agentid="1" data-color="30">30</div>
<div data-agentid="1" data-color="20">20</div>
<div class="sch" data-agent-id=2>Agent 2</div>
<div data-agentid="2" data-color="10">10</div>
<div data-agentid="2" data-color="20">20</div>
There is no selector that works off an array. So you would need to make a comma separated value
var selector = $('[data-color="30"]').map(function() {
return '[data-agent-id="' + $(this).data("agentid") + '"]';
}).get().join(',');
$(selector).hide();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div data-agentid="1" data-color="30"></div>
<div data-agentid="2" data-color="20"></div>
<div data-agentid="3" data-color="30"></div>
<div data-agent-id="1">1-1</div>
<div data-agent-id="2">2-1</div>
<div data-agent-id="3">3-1</div>
<div data-agent-id="1">1-2</div>
<div data-agent-id="2">2-2</div>
<div data-agent-id="3">3-2</div>
<div data-agent-id="1">1-3</div>
<div data-agent-id="2">2-3</div>
<div data-agent-id="3">3-3</div>
Other option is to use filter()
var ids = $('[data-color="30"]').map(function() {
return $(this).data('agentid');
}).get();
$('[data-agent-id]')
.filter(function () {
return ids.includes($(this).data('agent-id'));
})
.hide();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div data-agentid="1" data-color="30"></div>
<div data-agentid="2" data-color="20"></div>
<div data-agentid="3" data-color="30"></div>
<div data-agent-id="1">1-1</div>
<div data-agent-id="2">2-1</div>
<div data-agent-id="3">3-1</div>
<div data-agent-id="1">1-2</div>
<div data-agent-id="2">2-2</div>
<div data-agent-id="3">3-2</div>
<div data-agent-id="1">1-3</div>
<div data-agent-id="2">2-3</div>
<div data-agent-id="3">3-3</div>
Or just select in a loop
$('[data-color="30"]').each(function() {
var id = $(this).data('agentid');
$('[data-agent-id="' + id + '"]').hide();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div data-agentid="1" data-color="30"></div>
<div data-agentid="2" data-color="20"></div>
<div data-agentid="3" data-color="30"></div>
<div data-agent-id="1">1-1</div>
<div data-agent-id="2">2-1</div>
<div data-agent-id="3">3-1</div>
<div data-agent-id="1">1-2</div>
<div data-agent-id="2">2-2</div>
<div data-agent-id="3">3-2</div>
<div data-agent-id="1">1-3</div>
<div data-agent-id="2">2-3</div>
<div data-agent-id="3">3-3</div>
Plain and simple in vanilla javascript:
document.querySelectorAll('[data-color="30"]').forEach(function(item) {
item.style.display = "none";
});
<div data-agentid="1" data-color="30">Test30</div>
<div data-agentid="2" data-color="20">Test20</div>
<div data-agentid="1" data-color="30">Test30</div>
<div data-agentid="2" data-color="20">Test20</div>
<div data-agentid="1" data-color="30">Test30</div>
<div data-agentid="2" data-color="20">Test20</div>
<div data-agentid="1" data-color="30">Test30</div>
I need - button on click to hide each div, but here in my code only hide the first one then not working.
const closeInnermenu = document.querySelector('closeInnrmenu');
const innerC = document.querySelector('.inner-container')
closeInnermenu.addEventListener('click', () => {
innerC.style.display = 'none'
})
<div class="inner-container">
<div>Demo 1</div>
<button class="closeInnrmenu"></button>
</div>
<div class="inner-container">
<div>Demo 2</div>
<button class="closeInnrmenu"></button>
</div>
Get all the button using document.querySelectorAll('.closeInnrmenu') instead of document.querySelector since this will only give first matching element. Then iterate and add event listener to the button so that on click get the closest div and add style to it.
Also there is a type error here const closeInnermenu = document.querySelector('closeInnrmenu');. You need to pass dot as class selector
document.querySelectorAll('.closeInnrmenu').forEach((item) => {
item.addEventListener('click', function() {
this.closest('div').style.display = 'none'
})
})
<div class="inner-container">
<div>Demo 1</div>
<button class="closeInnrmenu">Close</button>
</div>
<div class="inner-container">
<div>Demo 2</div>
<button class="closeInnrmenu">Close</button>
</div>
Use:
let buttonClose = document.querySelectorAll('.closeInnrmenu')
for(let btns of buttonClose){
btns.addEventListener('click', function func(e) {
this.parentNode.style.display = 'none'
})
}
<div class="inner-container">
<div>Demo 1</div>
<button class="closeInnrmenu">Close</button>
</div>
<div class="inner-container">
<div>Demo 2</div>
<button class="closeInnrmenu">Close</button>
</div>
You can delegate
If you do not want to wrap in a div, use
document.addEventListener('click'
Here I wrapped
document.getElementById("container").addEventListener('click', (e) => {
const tgt = e.target;
if (tgt.classList.contains("closeInnrmenu")) {
tgt.previousElementSibling.style.display = 'none'
}
})
<div id="container">
<div class="inner-container">
<div>Demo 1</div>
<button class="closeInnrmenu"></button>
</div>
<div class="inner-container">
<div>Demo 2</div>
<button class="closeInnrmenu"></button>
</div>
</div>