Attach onmouseover() function to each href in all <a> anchor tags, if anchor tags have <img> child elements? - anchor

HTML code:
<p><div>
<a href="https://www.digi.com.my/chat-with-us">
<img src="">
</a></p><div>
<p><a href="https://unifi.com.my/support/contact-us"><img src="">
</a></p>
</div>
<p><a>Hey Man
</a>
</p>
<div>
<p><a href="https://unifi.com.my/support/contact-us">Hey man
</a>
</p></div>
Javascript code:
let tar = document.querySelectorAll("a[href] > img[src]");
tar.forEach(tarG => {
tarG.addEventListener("mouseover", e => {
const ahref = e.target.a[href];
if (a[href]) location.assign(a[href]);
});
});
First, I want to attach onmouseover() function to all href links in all anchor tags with an child tags, in an HTML page.
My intention is that the onmouseover() function only activates the href, when the mouse cursor moves over a anchor tag containing the img child tag. Otherwise, if there is no img child tag, the onmouseover() function does not activate the href.
Where did my code go wrong? Thank you for all the helpful answers

Replace your JavaScrip code with this:
const tars = document.querySelectorAll('a > img');
tars.forEach(tar => {
const a = tar.parentNode;
a.addEventListener('mouseover', /* Your mouseover handler goes here */);
});

const tars = document.querySelectorAll("a > img");
tars.forEach(tar => {
const a = tar.parentNode;`
a.addEventListener("mouseover", e => {
const ahref = e.target.tar;
if (tar) location.assign(tar);
});
});
like this, #Corey?

sorry for vague answer. in your code you are adding event listener to img. you need to get parentnode of tar and then add event listener to it.
//js
x = [].slice
.call(document.querySelectorAll("img"))
.filter((e) => e.parentNode.tagName == "A")
.map((e) => e.parentNode);
console.log(x);
//jquery
y = $("a img").parent();
console.log(y.toArray());
//you can now add eventlisteners to x,y

Related

How to get the locator for an CSS ::after selector?

I have the following element (stripped for brevitiy):
<div id="searchButton">
<div>
<div>
"Search"
::after
</div>
</div>
</div>
Which renders to this element:
I now want to click the dropdown arrow.
How to write a selector for this?
Depending on Your CSS You can try this:
const element = await page.locator('div:has-text("Search")')
const arrow = await element.evaluate((e1) => {
return window.getComputedStyle(e1,':after').top
})
This should return position and then use mouse click on coordinates, but its possible that this will return auto and in that case try to find property that You could use instead of .top

svelte keep updating store var without clicking to update

My app automatically update $content value without me clicking on buttons. I know it is a simple question, but I can't find out why, I'm learning svelte.
App.svelte
<script>
import { content } from './store.js';
import Item from './Item.svelte';
$content = [{ id:0,obj: "Fell free to browse any category on top." }];
function addContent(value) {
$content = [{ id:0,obj: value}]
}
</script>
<li><button on:click={addContent("Home Page")}>Home</button></li>
<li><button on:click={addContent("Products Page")}>Products</button></li>
<div class="Content">
<p>Fell free to browse any category on top.</p>
{#each $content as item}
<p><svelte:component this={Item} objAttributes={item} /></p>
{/each}
</div>
store.js
import { writable } from 'svelte/store';
export let content = writable({});
Item.svelte
<script>
import { fade } from 'svelte/transition';
export let objAttributes = {};
</script>
<p transition:fade>
{objAttributes.obj}
{#if objAttributes.otherattrib}<em>{objAttributes.otherattrib}</em>{/if}
</p>
This is because your on:click events are defined wrongly.
The on:click takes as argument a function like this
<button on:click={functionGoesHere}>
or, if you want it inlined
<button on:click={() => { }>
What happens in your case is that you directly call a function and the result of this function will then be called when the button is clicked. You can see that in this example:
<script>
function createFn() {
return () => console.log('logging this')
}
</script>
<button on:click={createFn}>Click here</button>
in this example the function () => console.log('logging this') will be attached the button.
So to come back to your code, this is easily fixed by making it a function instead of a function call:
<li><button on:click={() => addContent("Home Page")}>Home</button></li>

Svelte: Reference to self for use in modules

I have a simple popup component in Popup.svelte:
<script>
let hidden = true;
</script>
<button on:click={() => hidden = !hidden}> Pop </button>
<div class:hidden> Extra Content </div>
<style>
.hidden { display: none; }
</style>
and I have multiple of these shown in my app:
<script>
import Popup from './Popup.svelte';
</script>
<div> <Popup /> </div>
<div> <Popup /> </div>
<div> <Popup /> </div>
I would like to hide other popups at the component level when clicked, meaning only one popup can be visible at any time. I thought svelte module contexts would suit, but I am not able to add a reference to self using which I can call say setHidden function for others.
<script>
import {onMount} from 'svelte';
let hidden = true;
export const setHidden = value => hidden = value;
const toggleHidden = () => {
if (hidden === true) { // transition to false
hideOthers();
}
hidden = !hidden
}
onMount(() => elements.add(self);
</script>
<script context="module">
const elements = new Set();
const hideOthers = () => elements.forEach(e => e.setHidden(true))
</script>
Playground here
The context approach is a good one, but instead of adding self to the elements, you can add the component's setHidden function:
<script context="module">
const elements = new Set();
const hideOthers = () => elements.forEach(hide => hide())
</script>
<script>
onMount(() => elements.add(setHidden))
</script>
For simply hiding things, #Stephane's answer works just fine. But if there are multiple functions, you could add them inside an object and add that to the module context.
You can also check if you are with the current instance or not while looping through all the elements by using a Map instead of a set. I'm using object keys to get unique references to each instance.
<script context="module">
const elements = new Map();
const hideOthers = () => Array.from(elements.entries()).forEach(([k, funcs]) => {
funcs.setHidden(true)
// if (k === key)
// true for current instance
// do something in the current instance
});
</script>
<script>
let key = {};
let hidden = true; ​
​ const funcs = {
setHidden: value => hidden = value,
setSomething: value => something = value,
setElse: value => else = value
}
​onMount(() => elements.set(key, funcs))
</script>

How can I use a div element to redirect with MVC htmlhelper?

I have a bunch of div elements that look like this at the moment:
<div onclick="window.open('Technology','mywindow');" class="grid" id="technology">
<p class="category-title">Technology</p>
</div>
I would like to get rid of the window.open and instead use MVC htmlhelper like actionlink to redirect users when they click on the div element. How can I do that?
The correct way to handle this is with a simple anchor tag.
Replace "myAction" and "myController" with the location you want to redirect the user to.
<a href="#Url.Action("myAction", "myController")">
<div class="grid" id="technology">
<p class="category-title">Technology</p>
</div>
</a>
ActionLink will return an anchor tag. What you can do is, you can assign the URL to the attribute of div via #Url.Action(). Then in JavaScript you can grab this URL and open a new window.
<div data-action ="#Url.Action("Text", "ActionName")">
<p class="category-title">Technology</p>
</div>
And in jQuery
$('div').click(function () {
var url = $(this).attr('data-action');
if(url !== undefined)
window.location.href = url;
});
Alternatively in pure JS,
document.document.getElementsByTagName('div').onclick = function(e) {
var url = this.getAttribute('data-action')
if(url !== null)
window.location.href = url;
}
This way, all divs having the data-action attribute will redirect to new page.

How to get the value of the element selected in ListView JQUERYMOBILE

Hi i'm developping a simple listView that lists the column "firstname" of my table : i want to get the selected value (name) , i found this link but it shows he how to get the index and not the value of the selected item http://jsfiddle.net/w2JZU/
here's my code :
HTML:
<div id="popup-bg">
</div>
<div id="popup-box">
<div data-role="page" id="home">
<div data-role="header">
<h1>Players</h1>
</div>
<div data-role="content">
<ul data-role="listview" id="artiste" >
</ul>
</div>
</div>
</div>
</section>
js :
function successCB()
{
db.transaction(queryDB, errorCB);
}
function queryDB(tx)
{
tx.executeSql('SELECT * FROM Players ', [], querySuccess, errorCB);
}
function querySuccess(tx, results)
{
var len = results.rows.length;
var dataset= results.rows;
$("#artiste").empty();
for (var i = 0; i < len; i++)
{ item = dataset.item(i);
$("#artiste").append( "<li data-theme='c'><a href='game.html'>
<img src='images/avatar.jpg'><h3>"+item['firstName']+"</h3></a></li>" );
}
There isn't a "value" for an item in a list using the li tag. However, you can get the text of what's in that list element using the jQuery .text() method. I've modified the jsfiddle you referenced to do exactly that: http://jsfiddle.net/Cht2e/
You might want to consider adding another attribute to the li tag, such as data-name (you can make up the attribute) and then you can get that via the jQuery .attr() method. For example, you might change you append code to do:
$("#artiste").append( "<li data-theme='c' data-name='"+item['firstName']+"'><a href='game.html'>
<img src='images/avatar.jpg'><h3>"+item['firstName']+"</h3></a></li>" );
And then attach your click handler like this:
$('#artiste').children('li').on('click', function () {
alert('Selected Name=' + $(this).attr('data-name'));
});
I don't think this is necessarily the best structure or approach to take, but it will accomplish what you're asking.

Resources