Materialize - Implement "materialboxed" class in a link

5

Greetings ...

The " Material box " class of the FW Materialize allows the user to click on an image to center and enlarge it. To exit the effect, the user can click on the image again, scroll outwards, or press the ESC key.

I intend to associate this behavior with a link to enlarge a hidden image.

Image hidden with the materialboxed class:

<img id="img1" class="hide materialboxed" src="images/img1.jpg">

Link:

<a href="#!" id="linkImg1" onclick="document.getElementById('img1').classList.remove('hide'); document.getElementById('img1').click();">Imagen 1</a>

It works well. But when returning to the initial state, by clicking or with ESC, the image must be hidden again by adding the class "hide" or "display: hidden". For example:

document.getElementById('img1').classList.add('hide');

Returning to the initial state of the image is a different event than clicking on the link. It happens on the enlarged image. It should be done when the returnToOriginal () function occurs within the materialbox property of the fn object created in the materialize.js file.

Any clues?

I can not " listen " throughout the document because there are "materialboxed" images that should not be hidden. How can I listen "what happens returnToOriginal () specifically on the image that should be hidden again.

    
asked by Juan Varela 25.02.2017 в 17:17
source

2 answers

0

The behavior you are raising is too dependent on the implementation of Materialize . And it seems that they did not develop taking into account that scenario ( Add an action to the closing event or provide the possibility of passing a callback to a closing event ).

It is true that the returnToOriginal function could be used, but there is no decent way to get access to it, let alone modify it.

The simplest way to achieve what you're looking for, feels a bit Hacky , but it can be simulated by passing a width with a very small value ( But not too much ). For example:

HTML:

<img id="img1" class="materialboxed" src="images/img1.jpg" width="0.2">
<a href="#!" id="linkImg1" onclick="document.getElementById('img1').click();">Imagen 1</a>

In this way the element can not be seen on the screen, the link works to awaken the effect, and Materialize continues to manage its closure.

Another way to achieve the same thing, feels much more Hacky and is much more complex. But it would be using javascript mainly. Something quick could be:

First, keep a reference to the currently open image ( When I click on a link ). Saved in OpenActually in this example. Second, by having reference to the active image, I can know which one to close / hide. I do not overwrite the Materialize action, but let the animation complete ( At 200ms currently ), hide the element and destroy the reference since the image would not be currently active.

let elementoAbiertoActualmente;

function abrirElemento(selector) {
  elementoAbiertoActualmente = document.getElementById(selector);
  elementoAbiertoActualmente.classList.remove('hide');
  elementoAbiertoActualmente.click();
}

function cerrarElemento() {
  if (elementoAbiertoActualmente) {
    let aCerrar = elementoAbiertoActualmente;
    setTimeout(function() {
      aCerrar.classList.add('hide');
    }, 200);
    elementoAbiertoActualmente = null;
  }
}

Having the basic logic, we must prepare the HTML elements for this solution:

<img id="img1" class="hide materialboxed" src="images/img1.jpg" width="1">
<a href="#!" id="linkImg1" onclick="abrirElemento('img1');">Imagen 1</a>

And finally, handle the same events that you described for the closing; click, scroll and escape key. Something minimally functional:

$(document).keyup(function(e) {
  if (e.keyCode === 27) {
    cerrarElemento();
  }
});
$(window).scroll(function() {
  if (ultimoElemento) {
    cerrarElemento();
  }
});
$(document).click(function(e) {
  if (ultimoElemento && e.target.tagName == "DIV") {
    cerrarElemento();
  }
});

With this you can already perform the same behavior. In this situation, the smaller the width that the img element has, the more pleasing it will be to the view.

But, another way to achieve the same, is the most obvious; abandon Materialize for this particular case, and manually implement that effect by css and js, already having full control of it.

    
answered by 26.04.2017 / 16:35
source
0

Hello good afternoon what? Well I think I understand it more or less, so I'll try to guide you since I do not have the application you're using for something live.

I see that you have removed the class 'hide', why do not you change the online style of the image that you are going to take instead of deleting your class? So you could close the image, return that CSS style that we changed. Example:

<a href="#!" id="linkImg1" onclick="document.getElementById('img1').style.display = 'inline'; document.getElementById('img1').click();">Imagen 1</a>

And when closing it would have to add to the function, that of its previous style.

document.getElementById('img1').style.display = 'none';

With this (as long as the 'hide' class is a mere concealment) you do not need to delete your class to appear. It may not be 'display', you'll have to check if it's opacity, or others.

I edit from here, I hope it helps you so you can try based on your web page. Greetings

I have created a new style, just to keep it hidden and not depend on the original, which only does that.

.hide-new {            
    display: none;
}

HTML, the image inside a DIV with that new class.

<div id="div1" class="hide-new">
    <img id="img1" class="materialboxed" width="250" src="http://th01.deviantart.net/fs70/PRE/i/2013/126/1/e/nature_portrait_by_pw_fotografie-d63tx0n.jpg">
</div> 

And finally the code.

$(document).ready(function () {
        var imgContainer = $('.material-placeholder');
        var imagen = $('#img1');
        var link = document.getElementById('linkImg1');

        //Función de retorno que oculta la imagen animando una opacidad y removiendo el id asignado en la otra función.
        var quitaClase = function () {
            imagen.animate({ opacity: 0 }, {duration: 0});             
            setTimeout(function () {
                $('#div1').addClass('hide-new');
            }, 250);
            imgContainer.removeAttr('id');
            quitaClase = null;
        }

        //Función que elimina la clase, activa el evento click y da un atributo nuevo al div para poder cerrarla.
        var cambioClase = function () {
            $('#div1').removeClass('hide-new');
            document.getElementById('img1').click();
            imgContainer.attr('id', 'new-click');                
            document.getElementById('new-click').addEventListener('click', quitaClase, false);
        }
        //Si quieres que también se active en la imagen, hay que agregarla

        link.addEventListener('click', cambioClase, false);

        //Cierre de la imagen con la tecla ESC
        $(document).keyup(function (e) {
            if (e.keyCode === 27 && imagen.hasClass('active')) {
                quitaClase();
            }
        });
    });

As you will observe, it is 'too much' and difficult to control when you have the option to add something to the original. I hope that at least something will guide you. Greetings!.

    
answered by 25.02.2017 в 19:52