Difficulties encountered when trying to create a pop-up flyover image in a Greasemonkey script

Recently, I ventured into the world of Greasemonkey scripts to learn JavaScript. My script's objective is quite simple - it enlarges a thumbnail image to a popup window when hovering over it with the mouse.

Almost nearing completion, I encountered a few hurdles...

  1. Upon triggering the mouseenter event, a popup window is spawned but the same image also loads on the webpage itself! This seems to hinder the execution of the mouseleave function as well.

  2. Is there a way to dynamically adjust the width and height of the popup based on the dimensions of the loading image?

  3. In the '/thumbs/75x60/' section, I aim to utilize the wildcard * to substitute '75x60' (like * x *) so that thumbnails of any size are affected. How can this be accomplished?

For reference, visit http://jsfiddle.net/JWcB7/6/

The structure of the HTML code is as follows:

<div id="profPhotos">
    <a class="profPhotoLink" href="...">
        <img width="95" height="130" src=".../thumbs/163x130/8f/fd/588x800_1319044306_9223981.jpg">
    </a>
    <br>
    <a class="profPhotoLink" href="...">
        <img width="75" height="60" src=".../thumbs/75x60/f0/d9/604x453_1319044306_9254715.jpg">
    </a>
    ... ...
</div>

The JavaScript snippet is outlined below:

$('#profPhotos .profPhotoLink > img').bind
(
    "mouseenter mouseleave", myImageHover
);

function myImageHover (zEvent)
{
    if (zEvent.type == 'mouseenter')
    {
        var imgurl = this.src.toString();
        //need to replace '/thumbs/75x60/' part with '/photos/' to get the full size image
        var bigimg = imgurl.replace("/thumbs/75x60/", "/photos/");  
        window.location.href = bigimg;
        popup = window.open(bigimg,"popwindow","menubar=0,resizable=0,status=0,titlebar=0,toolbar=0,scrollbars=0,location=0,width=600,height=800") //how to set the width and the height dynamically
    }
    else
    {
        popup.close();
    }
}

Answer №1

If you prefer not to load the image on the same page, avoid using this code:

window.location.href = bigimg;

Did you intend for the image to appear along with the popup?

~~~
When it comes to wildcard replacement, it's quite simple. Update:

var bigimg = imgurl.replace("/thumbs/75x60/", "/photos/");

To:

var bigimg = imgurl.replace(/\/thumbs\/[0-9x]+\//i, "/photos/");  


~~~
Resizing the popup can be tricky. Do you really require a popup on mouseover!? Would displaying a larger flyover image suffice?

I don't recommend using an actual popup (window.open()) to display large images due to security and cross-site restrictions. However, it can be achieved with Greasemonkey.

Instead, I suggest showing the image in a pseudo-popup dialog by inserting a <div> with position: absolute; and a high z-index.

The mouseenter event would change the src of the image inside the div.

Here's a complete Greasemonkey script that creates simple popup images on mouseover:

You can view the code in action at jsBin.

// ==UserScript==
// @name    _Popup Image Flyover, Mark I
// @include http://YOUR_SERVER/YOUR_PATH/*
// @require http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js
// ==/UserScript==

/*--- Create the div and the image that will point to our large pictures.
*/
$("body").append ('<div id="idLargePicturePopupWindow"><img></div>');

/*--- In case the popup covers the current mouse position, it must also trigger the hover change to prevent blinking scenarios.
*/
$('#idLargePicturePopupWindow').bind (
    "mouseenter mouseleave",
    {bInPopup: true},
    myImageHover
);

/*--- Activate the mouseover on the desired images on the target page.
*/
$('#profPhotos .profPhotoLink > img').bind (
    "mouseenter mouseleave",
    {bInPopup: false},
    myImageHover
);

function myImageHover (zEvent) {
    if (zEvent.type == 'mouseenter') {

        if ( ! zEvent.data.bInPopup) {

            var imgurl = this.src.toString();
            /*--- Replace the '/thumbs/75x60/' part with '/photos/' to get the full-size image.
            */
            var bigimg = imgurl.replace(/\/thumbs\/[0-9x]+\//i, "/photos/");

            $("#idLargePicturePopupWindow img").attr ('src', bigimg);
        }

        $("#idLargePicturePopupWindow").show ();
    }
    else {
        $("#idLargePicturePopupWindow").hide ();
    }
}


/*--- Add CSS styles to make this approach work.
*/
GM_addStyle ( (<><![CDATA[
    #idLargePicturePopupWindow {
        position:               absolute;
        background:             white;
        border:                 3px double blue;
        margin:                 1ex;
        opacity:                1.0;
        z-index:                1222;
        min-height:             100px;
        min-width:              200px;
        padding:                0;
        display:                none;
        top:                    10em;
        left:                   10em;
    }
    #idLargePicturePopupWindow img {
        margin:                 0;
        margin-bottom:          -4px;
        padding:                0;
    }
]]></>).toString () );

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Possible rewrite: "Unable to use jQuery to add elements to data fetched through AJAX requests."

I am looking to add a button to copy code inside every div that has a class starting with language. The code is functioning properly, however, after attempting to retrieve data from the database using Ajax, the button no longer appears in the div as it did ...

Algorithm using JavaScript to identify objects within an array

I am working with an array of objects that contain information about different projects. Each project has a unique ID and two arrays, one containing the IDs of projects that will happen before it, and another with the IDs of projects that will follow. Here ...

What is the best way to ensure that an ASync function only continues once all necessary information has been collected?

retrieveStudentGrades() { let grades = {}; let totalStudents = this.state.studentDetails.length; let studentCount = 0; this.state.courses.map((course) => { this.state.studentDetails.map((student) => { request.get( ...

Displaying separate items onto a webpage based on their unique identifiers

Currently, I am in the process of developing a JavaScript web application that retrieves input from a user (specifically the name of a music artist) and then produces a list of related artists along with their most popular songs, all thanks to information ...

Choose default checkboxes within a Vuetify list item group based on an array of objects

I'm having trouble preselecting checkboxes within a v-list-item-group. I can't seem to figure out what the true-value should be set to in order for the checkbox to be checked. I've also attempted changing the value of true-value to column.v ...

Transform audio data URI string into a downloadable file

The audio data is stored by the server as a base64 data string, which is then retrieved and played by the mobile web client. However, there seems to be a problem with playing the audio on mobile Chrome in iOS and Android when using a data uri (issue). I ...

I'm tired of dealing with text transformations, Javascript, and other shenanigans happening when I least expect it

Recently, I've been experimenting with button hover effects and some basic JavaScript. Unfortunately, I've encountered a few issues along the way. Below is the code snippet: document.querySelector('.btn').addEventListener("click", m ...

How can I extract the text from a textarea in react-bootstrap and pass it to a function when a button is clicked?

Below is the React-Bootstrap code that I am working with: <Form> <Form.Group className="mb-3" controlId="exampleForm.ControlTextarea1"> <Form.Label>Example textarea</Form.Label> <Form.Control as=&quo ...

creating a custom type with enums in Angular can lead to implicit 'any' issues

Why does the key of [type] require a type? It may sound strange, but I am facing an issue. Here is some example data: export enum ENUM_Bike { suzuki = 'suzuki', yamaha = 'yamaha', kawasaki = 'kawasaki' } export type T ...

The indicated processing instruction is incompatible with the provided payment source. PayPal's hosted fields for credit card payments do not support this specific processor

I'm currently working on integrating credit card payments with hosted fields into my checkout process. However, I keep encountering an UNPROCESSABLE_ENTITY error when making the confirm-payment-source request through the PayPal JS SDK. Here is the co ...

When one option is chosen, it automatically disables the other selected option across all selections

I am attempting to disable other options if one option is selected. I have tried a few methods, but none seem to be working for me. Below are my HTML select options: <select class="input_slip_no form-control" name="slip_no[]" id="ID_2_slip_no" required ...

Sharing CSS styles among multiple single-page applications (SPAs) developed using the React

I am currently working on multiple micro SPAs that exist independently within an Express environment. I am facing a challenge with importing a global CSS file that is located outside of the apps, as it is not being recognized. The use of @import url(asset ...

Display HTML content using JavaScript only when a checkbox is selected

Currently, I am updating an HTML form to show additional subsets of questions based on the selection of a "parent" checkbox. The current implementation works well, but I am wondering if there is a more efficient way to achieve this without having to rewrit ...

Obtaining the scene's coordinates in Three.js

Struggling with a coding issue, I've scanned various discussions that don't quite address my specific problem. Any assistance would be greatly appreciated. In my HTML document, I am using the three.js library to create a scene titled scaledScene ...

Arrange the array depending on the existence of properties in the objects

Is there a way to efficiently organize an array like the following in cases where certain fields are missing? For instance, consider the current array: const users = [ { id: 1, firstname: 'Jerry' }, { id: 2, firstname: & ...

Unable to call Success function in JQuery AJAX request

Here is a simple JQuery ajax request I am working on: $.ajax("../ajax/data/items.json", { success: setContent, type: "GET", dataType: "json" }); function setContent(data, status, jqxhr) { alert("Hello!"); } The json file loads successfully with a 200 r ...

Force a single thread in node.js to execute code exclusively

Upon starting my application with node app.js, initially only 1 thread is running in the process. However, as time progresses, more threads are created for the process. The issue arises when trying to execute specific code like: var io = require('soc ...

The backdrop transforms with every new page load

For testing purposes, I have currently added only one background image. However, my goal is to change the background image on each reload. To achieve this, I need to create an array containing the paths of all the images to be used and have the backgroun ...

increasing the `WeakSet` size while simultaneously causing a memory overload

There's something strange I observed. Despite using a WeakSet which should not retain any references, the code below still manages to exhaust memory: 'use strict'; require('babel-polyfill'); const s = new WeakSet(); for (let i = ...

Is it necessary to publish a package for client-side usage on npm?

I'm struggling to understand the recent trend of using npm to publish client-side packages that have no dependencies. Take for example a simple class that extends HTMLElement and can only be used in the browser by adding a script tag to an HTML file. ...