How to build array contains conditional - javascript

I need to build a window listener that triggers on the mouseover on a box using contains and I'm not quite sure of how to build that?
This is a test I've built:
window.addEventListener("mouseover", trial)
function trial(e) {
const contain_material = document.getElementsByClassName("item")
if(contain_material.contains(e.target)) {
alert("so far so good")
}
else {
return
}
}

See if the following works for you.
function trial(e) {
const contain_material = document.getElementsByClassName("item")
for (var i = 0; i < contain_material.length; i++) {
if(contain_material[i] == e.target) {
alert("so far so good")
}
}
}

Instead of checking hover on the window, why not just check when one of those elements is hovered over. For example:
const contain_material = document.getElementsByClassName("item")
for (mat of contain_material) {
mat.addEventListener("mouseover", trial)
}
function trial(e) {
alert("so far so good")
}

Can't you just listen to the mouseover on the box element instead of in the whole page?
function handleMouseOver() {
alert('so far so good')
}
// or you can add dynamicaly with js
var boxes = document.getElementsByClassName("item");
Array.from(boxes).forEach(function() {
this.onmouseover = () => alert('so far so good')
})
// () => this is an arrow function in case you dont know
// Array.from() is because you can't use the forEach straight with a HTMLCollection
body {
display: flex;
}
.item {
width: 300px;
height: 300px;
background-color: yellow;
margin: 10px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div class="item" onmouseover="handleMouseOver()"></div>
<div class="item" onmouseover="handleMouseOver()"></div>
<div class="item" onmouseover="handleMouseOver()"></div>
<div class="item" onmouseover="handleMouseOver()"></div>
</body>
</html>

Related

How to make a tooltip with the same look and feel as when we add "title" attribute to an element?

I am trying to replicate the look and feel of the tooltip when we add the "title" attribute to an element.
Tooltip should be hovarable
Tooltip should be dismissable by pressing the Esc key
Currently, my custom tooltip is not hoverable. Also the look and feel is not matched with - https://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_global_title
Any help is really appreciated and thanks in advance
const tooltipTrigger = document.querySelector(".tooltip-trigger");
const tooltipText = document.querySelector(".tooltip-text");
tooltipTrigger.addEventListener("mouseenter", showTooltip);
tooltipTrigger.addEventListener("mouseleave", hideTooltip);
tooltipText.addEventListener("keydown", dismissTooltip);
function showTooltip() {
tooltipText.style.visibility = "visible";
}
function hideTooltip() {
tooltipText.style.visibility = "hidden";
}
function dismissTooltip(event) {
if (event.keyCode === 27) {
tooltipText.style.visibility = "hidden";
}
}
.tooltip-text {
visibility: hidden;
position: absolute;
background-color: #000;
color: #fff;
padding: 4px;
z-index: 1;
}
.tooltip-trigger{
cursor: pointer;
}
.tooltip-trigger:hover .tooltip-text {
visibility: visible;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="styles.css" />
<title>Tooltip</title>
</head>
<body>
<span class="tooltip-trigger" aria-describedby="tooltip-text"
>Hover over me</span
>
<div id="tooltip-text" class="tooltip-text" role="tooltip">
This is the tooltip text
</div>
<script src="script.js"></script>
</body>
</html>
const tooltipTrigger = document.querySelector(".tooltip-trigger");
const tooltipText = document.querySelector(".tooltip-text");
let timeout = null;
tooltipTrigger.addEventListener("mouseenter", showTooltip);
tooltipTrigger.addEventListener("mouseleave", hideTooltip);
window.addEventListener("keydown", dismissTooltip);
function showTooltip(event) {
timeout = setTimeout(() => {
tooltipText.style.visibility = "visible";
tooltipText.style.left = `${event.clientX}px`
tooltipText.style.top = `${event.clientY}px`
}, 1000)
}
function hideTooltip() {
clearTimeout(timeout);
timeout = null;
tooltipText.style.visibility = "hidden";
}
function dismissTooltip(event) {
if (event.key === 'Escape') {
tooltipText.style.visibility = "hidden";
}
}
.tooltip-text {
visibility: hidden;
position: absolute;
background-color: #000;
color: #fff;
padding: 4px;
z-index: 1;
}
.tooltip-trigger {
cursor: pointer;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="styles.css" />
<title>Tooltip</title>
</head>
<body>
<span class="tooltip-trigger" aria-describedby="tooltip-text">Hover over me</span
>
<div id="tooltip-text" class="tooltip-text" role="tooltip">
This is the tooltip text
</div>
<script src="script.js"></script>
</body>
</html>
The ultimate answer is in fact, you can't.
You can't replicate the exact behavior of a tooltip generated by a title attribute, simply because their appearance and behavior can be dramatically different across browsers, devices and OS.
You can certainly try to approach very close what it looks like on a particular browser/device/OS, but won't probably be able to replicate exactly everything everywhere. Note that doing user agent detection to finetune is most often a bad idea.

Call back a function to change the div color after click on button + click on div

hello everyone. I'm strugling to do some piece of code with 2 different buttons colors that when clicked, they change the color value so when I click the div it changes to that color. I found that I can do it the first time but I can not call again the function to repeat the process all over again. Any suggestions? Thank you a lot :)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<style>
.green {
background-color: green;
}
.red {
background-color: red;
}
#change {
border: 1px solid black;
width: 500px;
height: 500px;
}
</style>
</head>
<body>
<div id="change"></div>
<button id="green-btn">Green</button>
<button id="red-btn">Red</button>
<script>
const gbutton = document.getElementById("green-btn");
const rbutton = document.getElementById("red-btn");
const change = document.getElementById("change");
let color = "";
function changeGreen () {
color = "green";
}
function changeRed () {
color = "red";
}
gbutton.addEventListener("click", changeGreen)
rbutton.addEventListener("click", changeRed)
change.addEventListener("click", () => {
if(color == "green") {
change.classList.add("green");
} else if (color == "red") {
change.classList.add("red");
}});
</script>
</body>
</html>
you just have to remove other class
change.addEventListener("click", () => {
console.log('color', color)
if (color == "green") {
change.classList.add("green");
change.classList.remove("red");
} else if (color == "red") {
change.classList.add("red");
change.classList.remove("green");
}
});
you should remove the other class
change.classList.add("green")
change.classList.remove("red")

Hiding classes by clicking outside

I made a script that when I click on the container it hides a list. However, what I have been trying to do is that the list should hide when clicking outside the container and not inside. I have been looking for answers but nothing really worked for me as I use classes. Does someone know a solution?
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width" />
<title>Hiding the list</title>
</head>
<body>
<h1>Hiding the list</h1>
<div class="list">Hide the list by clicking outside
<li>Text1</li>
<li>Text2</li>
<li>Text3</li>
</div>
<div class="list">Hide the list by clicking outside
<li>Text1</li>
<li>Text2</li>
<li>Text3</li>
</div>
</body>
</html>
<style>
.list {
width: 50%;
height: 100%;
background-color: #f2f2f2;
}
li {
}
</style>
<script>
function hide_list() {
var children = this.children;
for (let i = 0; i < children.length; i++) {
children[i].style.display = "none";
}
}
document.querySelectorAll(".list").forEach(function (elem) {
elem.addEventListener("click", hide_list);
});
</script>

File won't open in Chrome or Firefox, file name in URL changes to "0"

I tried searching for "file name changes to 0 in browser" both in Google and here, but got nowhere. This is a simple file which suddenly stopped opening. I can't even get at the inspector to troubleshoot it. Undo/redo history is lost, so that will not help. I'm guessing it's a simple mistake, but I have NEVER seen this before.
<!doctype html>
<html lang="en">
<head>
<title>JS Animated Navigation Test</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script>
<!--
var location = 0;
var bar = document.getElementById("bar1");
function myMove()
{
// if (id != 0) clearInterval(id);
location = -144;
// if (location != -144) return; // don't execute onmouseover while previous onmouseover is still running.
id = setInterval(move, 1);
}
function move()
{
location++;
bar.style.left = location + 'px';
if (location == 300)
{
clearInterval(id);
id = setInterval(moveback, 1);
}
}
function moveback()
{
location--;
bar.style.left = location + 'px';
if (location == -144)
{
clearInterval(id);
// id = setInterval(move, 1);
}
}
-->
</script>
<style>
#container
{
width: 600px;
height: 100px;
position: relative;
background: white;
}
#bar1
{
width: 150px;
height: 30px;
position: absolute;
left: -144px;
background-color: white;
}
</style>
</head>
<body>
<p>
<button onclick="myMove()">Click Me</button>
</p>
<div id ="container">
<div id ="animate"><img src="imageGalleryBar.png" alt="Image Gallery" width="150" height="30" id="bar1" onmouseover="myMove()" /></div>
</div>
</body>
</html>
Thank you
You can't use the variable name location as it is a reserved word; what you're actually doing is setting the window.location variable to 0.
Rename it, or put it in a namespace or object.

SetTimeout executing but no delay

I am developing a Binary Tree Search visualization program using JSAV library. The problem is that all the nodes are getting highlighted instantly and I want to show it step by step without any pressing of button again and again.
I tried to highlight a node and use timeout function to stop the execution for few seconds and then unhighlight the node and then proceed with next selected node, however there is no effect at all. Can anybody suggest me what can I do to modify my program to incorporate this type of feature?
Code: (Uses JSAV library)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="css/JSAV.css" type="text/css" media="screen" title="no title" charset="utf-8" />
<title>Test Binary Tree Page</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script src="lib/jquery.transit.js"></script>
<script src="lib/raphael.js"></script>
<script src="lib/JSAV.js"></script>
<Script src="lib/includeall.js"></Script>
<style>
.highlight
{
background-color: blue;
}
.unhighlight
{
background-color: white;
}
#av {
width: 98%;
position: relative;
}
.jsavcounter {
position: absolute;
top: 15px;
}
.jsavtree {
position: relative;
width: 500px;
height: 300px;
}
svg {
height: 600px;
}
path {
pointer-events: visible;
}
</style>
</head>
<body>
<div id="av">
</div>
<script>
var jsav=new JSAV("av");
var bt=jsav.ds.binarytree();
addNode(bt,20);
addNode(bt,5);
addNode(bt,40);
addNode(bt,50);
addNode(bt,60);
addNode(bt,70);
addNode(bt,4);
function donothing()
{
}
function searchBinarytree()
{
var value=parseInt(document.getElementById("value").value);
var test=bt.root();
while(test!=null)
{
test.addClass("highlight");
setTimeout(donothing,20000);
if(test.value()==value)
{
break ;
}
if(test.value()<=value)
{
test.toggleClass("unhighlight");
test=test.right();
}
else
{test.toggleClass("unhighlight");
test=test.left();
}
bt.layout();
}
}
</script>
<div id="valuebox">
Value to search:<input id="value" type="text"> <button type="button" onclick="searchBinarytree()"> Search</button>
</div>
</body>
</html>
setTimeout is calling donothing which is "doing nothing". You should instead call the function you want repeated from within setTimeout. I assume you expect it to pause at that call, but that's not how setTimeout works. More info can be found at https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout
Something like this should work (not tested)
var test;
function searchBinarytree() {
test = bt.root();
test.addClass("highlight");
setTimeout(updateNode, 20000);
}
function updateNode() {
var value = parseInt(document.getElementById("value").value);
if (test != null) {
if (test.value() != value) {
test.removeClass("highlight");
if (test.value() <= value) {
test = test.right();
} else {
test = test.left();
}
if (test != null) {
test.addClass("highlight");
}
setTimeout(updateNode, 20000);
}
bt.layout();
}
}
Not really sure that it's your issue but:
When you use setTimeout use it like that
setTimeout(yourFunction, timeout);
not
setTimeout(yourFunction(), timeout);
you have to pass the function to be invoked, you don't invoke the function

Categories

Resources