Iterate through document.querySelectorAl ascendand elements

Hope you could help me solve this JS puzzle.

I need to run through the webpage, find divs with class “lstp-t” then hover over the container div.user-grid-card_avatar and press some more buttons which are loaded via AJAX.

Here’s the HTML:

<div class="ugrid_i">
  <div class="user-grid-card __xs">
    <div class="user-grid-card_avatar"></div>
   <divclass="user-grid-card_cnt">
      <div class="ellip"></div>
      <div></div>
    </div>
  </div>

<div class="ugrid_i">
  <div class="user-grid-card __xs">
    <div class="user-grid-card_avatar"><!-- this I want to hover over --></div>
   <div class="user-grid-card_cnt">
      <div class="lstp-t"></div>
      <div></div>
    </div>
  </div>

</div>

I went to read about querySelectorAll at MDN and several hours after I wrote this:

// Find all elements containing the specified text
const elementsWithText = document.querySelectorAll("div.lstp-t");

console.log(elementsWithText);
// outputs [NodeList(65) [div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t, div.lstp-t]

// Define the class name of the parent container
const parentContainerClass = ".user-grid-card_avatar";

    // Iterate through the elements containing the text
    elementsWithText.forEach(element => {
        // Find the parent container with the specified class
        let parentContainer = element.closest('parentContainerClass');

        console.log(parentContainer); // outputs 65 null and the rest doesn't work of course

        
        let event = new Event('mouseenter', {
        'view': window,
        'bubbles': true,
        'cancelable': true
        });
        
        
        // If a parent container with the specified class is found, trigger a click event on it
        if (parentContainer) {
            parentContainer.dispatchEvent(event); // Trigger click event
        }
    });

I would appreciate any ideas from you guys!

Is there a way to force the focus on a determined window tab?

A little bit of background: I’m working with ServiceNow and we’re trying to build a custom UI Page/Portal Widget that can listen to an external barcode scanner, this solution is mobile-focused. The plan is to use a Mobile Web Screen so we can call this page from the ServiceNow Agent App. (OOTB Barcode Scanner via mobile does not meet our business needs).

The challenge I’m facing right now is that I have a simple HTML page with an input, and then I added a load event to focus the input after the page loads.

This works well if we try the page from desktop, but once we try it from the mobile app, it doesn’t work.

Desktop View vs
Mobile View

I have tried a bunch of different things:

  • $j( '#input_asset_tag' ).focus();
  • window.focus()
  • document.activeelement.blur()
  • $j( '#input_asset_tag' ).click();

I realized that the mobile window does not have a focus when it is opened by adding this line of code to the load event:
alert( 'Has focus: '+ document.hasFocus() );

So now when the page is opened I get an alert that tells me if the document has focus.
In desktop returns true, but mobile returns false:
Desktop has focus vs Mobile has no focus

The main issue is that the mobile web window is not focused by default. I tried setting a timeout and after 5 seconds ran this line: $j( '#input_asset_tag' ).focus();, Then opened the mobile web screen, tab on any part of the screen before the 5 seconds were reached and then that worked, the input got focused.

Also, I tried adding another event “keypress” so we can listen to the external barcode scanner this way, but it doesn’t seem to work until you set the focus on the window (tab on any part of the screen).

We need this solution to work without the user having to click on the screen, the only responsibility of the user should be to press the scan button on the hardware to scan barcodes and leave the rest to the app.

*$j(‘element’) is the syntax used in ServiceNow to call jQuery.

*This is how the load event looks like:

window.addEventListener( 'load', function(){
    $j( '#input_asset_tag' ).focus();
    alert( 'Has focus: '+ document.hasFocus() );

});

I found an article stating this depends entirely on the browser and we don’t have too much control over this, but I’m still not convinced.

How to create a simple html captcha using javascript

I’m new to web design, and I created this HTML form, but I want it to also have a simple captcha.I want the form to be submitted only if the required values are correct.

<form id="captcha" action="" method="post">
<input type="text" name="engagement" placeholder="Your name">
/** then the user has to enter the value in cap1 into cap2. before he can submit the form */
<input id="cap1" type="text" name="time1" value="123">
  <input id="cap2" type="text">
  <button type="submit"  id="button">Join</button>
</form>

<script>
/** this was my trash code which i couldn't complete */
const captcha = document.getElementById('captcha'),
  cap1 = document.getElementById('cap-1'),
  cap2 = document.getElementById('cap-2');
</script>

Please, if possible, add an alert when the person inputs the wrong value.

Sidebar reopening animation on page navigation through navbar

So in this JavaScript below I run addEventListener click on a button, if clicked it will add to the .sidebar active class.

const sidebarbtn = document.querySelector('#sidebar-btn');
const sidebar = document.querySelector('.sidebar');

sidebarbtn.addEventListener('click', function () {
    sidebar.classList.toggle('active');
    localStorage.setItem('sidebarActive', sidebar.classList.contains('active'));
});


document.addEventListener('DOMContentLoaded', function () {
    const isSidebarActive = localStorage.getItem('sidebarActive') === 'true';
    if (isSidebarActive) {
        sidebar.classList.add('active');
    }
});

Everything is working. If I open the sidebar and redirect using navbar to another page it will stay opened. The thing I am asking is more esthetical rather than functional.

When I navigate with opened sidebar, it will firstly load closed because it is default then it will open. The same thing happens with dark/light mode using the localStorage. Is there any solution to this?

How does Android handle APK apps data?

I have created an app using React Native and Expo, and I built it into an apk using EAS, I have installed it on my phone for debugging purposes and the such.

Anyways, I am using the Expo filesystem library to create files within the documentDirectory as Expo names it. My question is, if I make changes and rebuild the APK and reinstall it, will the data there be intact? Or will the install wipe it due to the new version? And if so, how do I make sure it will install it as a separate app? Will changing the package name work?

This is the Expo module I am using: https://docs.expo.dev/versions/latest/sdk/filesystem

I am using a Xiaomi phone running MIUI, which is built upon Android.

Thanks in advance for any answers.

error in a user loading controller for excel, but it is an error that does not throw a status

From the front an Excel file is loaded with around 50 to 100 users, some cases may be more, however the problem lies in the fact that, after loading a third of the users, the following error is thrown.

POST /api/loadXLSX/ – – ms – –

which causes the front to issue an alert saying that there was a problem but the back continues to iterate the users after that error.

I’m not sure how to handle the error since I don’t know if it’s a settimeout or what?

The error is not shown if there are between 0 and 50 users, but when there are more, at some point the error is thrown.

We cannot lower the number of users since the company wants it to be massive and fast.

how to create diagonal galleries/banners that move on scroll

I’m trying to create a diagonal gallery that moves with scroll, but when I scroll too fast the sliders (pictures) don’t return to their positions, I tried to solve this problem, but it doesn’t look good, the pictures have to return to a position when I scroll up or down without getting disordered.

examples:
https://www.env.studio/
https://3rcore.com/

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" href="styles.css">
    <title>Locomotive scrolling</title>
</head>
<body>


    <div class="container">

        <div class="container__gallery">

            <div class="slide__1">
                <div class="img1">
                </div>
                <div class="img2">
                </div>
                <div class="img3">
                </div>
                <div class="img4">
                </div>
            </div>
            <div class="slide__2">
                <div class="img2"></div>
                <div class="img4">
                </div>
                <div class="img1">
                </div>
                <div class="img3">
                </div>
            </div>
            <div class="slide__3">
                <div class="img1">
                </div>
                <div class="img3">
                </div>
                <div class="img2">
                </div>
                <div class="img4">
                </div>
            </div>
            <div class="slide__4">
                <div class="img4">
                </div>
                <div class="img1">
                </div>

                <div class="img2">
                </div>
                <div class="img3">
                </div>
            </div>

        </div>

    </div>
</body>
<script src="main.js"></script>

</html>
*{
    margin: 0;
    padding: 0;
}

.container{
    background-color: white;
    width: 100%;
    height: 800px;
    margin-top: 1000px;
    margin-bottom: 1000px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.container__gallery{
    position: relative;
    background-color: white;
    width: 70%;
    height: 80%;
    overflow: hidden;
    border-radius: 8px;
}


.slide__1, .slide__2, .slide__3, .slide__4{
    position: absolute;
    background-color: white;
    width: 140%;
    height: 40%;
    display: flex;
    margin-bottom: 5px;
    transform: skew(-10deg) rotateZ(20deg);
}

.slide__1{
    top: -37px;
    right: -830px;
    transition: all 50ms ease-in;
}

.slide__2{
    top: 10px;
    right: -190px;
    transition: all 50ms ease-in;
}

.slide__3{
    top: 400px;
    right: -430px;
    transition: all 50ms ease-in;
}

.slide__4{
    top: 568px;
    right: -100px;
    transition: all 50ms ease-in;
}

.img1{
    background-color: blueviolet;
    background-image: url("https://static.fundacion-affinity.org/cdn/farfuture/PVbbIC-0M9y4fPbbCsdvAD8bcjjtbFc0NSP3lRwlWcE/mtime:1643275542/sites/default/files/los-10-sonidos-principales-del-perro.jpg");
    background-position: center;
    background-size: cover;
    background-repeat: no-repeat;
    height: 100%;
    width: 25%;
    margin-right: 5px;
}
.img2{
    background-color: orange;
    background-image: url("https://media.glamour.mx/photos/6529b544daab1b14402e2b34/16:9/w_2992,h_1683,c_limit/qu%C3%A9-significa-encontrarte-con-un-gato-negro-en-viernes-13-.png");
    background-position: center;
    background-size: cover;
    background-repeat: no-repeat;
    height: 100%;
    width: 25%;
    margin-right: 5px;
}
.img3{
    background-color: crimson;
    background-image: url("https://ca-times.brightspotcdn.com/dims4/default/796e6c9/2147483647/strip/true/crop/1970x1108+39+0/resize/1200x675!/quality/75/?url=https%3A%2F%2Fcalifornia-times-brightspot.s3.amazonaws.com%2F12%2Fa5%2F79e097ccf62312d18a025f22ce48%2Fhoyla-recuento-11-cosas-aman-gatos-top-001");
    background-position: center;
    background-size: cover;
    background-repeat: no-repeat;
    height: 100%;
    width: 25%;
    margin-right: 5px;
}
.img4{
    background-color: black;
    background-image: url("https://www.ngenespanol.com/wp-content/uploads/2023/12/descubren-que-los-humanos-influimos-en-el-color-de-ojos-de-los-perros-1280x720.jpg");
    background-position: center;
    background-size: cover;
    background-repeat: no-repeat;
    height: 100%;
    width: 25%;
    margin-right: 5px;
}


const element = document.querySelector('.container__gallery')
const slider1 = document.querySelector('.slide__1')
const slider2 = document.querySelector('.slide__2')
const slider3 = document.querySelector('.slide__3')
const slider4 = document.querySelector('.slide__4')

let lastScrollTop = 0

let control = {
    top1: -37,
    right1: -830,
    top2: 10,
    right2: -190,
    top3: 400,
    right3: -430,
    top4: 350,
    right4: 460,
}

const options = {
    root: null,
    rootMargin: '600px',
    threshold: 0.05
}

const observer = new IntersectionObserver(callback, options)
observer.observe(element)

function validateScrolling(){

    const currentScrollTop = window.pageYOffset || document.documentElement.scrollTop;
    const isScrollingDown = currentScrollTop > lastScrollTop;
    lastScrollTop = currentScrollTop;
    return isScrollingDown;
}

function move(isScrollingDown){
    // Definir el ángulo en radianes (20 grados)
    const anguloRadianes = 158.72 * (Math.PI / 180);
    const scale = 0.01;
    let deltaX = 0
    let deltaY = 0
    const scrollY = window.scrollY || window.pageYOffset;

    if(!(isScrollingDown ===false && scrollY <= 200 && scrollY >= 122))
        // Calcular el cambio en las coordenadas X e Y utilizando funciones trigonométricas
        deltaX = scrollY * Math.cos(anguloRadianes) * scale;
        deltaY = scrollY * Math.sin(anguloRadianes) * scale;



    return {deltaX, deltaY}
}

function scrollerEvent(){

    let isScrollingDown = validateScrolling()
    let delta = move(isScrollingDown)

    if(isScrollingDown == false && scrollY <= 200 && scrollY >= 120){

        control.right1 = -830;
        control.top1 = -37;

        control.right2 = -190;
        control.top2 = 10;

        control.right3 = -430 ;
        control.top3 = 400 ;

        control.right4 = 460;
        control.top4 = 350;

        slider1.style.right = control.right1 + "px";
        slider1.style.top = control.top1 + "px";

        slider2.style.right = control.right2 + "px";
        slider2.style.top = control.top2 + "px";

        slider3.style.right = control.right3 + "px";
        slider3.style.top = control.top3 + "px";

        slider4.style.right = control.right4 + "px";
        slider4.style.top = control.top4 + "px";
    }
    else if(isScrollingDown == false && scrollY <= 1000 && scrollY >= 977){

        control.right1 = -537.9142029413038  ;
        control.top1 = -150.7620539573103;

        control.right2 = -482.0857970586964  ;
        control.top2 = 123.7620539573103;

        control.right3 = -225.5399420589124  ;
        control.top3 = 320.36656222988285 ;

        control.right4 = 167.91420294130347;
        control.top4 = 463.76205395731006;


        slider1.style.transition = "600ms"
        slider1.style.right = control.right1 + "px";
        slider1.style.top = control.top1 + "px";
        //slider1.style.transition = "50ms"

        slider2.style.transition = "600ms"
        slider2.style.right = control.right2 + "px";
        slider2.style.top = control.top2 + "px";
        //slider2.style.transition = "50ms"

        slider3.style.transition = "600ms"
        slider3.style.right = control.right3 + "px";
        slider3.style.top = control.top3 + "px";

        slider4.style.transition = "600ms"
        slider4.style.right = control.right4 + "px";
        slider4.style.top = control.top4 + "px";
        //slider4.style.transition = "50ms"
    }
    else if (isScrollingDown){
        // Actualizar las coordenadas del objeto
        control.right1 -= delta.deltaX;
        control.top1 -= delta.deltaY;

        control.right2 += delta.deltaX;
        control.top2 += delta.deltaY;

        control.right3 -= (delta.deltaX * 0.7);
        control.top3 -= (delta.deltaY * 0.7);

        control.right4 += delta.deltaX;
        control.top4 += delta.deltaY;

        slider1.style.transition = "50ms"
        slider1.style.right = control.right1 + "px";
        slider1.style.top = control.top1 + "px";

        slider2.style.transition = "50ms"
        slider2.style.right = control.right2 + "px";
        slider2.style.top = control.top2 + "px";

        slider3.style.transition = "50ms"
        slider3.style.right = control.right3 + "px";
        slider3.style.top = control.top3 + "px";

        slider4.style.transition = "50ms"
        slider4.style.right = control.right4 + "px";
        slider4.style.top = control.top4 + "px";
    }
    else{
        // Actualizar las coordenadas del objeto

        control.right1 += delta.deltaX;
        control.top1 += delta.deltaY;

        control.right2 -= delta.deltaX;
        control.top2 -= delta.deltaY;

        control.right3 += (delta.deltaX *0.7);
        control.top3 += (delta.deltaY *0.7);

        control.right4 -= delta.deltaX;
        control.top4 -= delta.deltaY;


        slider1.style.transition = "50ms"
        slider1.style.right = control.right1 + "px";
        slider1.style.top = control.top1 + "px";

        slider2.style.transition = "50ms"
        slider2.style.right = control.right2 + "px";
        slider2.style.top = control.top2 + "px";

        slider3.style.transition = "50ms"
        slider3.style.right = control.right3 + "px";
        slider3.style.top = control.top3 + "px";

        slider4.style.transition = "50ms"
        slider4.style.right = control.right4 + "px";
        slider4.style.top = control.top4 + "px";
    }
}

function callback(entries){

    entries.forEach(entry =>{
        let intersecting = entry.isIntersecting
        if (intersecting){
            lastScrollTop = window.pageYOffset || document.documentElement.scrollTop;
            window.addEventListener("scroll", scrollerEvent)
        }
        else{
            window.removeEventListener("scroll", scrollerEvent);
        }
    })
}

How to simplify jQuery code that uses ids and class names that include array loop indexes

I have a chunk of working jQuery code (seen below) but it’s very repetitive. How do I make it more simplified?

    $('.card-loop2').addClass('d-none').removeClass('d-flex');
    $('.card-loop3').addClass('d-none').removeClass('d-flex');
    $('.card-loop4').addClass('d-none').removeClass('d-flex');



    $('#newsUpdateLink').on( "click", function() {
        $('.category-loop1.card-loop1').addClass('d-flex').removeClass('d-none');
        $('.category-loop2.card-loop1').addClass('d-flex').removeClass('d-none');
        $('.category-loop3.card-loop1').addClass('d-flex').removeClass('d-none');
        $('.category-loop4.card-loop1').addClass('d-flex').removeClass('d-none');

        $('.card-loop2').addClass('d-none').removeClass('d-flex');
        $('.card-loop3').addClass('d-none').removeClass('d-flex');
        $('.card-loop4').addClass('d-none').removeClass('d-flex');
    } );

    $('#categoryLink1').on( "click", function() {
        $('.category-loop1.card-loop1').addClass('d-flex').removeClass('d-none');
        $('.category-loop1.card-loop2').addClass('d-flex').removeClass('d-none');
        $('.category-loop1.card-loop3').addClass('d-flex').removeClass('d-none');
        $('.category-loop1.card-loop4').addClass('d-flex').removeClass('d-none');

        $('.category-loop2').addClass('d-none').removeClass('d-flex');
        $('.category-loop3').addClass('d-none').removeClass('d-flex');
        $('.category-loop4').addClass('d-none').removeClass('d-flex');
    } );

    $('#categoryLink2').on( "click", function() {
        $('.category-loop2.card-loop1').addClass('d-flex').removeClass('d-none');
        $('.category-loop2.card-loop2').addClass('d-flex').removeClass('d-none');
        $('.category-loop2.card-loop3').addClass('d-flex').removeClass('d-none');
        $('.category-loop2.card-loop4').addClass('d-flex').removeClass('d-none');

        $('.category-loop1').addClass('d-none').removeClass('d-flex');
        $('.category-loop3').addClass('d-none').removeClass('d-flex');
        $('.category-loop4').addClass('d-none').removeClass('d-flex');
    } );

    $('#categoryLink3').on( "click", function() {
        $('.category-loop3.card-loop1').addClass('d-flex').removeClass('d-none');
        $('.category-loop3.card-loop2').addClass('d-flex').removeClass('d-none');
        $('.category-loop3.card-loop3').addClass('d-flex').removeClass('d-none');
        $('.category-loop3.card-loop4').addClass('d-flex').removeClass('d-none');

        $('.category-loop1').addClass('d-none').removeClass('d-flex');
        $('.category-loop2').addClass('d-none').removeClass('d-flex');
        $('.category-loop4').addClass('d-none').removeClass('d-flex');
    } );

    $('#categoryLink4').on( "click", function() {
        $('.category-loop4.card-loop1').addClass('d-flex').removeClass('d-none');
        $('.category-loop4.card-loop2').addClass('d-flex').removeClass('d-none');
        $('.category-loop4.card-loop3').addClass('d-flex').removeClass('d-none');
        $('.category-loop4.card-loop4').addClass('d-flex').removeClass('d-none');

        $('.category-loop1').addClass('d-none').removeClass('d-flex');
        $('.category-loop2').addClass('d-none').removeClass('d-flex');
        $('.category-loop3').addClass('d-none').removeClass('d-flex');
    } );

I’ve tried to do a for loop in jQuery but it did not work at all the way I was expecting.

How to remove piecemeal loading from WMS Geoserver and load the entire map using react-leaflet?

I’m implementing a timelapse, selecting a date range, but I’m not able to show the entire map at once, it’s loading via Tiles.

const Map = () => {
    const [selectedLayers, setSelectedLayers] = useState([]);
    const [timelapseActive, setTimelapseActive] = useState(false);
    const [startDate, setStartDate] = useState(new Date());
    const [endDate, setEndDate] = useState(new Date());
    const [selectedDate, setSelectedDate] = useState(new Date());

    const timelapseLayers = filterR["Filter"];

    useEffect(() => {
        let interval;
        if (timelapseActive) {
            interval = setInterval(() => {
                setSelectedDate(currentDate => {
                    let nextDate = new Date(currentDate);
                    nextDate.setDate(nextDate.getDate() + 1);
                    if (nextDate > endDate) {
                        nextDate = startDate;
                    }
                    return nextDate;
                });
            }, 3000);
        }

        return () => {
            if (interval) {
                clearInterval(interval);
            }
        };
    }, [timelapseActive, startDate, endDate]);

    const renderTimelapseWmsTiles = (selectedDate, layers) => {
        return layers.map(layer => {

            const timeParam = { time: selectedDate.toISOString().split('T')[0] };

            return (
                <WMSTileLayer
                    key={`${layer.name}-${selectedDate}`}
                    url={layer.wms_url}
                    layers={layer.name}
                    format="image/png"
                    transparent={true}
                    version="1.3.0"
                    {...timeParam}
                />
            );
        }).filter(component => component !== null);
    };
....
return (
    ....

Does anyone know a possible solution for this? I’ve already tried saving it in useState and then showing it to the map, but it still doesn’t work.

How do I test a color value in Javascript?

Setting a color value in Javascript is easy.

But what is the canonical color format across browsers? In other words what is the value of window.getComputedStyle(element).getPropertyValue("color") or window.getComputedStyle(element).getPropertyValue("background-color")? As they are strings it is hard to test for a specific color or transparency.

Is there a way in Javascript to turn these values reliably into an array [r-value, g-value, b-value, alpha] or any other acceptable CSS color value format? Or coerce these in a comparable color format/string? Like a boolean function Color.equal( colorString )?

(I’ve spend just four days of debugging to find out that "rgb(0 0 0/0)" is not equal to "rgba(0, 0, 0, 0)" although semantically they are the same color.)

Integrating OpenStreetMap with React Native for Marker Placement: How?

Hey fellow developers,

I’m currently working on an application where I need to integrate a map feature using OpenStreetMap in React Native. Specifically, I’m looking to set markers on the map dynamically based on certain data points.

Ideally, I’m looking for guidance on:

How to integrate OpenStreetMap into a React Native project.

How to dynamically add markers to the map based on data points.

Any potential challenges or pitfalls to watch out for during integration.

Any insights, code snippets, or tutorials would be greatly appreciated! Thank you in advance for your help. Let’s build better maps together!

Cheers!

I’ve done some research, but I’m struggling to find clear, concise resources or examples on how to achieve this. Has anyone successfully integrated OpenStreetMap into a React Native app for marker placement? If so, could you share your approach or any helpful resources?

Ayuda con Javascript

tengo un problema y me preocupa bastante, estoy aprendiendo Javascript, ya voy por DOM, estoy viendo un curso de Udemy. Aca la cuestión: Se leer codigo y hasta crear funciones basicas, pero a la hora de manejar arrays o replicar codigo por ej. Se me pone la mente en blanco y no se que hacer. Como puedo solucionar esto? Algun metodo para practicar que sirva para memorizar cosas? Espero sus respuestas, Gracias!!

Estoy haciendo un curso en Udemy, practico con esos ejercicios, pero a la hora de hacerlo por mi mismo no me salen, a la hora de implementar arrays, funciones y bucles me cuesta mas.

How to programatically fast forward video on a website

I’m considering writting a browser plugin (firefox or chrome), that will trigger a fast forward or skip on an embedded video player on a website. Its not youtube, but a custom video player component. No idea what it is.

Using developer tools, I can see that the video has a skip 10s button, that has a specific Div ID. Similar to youtube, it also have one of thoes progress bars, that you can click on to skip to different parts of the video.

How would I go about creating an action on this video, to fast forward or skip? Is there some sort of API in the browser I can use, to perorm these sorts of actions?

Thanks,