在body中定义不同的window.open目标URL

问题描述 投票:1回答:1

我在外部js文件中使用没有jQuery的JavaScriptlightbox,我想在那里配置一个按钮链接到几个不同的URL(点击按钮1将打开链接1,点击按钮2将打开链接2)。

我按下按钮,使用window.open('link1.html', '_blank')打开一个新窗口。但是我无法弄清楚如何定义几个不同的目标URL,最好是在我的代码体中。

有可能以某种方式配置它,window.open函数会在正文中获取不同的目标URL吗?

正是这个灯箱:https://jiri.hybek.cz/wa-mediabox/完全在外部js文件上运行,只有图像在主体中定义如下:

<a href="image.jpg" data-mediabox="my-gallery-name" data-title="Sample image">
<img src="image-thumb.jpg" alt="Image" />

我想更改js文件中的打开按钮功能以打开一个url,它在body中定义(如图像)。我需要的只是正确的命令,它将导致window.open函数在正文中获取其不同的目标URL,某些地方也定义了图像。

按钮功能定义如下(我用???替换了目标,因为这基本上就是我所要求的):

this.openBtn.addEventListener("click",function(t){t.stopPropagation(),i.open('') win = window.open(???,'_blank');win.focus();})

身体保持图像洗牌,图像在灯箱中打开。该按钮在lighbox中打开,应从那里引用到目标URL。

<div class="grid"><div class="grid-item"><a href="img/image1.jpg" data-mediabox="my-gallery-name" data-title="text" ???="link1.html"><img src="img/image1.jpg" alt="Image"/></a></div><div class="grid-item"><a href="img/image2.png" data-mediabox="my-gallery-name" data-title="text" ???="link2.html"><img src="img/image2.png" /></a>

我的问题是:如何让window.open函数从正文中获取不同的目标URL?

非常感谢您的帮助!

javascript lightbox
1个回答
0
投票

我有两个解决方案,一个是hacky,但它是单行更改,另一个是更优雅,但需要更多修改。请注意,我正在对原始JavaScript源文件进行更改(非缩小)。

对于这两种解决方案,HTML都是一样的;您将data-custom-url属性添加到<a>标记,并将值设置为您要为该图像打开的任何页面:

<a href="http://lorempixel.com/800/400/" data-custom-url="http://google.com/search?q=custom+link" data-mediabox="my-gallery-name" data-title="Sample image">
    <img src="http://lorempixel.com/400/200/" alt="Image" />
</a>

Single line version

window.open函数中的WAMediaBox_Gallery.prototype.openSource行更改为:

window.open( document.querySelector(`a[href='${this.mediaList[this.current].src}']`).getAttribute("data-custom-url") || this.mediaList[this.current].src );

这将从HTML中获取data-custom-url属性的值并将其打开,如果不存在则回退到默认值。这个“hacky”部分是它需要查找原始的<a>标记来获取属性值。如果您有多个指向同一图像的链接,也可能会出现问题。

Full version

此版本将自定义URL添加到脚本内部创建的媒体对象,以便在单击链接时不必搜索DOM。您可以查看文件here的所有更改。

/*
 * WA MediaBox
 *
 * @author WA Studio <www.webarts.name>
 * @author Jiri Hybek <[email protected]>
 * @license MIT
 */

(function(){

    /*
     * Preloader constructor
     */
    var Preloader = function(){

        this.el = document.createElement("div");
        this.el.classList.add("wa-mediabox-preloader");

        this.wrap = document.createElement("div");
        this.wrap.classList.add("wa-mediabox-preloader-wrap");

        this.spinner = document.createElement("div");
        this.spinner.classList.add("wa-mediabox-preloader-spinner");

        this.patch = document.createElement("div");
        this.patch.classList.add("wa-mediabox-preloader-patch");

        this.clipperLeft = document.createElement("div");
        this.clipperLeft.classList.add("wa-mediabox-preloader-clipper");
        this.clipperLeft.classList.add("left");

        this.clipperRight = document.createElement("div");
        this.clipperRight.classList.add("wa-mediabox-preloader-clipper");
        this.clipperRight.classList.add("right");

        var circle = document.createElement("div");
        circle.classList.add("wa-mediabox-preloader-circle");

        this.patch.appendChild(circle);
        this.clipperLeft.appendChild(circle.cloneNode(true));
        this.clipperRight.appendChild(circle.cloneNode(true));

        this.spinner.appendChild(this.clipperLeft);
        this.spinner.appendChild(this.patch);
        this.spinner.appendChild(this.clipperRight);

        this.wrap.appendChild(this.spinner);
        this.el.appendChild(this.wrap);

    };

    Preloader.prototype.show = function(){

        this.el.classList.remove("hidden");
        this.el.style.display = '';

    };

    Preloader.prototype.hide = function(){

        var self = this;

        this.el.classList.add("hidden");

        setTimeout(function(){

            if(self.el.classList.contains("hidden"))
                self.el.style.display = 'none';

        }, 350);

    };

    /* 
     * Gallery constructor
     */
    var WAMediaBox_Gallery = function(parent){

        this.parent = parent;
        this.mediaList = [];

        this.opened = false;

        this.loaded = false;
        this.current = null;

        this.containerWidth = null;
        this.containerHeight = null;

    };

    /*
     * Media adders
     */
    WAMediaBox_Gallery.prototype.addImage = function(src, title, customUrl){

        this.mediaList.push({
            type: "image",
            src: src,
            title: title,
            customUrl: customUrl
        });

        return this.mediaList.length - 1;

    };

    WAMediaBox_Gallery.prototype.addIframe = function(src, title, customUrl, width, height){

        this.mediaList.push({
            type: "iframe",
            src: src,
            title: title,
            customUrl: customUrl,
            width: width,
            height: height
        });

        return this.mediaList.length - 1;

    };

    /*
     * Open gallery
     */
    WAMediaBox_Gallery.prototype.open = function(index){

        if(this.opened) return;

        var self = this;

        this.current = -1;
        this.loaded = false;

        //Create overlay and content wrapper
        this.overlay = document.createElement("div");
        this.overlay.classList.add("wa-mediabox-overlay");

        this.frame = document.createElement("div");
        this.frame.classList.add("wa-mediabox-frame");

        this.container = document.createElement("div");
        this.container.classList.add("wa-mediabox-container");

        this.title = document.createElement("div");
        this.title.classList.add("wa-mediabox-title");

        this.loading = new Preloader();

        //Buttons
        this.closeBtn = document.createElement("button");
        this.closeBtn.classList.add("wa-mediabox-close");
        this.closeBtn.innerHTML = '<svg viewBox="0 0 24 24"><path d="M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z" /></svg>';
        this.closeBtn.setAttribute("title", this.parent.lang.close);

        this.prevBtn = document.createElement("button");
        this.prevBtn.classList.add("wa-mediabox-prev");
        this.prevBtn.innerHTML = '<svg viewBox="0 0 24 24"><path d="M15.41,16.58L10.83,12L15.41,7.41L14,6L8,12L14,18L15.41,16.58Z" /></svg>';
        this.prevBtn.setAttribute("title", this.parent.lang.prev);

        this.nextBtn = document.createElement("button");
        this.nextBtn.classList.add("wa-mediabox-next");
        this.nextBtn.innerHTML = '<svg viewBox="0 0 24 24"><path d="M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z" /></svg>';
        this.nextBtn.setAttribute("title", this.parent.lang.next);

        this.openBtn = document.createElement("button");
        this.openBtn.classList.add("wa-mediabox-open");
        this.openBtn.innerHTML = '<svg viewBox="0 0 24 24"><path d="M14,3V5H17.59L7.76,14.83L9.17,16.24L19,6.41V10H21V3M19,19H5V5H12V3H5C3.89,3 3,3.9 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V12H19V19Z" /></svg>';
        this.openBtn.setAttribute("title", this.parent.lang.openInNew);

        //Put together
        this.frame.appendChild(this.container);
        this.frame.appendChild(this.title);
        this.frame.appendChild(this.loading.el);
        this.frame.appendChild(this.closeBtn);
        this.frame.appendChild(this.prevBtn);
        this.frame.appendChild(this.nextBtn);
        this.frame.appendChild(this.openBtn);

        this.overlay.appendChild(this.frame);
        document.body.appendChild(this.overlay);

        //Bind events
        this.overlay.addEventListener("click", function(ev){

            ev.stopPropagation();
            self.close();

        });

        this.closeBtn.addEventListener("click", function(ev){

            ev.stopPropagation();
            self.close();

        });

        this.prevBtn.addEventListener("click", function(ev){

            ev.stopPropagation();
            self.prev();

        });

        this.nextBtn.addEventListener("click", function(ev){

            ev.stopPropagation();
            self.next();

        });

        this.container.addEventListener("click", function(ev){

            ev.stopPropagation();
            self.next();

        });

        this.openBtn.addEventListener("click", function(ev){

            ev.stopPropagation();
            self.openSource();

        });

        //Resize
        this.resizeHandler = function(){

            self.resizeContainer();

        };

        this.keyDownHandler = function(ev){

            ev.preventDefault();
            ev.stopPropagation();

            if(ev.keyCode === 37)
                self.prev();
            else if(ev.keyCode === 39)
                self.next();
            else if(ev.keyCode === 27)
                self.close();

            return false;

        };

        window.addEventListener("resize", this.resizeHandler);
        document.body.addEventListener("keydown", this.keyDownHandler);

        //Open
        setTimeout(function(){

            self.overlay.classList.add("opened");

            self.loadMedia(index);

        }, 10);

        //Set opened
        this.opened = true;

    };

    /*
     * Close gallery
     */
    WAMediaBox_Gallery.prototype.close = function(){

        if(!this.opened) return;

        var self = this;

        this.overlay.classList.remove("opened");

        window.removeEventListener("resize", this.resizeHandler);
        document.body.removeEventListener("keydown", this.keyDownHandler);

        setTimeout(function(){

            self.overlay.parentElement.removeChild(self.overlay);
            self.opened = false;

            self.nextBtn = null;
            self.prevBtn = null;
            self.closeBtn = null;
            self.openBtn = null;
            self.loading = null;
            self.container = null;
            self.frame = null;
            self.overlay = null;

            self.current = null;
            self.containerWidth = null;
            self.containerHeight = null;

        }, 450);

    };

    /*
     * Resize container
     */
    WAMediaBox_Gallery.prototype.resizeContainer = function(){

        if(!this.opened) return;

        //Defaults
        if(!this.containerWidth)
            this.containerWidth = Math.round(this.overlay.offsetWidth * 0.7);

        if(!this.containerHeight)
            this.containerHeight = Math.round(this.overlay.offsetWidth * 0.7);

        var widthLimit = 160;

        if(this.overlay.offsetWidth < 480)
            widthLimit = 70;

        var maxWidth = Math.min(this.overlay.offsetWidth * 0.9, this.overlay.offsetWidth - widthLimit);
        var maxHeight = Math.min(this.overlay.offsetHeight * 0.9, this.overlay.offsetHeight - 64);

        var targetWidth = this.containerWidth;
        var targetHeight = this.containerHeight;

        //Resize if neccesary
        var ratio = targetWidth / targetHeight;

        if(targetWidth > maxWidth){
            targetWidth = Math.round(maxWidth);
            targetHeight = targetWidth / ratio;
        }

        if(targetHeight > maxHeight){
            targetHeight = Math.round(maxHeight);
            targetWidth = targetHeight * ratio;
        }

        //Set styles
        this.frame.style.width = targetWidth + "px";
        this.frame.style.height = targetHeight + "px";

        this.frame.style.marginLeft = -Math.round(targetWidth / 2) + "px";
        this.frame.style.marginTop = -Math.round(targetHeight / 2) + "px";

    };

    /*
     * Set media into container
     */
    WAMediaBox_Gallery.prototype.setMedia = function(type, src, title, width, height){

        if(!this.opened) return;

        var self = this;
        this.loaded = false;

        this.frame.classList.remove("can-open-in-new");
        self.frame.classList.remove("has-title");

        //Reset content
        this.container.innerHTML = '';

        //Create proper element
        var mediaEl = null;

        if(type == "image"){

            //Resize
            if(width) this.containerWidth = width;
            if(height) this.containerHeight = height;
            this.resizeContainer();

            mediaEl = document.createElement("img");

            mediaEl.addEventListener("load", function(){

                self.containerWidth = mediaEl.width;
                self.containerHeight = mediaEl.height;

                self.resizeContainer();
                self.frame.classList.add("can-open-in-new");

                //Add to DOM
                self.container.appendChild(mediaEl);

            });

            mediaEl.src = src;

        } else {

            //Resize
            if(width) this.containerWidth = width;
            if(height) this.containerHeight = height + ( title ? 52 : 0 );
            this.resizeContainer();

            mediaEl = document.createElement("iframe");
            mediaEl.src = src;
            mediaEl.setAttribute("width", parseInt(this.frame.style.width));
            mediaEl.setAttribute("height", parseInt(this.frame.style.height) - ( title ? 52 : 0 ));
            mediaEl.setAttribute("frameborder", "0");
            mediaEl.setAttribute("allowfullscreen", "allowfullscreen");

            //Add to DOM
            this.container.appendChild(mediaEl);

        }

        //Wait for load
        mediaEl.addEventListener("load", function(){

            setTimeout(function(){

                //Set title
                if(title){
                    self.title.innerHTML = title;
                    self.frame.classList.add("has-title");
                }

                //Show
                self.frame.classList.add("loaded");
                self.loading.hide();
                self.loaded = true;

            }, 550);

        });

    };

    /*
     * Load media at index
     */
    WAMediaBox_Gallery.prototype.loadMedia = function(index){

        if(!this.opened) return;
        if(index == this.current) return;

        var self = this;

        if(!this.mediaList[index]) throw new Error("Undefined media");

        var load = function(){

            self.setMedia( self.mediaList[index].type, self.mediaList[index].src, self.mediaList[index].title, self.mediaList[index].width, self.mediaList[index].height );

        };

        if(this.loaded){

            this.frame.classList.remove("loaded");
            this.loading.show();
            setTimeout(load, 350);

        } else {

            load();

        }

        if(index > 0)
            this.frame.classList.add("has-prev");
        else
            this.frame.classList.remove("has-prev");

        if(index < this.mediaList.length - 1)
            this.frame.classList.add("has-next");
        else
            this.frame.classList.remove("has-next");

        this.current = index;

    };

    /*
     * Switch to previous media
     */
    WAMediaBox_Gallery.prototype.prev = function(){

        if(!this.opened) return;

        var index = Math.max(0, this.current - 1);
        this.loadMedia(index);

    };

    /*
     * Switch to next media
     */
    WAMediaBox_Gallery.prototype.next = function(){

        if(!this.opened) return;

        var index = Math.min(this.mediaList.length - 1, this.current + 1);
        this.loadMedia(index);

    };

    WAMediaBox_Gallery.prototype.openSource = function(){

        if(!this.opened) return;

        window.open( this.mediaList[this.current].customUrl || this.mediaList[this.current].src );

    };

    /*
     * ImageBox constructor
     */
    var WAMediaBox = function(){

        this.lang = {
            prev: "Previous",
            next: "Next",
            close: "Close",
            openInNew: "Open in new window"
        };

        this.galleries = {};

    };

    WAMediaBox.prototype.openGallery = function(gallery, index){

        if(!this.galleries[gallery]) throw new Error("Gallery not found");

        this.galleries[gallery].open(index);

    };

    /*
     * Media adders
     */
    WAMediaBox.prototype.addImage = function(gallery, src, title, customUrl){

        if(!this.galleries[gallery])
            this.galleries[gallery] = new WAMediaBox_Gallery(this);

        return this.galleries[gallery].addImage(src, title, customUrl);

    };

    WAMediaBox.prototype.addIframe = function(gallery, src, title, customUrl, width, height){

        if(!this.galleries[gallery])
            this.galleries[gallery] = new WAMediaBox_Gallery(this);

        return this.galleries[gallery].addIframe(src, title, customUrl, width, height);

    };

    /*
     * Bind single elements
     */
    WAMediaBox.prototype.bind = function(el){

        if(el._waMediaBoxBound) return;

        el._waMediaBoxBound = true;

        var self = this;

        var gallery = el.getAttribute("data-mediabox") || "_";
        var src = String(el.getAttribute("href") || el.getAttribute("data-src"));
        var title = el.getAttribute("data-title");
        var isIframe = ( el.hasAttribute("data-iframe") || src.indexOf("youtube") >= 0 ? true : false );
        var width = ( el.hasAttribute("data-width") ? parseInt(el.getAttribute("data-width")) : null );
        var height = ( el.hasAttribute("data-height") ? parseInt(el.getAttribute("data-height")) : null );
        var customUrl = el.getAttribute("data-custom-url");

        var index = null;

        //Add to gallery
        if(isIframe)
            index = this.addIframe(gallery, src, title, customUrl, width, height);
        else
            index = this.addImage(gallery, src, title, customUrl);

        //Bind open event
        el.addEventListener("click", function(ev){

            ev.preventDefault();
            ev.stopPropagation();

            self.openGallery(gallery, index);

            return false;

        });

    };

    /*
     * Bind all elements in given parent node
     */
    WAMediaBox.prototype.bindAll = function(parentEl){

        var elements = parentEl.querySelectorAll("a[data-mediabox]");

        for(var i = 0; i < elements.length; i++)
            this.bind(elements.item(i));

    };

    //Assign to window
    window.WAMediaBox = new WAMediaBox();

    //Bind lightbox elements
    window.addEventListener("load", function(){

        window.WAMediaBox.bindAll(document.body);

    });

})();
© www.soinside.com 2019 - 2024. All rights reserved.