How to extract index from this string? - javascript

I'm studying how to create my own lightbox component in vue. I figured out how to do it, but I faced one issue. I don't know how to get an access to this index of the array.
<LightBox
:thumbnail="images[7]" :images="images"></LightBox>
<template>
<div>
<a href="" #click.prevent="show">
<img class="thumbnail" :src="thumbnail">
</a>
<div class="lightbox" v-if="visible" #click="hide">
<div class="flex">
<div class="cursor left" #click.stop="prev" :class="{ 'invisible': !hasPrev() }">
<svg fill="#ffff" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" width="100px" height="100px"
viewBox="0 0 537.66 537.66" xml:space="preserve" stroke="#ffff">
<g id="SVGRepo_bgCarrier" stroke-width="0" />
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round" />
<g id="SVGRepo_iconCarrier">
<g>
<g>
<path
d="M526.375,175.442H249.458l101.781-115.23c2.939-5.875-0.006-10.64-6.574-10.64H194.735 c-15.012,0.003-34.74,30.233-44.538,41.188C132.96,110.028,3.146,254.326,2.204,256.208c-2.938,5.875-2.938,15.404,0,21.279 L177.52,477.449c2.938,5.875,10.646,10.64,17.215,10.64h149.931c6.57,0,9.514-4.765,6.576-10.64l-98.746-114.347h273.879 c6.234,0,11.285-5.052,11.285-11.285v-165.09C537.66,180.494,532.609,175.442,526.375,175.442z" />
</g>
</g>
</g>
</svg>
</div>
<div class="lightbox-image" #click.stop="">
<img :src="images[index]">
</div>
<div class="cursor right" #click.stop="next" :class="{ 'invisible': !hasNext() }">
<svg fill="#ffff" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" width="100px" height="100px"
viewBox="0 0 537.66 537.66" xml:space="preserve" transform="rotate(180)" stroke="#ffff">
<g id="SVGRepo_bgCarrier" stroke-width="0" />
<g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round" />
<g id="SVGRepo_iconCarrier">
<g>
<g>
<path
d="M526.375,175.442H249.458l101.781-115.23c2.939-5.875-0.006-10.64-6.574-10.64H194.735 c-15.012,0.003-34.74,30.233-44.538,41.188C132.96,110.028,3.146,254.326,2.204,256.208c-2.938,5.875-2.938,15.404,0,21.279 L177.52,477.449c2.938,5.875,10.646,10.64,17.215,10.64h149.931c6.57,0,9.514-4.765,6.576-10.64l-98.746-114.347h273.879 c6.234,0,11.285-5.052,11.285-11.285v-165.09C537.66,180.494,532.609,175.442,526.375,175.442z" />
</g>
</g>
</g>
</svg>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: {
thumbnail: {
type: String,
required: true,
},
images: {
type: Array,
default: () => [],
},
},
data() {
return {
visible: false,
index: 0,
};
},
methods: {
show() {
this.visible = true;
this.index = this.thumbnail.length
},
hide() {
this.visible = false;
this.index = 0;
},
hasNext() {
return this.index + 1 < this.images.length;
},
hasPrev() {
return this.index - 1 >= 0
},
prev() {
if (this.hasPrev()) {
this.index -= 1;
}
},
next() {
if (this.hasNext()) {
this.index += 1
}
}
}
}
</script>
I don't understand how to do it since I haven't found any method that can extract it from this string. I had tried to use IndexOf(), lastIndexOf(), map(), slice() but none of these methods hadn't worked for me

If you want to find index of it use:
let thumbIndex = images.findIndex(element => element === thumbnail);
Or instead of using string for thumbnail, try using just index of it, since you already passed this with images array, so there is no need to pass it again.
It would look like this:
<LightBox :thumbnailindex="7" :images="images"></LightBox>
Then you will be able to access it directly from the array:
<img class="thumbnail" :src="images[thumbnailindex]">
Of course will need slight refactor of props, methods and template :)

Related

React SVG Component using Objects

I'm trying to get SVG's in a object file. then use SVG's like this.
import {CustomIcons} from "./Icons"
<CustomIcons name="FrameIcon" />
<CustomIcons name="VectorIcon" />
I just want to import one file and get a custom icon based on the name. I been trying this for hours and I'm lost
CustomIcon.tsx
export const CustomIcons = {
FrameIcon: (
<svg
width="632"
height="330"
viewBox="0 0 632 330"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M460.923 -287.339L760.908 192.738C748.744 201.994 736.08 210.636 723.487 219.419C695.409 238.987 667.885 262.248 636.416 276.436C612.104 287.397 589.793 302.386 564.742 311.911C523.785 327.491"
fill="#232323"
/>
</svg>
),
VectorIcon: (
<svg
width="632"
height="330"
viewBox="0 0 632 330"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M460.923 -287.339L760.908 192.738C748.744 201.994 736.08 210.636 723.487 219.419C69"
fill="#232323"
/>
</svg>
),
};
I see a couple of issues here, I'll try to explain as much as I can:
The type of the exported value (e.g. FrameIcon) is supposed to be a function
For instance, your file should export this way:
export {
FrameIcon: () => (
<svg
width="632"
height="330"
viewBox="0 0 632 330"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M460.923 -287.339L760.908 192.738C748.744 201.994 736.08 210.636 723.487 219.419C695.409 238.987 667.885 262.248 636.416 276.436C612.104 287.397 589.793 302.386 564.742 311.911C523.785 327.491"
fill="#232323"
/>
</svg>
),
VectorIcon: () => (
<svg
width="632"
height="330"
viewBox="0 0 632 330"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M460.923 -287.339L760.908 192.738C748.744 201.994 736.08 210.636 723.487 219.419C69"
fill="#232323"
/>
</svg>
),
};
The import is supposed to be:
import { FrameIcon } from './Icons'
Extra tip(s)
Create a folder called Icon, create the following files in it:
index.js
FrameIcon.jsx
VectorIcon.jsx
Your index.js should export all the icons created in this folder, for instance:
export * from './FrameIcon';
export * from './VectorIcon';
Your FrameIcon for instance should be:
const FrameIcon = () => (
<svg
width="632"
height="330"
viewBox="0 0 632 330"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M460.923 -287.339L760.908 192.738C748.744 201.994 736.08 210.636 723.487 219.419C695.409 238.987 667.885 262.248 636.416 276.436C612.104 287.397 589.793 302.386 564.742 311.911C523.785 327.491"
fill="#232323"
/>
</svg>
)
export { FrameIcon };
I hope this helps.
You should define CustomIcons as function component
something like this should work
import React from 'react';
const CustomIcons = (props) => {
const icons = {
FrameIcon :
<svg width="632" height="330" viewBox="0 0 632 330" fill="none" xmlns="http://www.w3.org/2000/svg" >
<path d="M460.923 -287.339L760.908 192.738C748.744 201.994 736.08 210.636 723.487 219.419C695.409 238.987 667.885 262.248 636.416 276.436C612.104 287.397 589.793 302.386 564.742 311.911C523.785 327.491" fill="#232323"/>
</svg>,
VectorIcon:
<svg width="632" height="330" viewBox="0 0 632 330" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M460.923 -287.339L760.908 192.738C748.744 201.994 736.08 210.636 723.487 219.419C69" fill="#232323"/>
</svg>
}
return <>
{icons[props.name]}
</>
};
export default CustomIcons;
`

How to make array with SVG's

I am trying to make an Icon component that loads in a js file that contains an array of objects with the svg values inside it.
My Icon component looks like this:
<template>
<div class="icon"></div>
</template>
<script>
import icons from "~/assets/icons.js"
export default {
mounted() {
console.log(icons)
}
}
</script>
My icons.js looks like this:
[
{
circle: `<svg xmlns="http://www.w3.org/2000/svg" width="50" height="50" viewBox="0 0 50 50">
<circle id="Ellipse_1" data-name="Ellipse 1" cx="25" cy="25" r="25" fill="red"/>
</svg>`,
},
{
square: `<svg xmlns="http://www.w3.org/2000/svg" width="50" height="50" viewBox="0 0 50 50">
<rect id="Rectangle_1" data-name="Rectangle 1" width="50" height="50" fill="#02f"/>
</svg>`,
},
{
triangle: `<svg xmlns="http://www.w3.org/2000/svg" width="50" height="50" viewBox="0 0 50 50">
<path id="Polygon_1" data-name="Polygon 1" d="M25,0,50,50H0Z" fill="#00ff3c"/>
</svg>`,
},
]
When I try to read the icons with the console.log it returns an empty object. I've tried changing my icons.js to see if it was because of these things: ``
But even when I change it to this it returns an empty object:
[
{name: "foo"},
{name: "bar"}
]
My project has been newly made and has no other content besides this, could it be possible i selected a wrong setting while creating the nuxt project? Or am I looking at this all wrong?
You need to export your data. BTW, I don't see any reason for using an array in your case. It seems like your data should be an object like this:
export default {
circle: `<svg xmlns="http://www.w3.org/2000/svg" width="50" height="50" viewBox="0 0 50 50">
<circle id="Ellipse_1" data-name="Ellipse 1" cx="25" cy="25" r="25" fill="red"/>
</svg>`,
square: `<svg xmlns="http://www.w3.org/2000/svg" width="50" height="50" viewBox="0 0 50 50">
<rect id="Rectangle_1" data-name="Rectangle 1" width="50" height="50" fill="#02f"/>
</svg>`,
}
//Then import like
import icons from "~/assets/icons.js"
// use it like
icons.circle

Filtering in jQuery by text not working because of element inside [duplicate]

This question already has answers here:
Using .text() to retrieve only text not nested in child tags
(30 answers)
Closed 1 year ago.
I am trying to extract elements if they match a certain phrase using jQuery.
I have the following piece of HTML:
<a href="#" class="drop-menu" data-name="admissions-ul">Admissions<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="17px" height="16px" viewBox="0 0 17 16" version="1.1" class=" replaced-svg">
<!-- Generator: sketchtool 57.1 (101010) - https://sketch.com -->
<title>251A26C8-EC92-4EBA-B449-40FA2643F2CB#2x</title>
<desc>Created with sketchtool.</desc>
<g id="Design" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="square">
<g id="Main-Navigation" transform="translate(-256.000000, -139.000000)" stroke="#009F9B" stroke-width="3">
<g id="add-icon" transform="translate(258.000000, 140.000000)">
<path d="M6.5,13.5 L6.5,0.5" id="Line-26"></path>
<path d="M0,7 L13,7" id="Line-26-Copy"></path>
</g>
</g>
</g>
</svg></a>
I am using the following code to try to extract it:
let tempElements = $(targetElement).filter(function () {
return $(this).text() === phrase;
})
Here, targetElement is a and phrase is Admissions. This should work but it is returning blank. I suspect it is because of the SVG that is inside the a tag. How do I fix this?
You can use contents().first() to target the first childNode which is the text node
const phrase = 'Admissions'
$('a').filter(function(){
return $(this).contents().first().text().trim() === phrase
}).css('color', 'red')
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a href="#" class="drop-menu" data-name="admissions-ul">Admissions<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="17px" height="16px" viewBox="0 0 17 16" version="1.1" class=" replaced-svg">
<!-- Generator: sketchtool 57.1 (101010) - https://sketch.com -->
<title>251A26C8-EC92-4EBA-B449-40FA2643F2CB#2x</title>
<desc>Created with sketchtool.</desc>
<g id="Design" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="square">
<g id="Main-Navigation" transform="translate(-256.000000, -139.000000)" stroke="#009F9B" stroke-width="3">
<g id="add-icon" transform="translate(258.000000, 140.000000)">
<path d="M6.5,13.5 L6.5,0.5" id="Line-26"></path>
<path d="M0,7 L13,7" id="Line-26-Copy"></path>
</g>
</g>
</g>
</svg></a>
<a href="#" class="drop-menu" data-name="admissions-ul">Best Admissions<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="17px" height="16px" viewBox="0 0 17 16" version="1.1" class=" replaced-svg">
<!-- Generator: sketchtool 57.1 (101010) - https://sketch.com -->
<title>251A26C8-EC92-4EBA-B449-40FA2643F2CB#2x</title>
<desc>Created with sketchtool.</desc>
<g id="Design" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="square">
<g id="Main-Navigation" transform="translate(-256.000000, -139.000000)" stroke="#009F9B" stroke-width="3">
<g id="add-icon" transform="translate(258.000000, 140.000000)">
<path d="M6.5,13.5 L6.5,0.5" id="Line-26"></path>
<path d="M0,7 L13,7" id="Line-26-Copy"></path>
</g>
</g>
</g>
</svg></a>
In order to only get the immediate child text of an element and ignore text from nested elements, you need to clone the element, remove child nodes, then get the text—as this answer illustrates. Once you do that, you can compare it to the text you want to filter by. For example:
$(function() {
const shallowTextMatch = (selector, text) => {
return $(selector).filter(function() {
let shallowText = $(this).clone().children().remove().end().text().trim()
return shallowText === text
})
}
let matchingElements = shallowTextMatch('a', 'Admissions')
console.log(matchingElements.length) // 2
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Admissions<span>Other Text</span>
Academics<span>More Ignored Text Admissions </span>
About<span>Lorem Ipsum</span>
Contact<span>Dolor Amit</span>
Admissions<span>For a second match</span>
Best Admissions<span>Ignored</span>

How to change CSS class to an <use> children inside a SVG?

I am making and animation the objetive is change the xlink:href inside a SVG. (this is for change a shape), and change class respect to their position inside.
This is my SVG
<svg viewBox="-20 -20 600 200" id="main">
<defs id="test">
<rect width="80" height="80" id="circle" fill="red" class="first" />
<rect width="80" height="80" id="square" fill="pink" class="second" />
<rect width="80" height="80" id="cross" fill="blue" class="third" />
</defs>
<g id="load-area">
<use x="0" xlink:href="#circle" />
<use x="100" xlink:href="#square" />
<use x="200" xlink:href="#cross" />
</g>
</svg>
The class in every rectelement, has a different animation-delay according to position (first execute at 0s, second at 2s, third at 4s and so on).
With JS I change every <use> at #load-area
main.children['load-area'].children[0].setAttribute("xlink:href", getFigure(random()));
And it works, the shape changes but, suppose when it gets three times the id #cross then all elements have third CSS class.
I need change CSS class inside every children of <use>, How can I do that?
Below an element tree :
I get all <use> with: main.children['load-area'].children but it does not have child element, as I show u below:
You can solve this using CSS variables that you combine with nth-child selector and you no more need the classes.
Here is a basic example
rect {
animation:change 3s var(--d,0s) infinite;
}
#keyframes change {
0% {
opacity:1;
}
33%,100% {
opacity:0;
}
}
#load-area > use:nth-child(1) {--d:0s}
#load-area > use:nth-child(2) {--d:1s}
#load-area > use:nth-child(3) {--d:2s}
/*#load-area > use:nth-child(N) {--d:Xs}*/
<svg viewBox="-20 -20 600 200" id="main">
<defs id="test">
<rect width="80" height="80" id="circle" fill="red" />
<rect width="80" height="80" id="square" fill="pink" />
<rect width="80" height="80" id="cross" fill="blue" />
</defs>
<g id="load-area">
<use x="0" xlink:href="#circle" />
<use x="100" xlink:href="#square" />
<use x="200" xlink:href="#cross" />
</g>
</svg>
<svg viewBox="-20 -20 600 200" id="main">
<g id="load-area">
<use x="0" xlink:href="#square" />
<use x="100" xlink:href="#circle" />
<use x="200" xlink:href="#cross" />
</g>
</svg>
If the number is unknown or very big you can easily use a JS loop:
var e = document.querySelectorAll('#load-area use');
for(var i=0;i<e.length;i++) {
e[i].style.setProperty('--d',i+"s");
}
rect {
animation:change 3s var(--d,0s) infinite;
}
#keyframes change {
0% {
opacity:1;
}
33%,100% {
opacity:0;
}
}
<svg viewBox="-20 -20 600 200" id="main">
<defs id="test">
<rect width="80" height="80" id="circle" fill="red" />
<rect width="80" height="80" id="square" fill="pink" />
<rect width="80" height="80" id="cross" fill="blue" />
</defs>
<g id="load-area">
<use x="0" xlink:href="#circle" />
<use x="100" xlink:href="#square" />
<use x="200" xlink:href="#cross" />
</g>
</svg>
document.getElementsByTagName("use")[0].setAttribute("xlink:href", "#circle");
element.setAttribute(attributename, attributevalue)
Here is how you can change element attributes

Find css class after parent div

there is any jquery which is find class after parent div, I am using class "trapezoid-two" and make jquery code but that create issue, so can any one tel me how to find css after parent div class('ban-menu1').
HTML:-
<div class="col-md-2 nopadding">
<div class="ban-menu1"></div>
<svg class="trapezoid-two" viewbox="0 0 100 100" preserveAspectRatio="none" width="100%">
<defs>
<pattern id="img1" patternUnits="userSpaceOnUse" width="100" height="100">
<image xlink:href="images/shade-two.jpg" x="0" y="0" width="110" height="100" />
</pattern>
</defs>
<path d="M0,0 L100,23 L100,77 L0,100z" fill="url(#img1)"></path>
</svg>
</div>
Jquery
$(document).ready(function(){
$( ".trapezoid-two" ).hover(
function() {
$(this).find('path').attr('d','M0,0 L100,0 L100,100 L0,100z');
$(this).parent().addClass('img-scale');
}, function() {
$(this).find('path').attr('d','M0,0 L100,23 L100,80 L0,100z');
$(this).parent().removeClass('img-scale');
}
);
});
ban-menu1 is a sibling of .trapezoid-two use prev() to help you add a class to it
$(document).ready(function(){
// svg path change
$( ".trapezoid-two" ).hover(
function() {
$(this).find('path').attr('d','M0,0 L100,0 L100,100 L0,100z');
$(this).prev().addClass('img-scale');
}, function() {
$(this).find('path').attr('d','M0,0 L100,23 L100,80 L0,100z');
$(this).prev().removeClass('img-scale');
}
);
see demo : https://jsfiddle.net/cgvbt80q/

Categories