1

I'd like to use https://github.com/lonekorean/mini-preview to create mouseover previews for parts of a website only.

I have no problems using anchors from the target website to have the script render a full website preview, scrolled to where an individual anchor is. That's not what I'm after however.

I'd like the script to show only the content of the anchors' parent <p> or <div>.

On the site, the link target anchors are coded like this:

<div class="paragraph">
    <p>
        <a id="anchor_1"></a>
        Foo bar baz.
    </p>
</div>

So, I'd like the little preview box to show Foo bar baz. only.

I suspect the answer lies in this part of the script:

loadPreview: function() {
    this.$el.find('.' + PREFIX + '-frame')
        .attr('src', this.$el.attr('href'))
        .on('load', function() {
            // some sites don't set their background color
            $(this).css('background-color', '#fff');
});

specifically, the .attr('src', this.$el.attr('href')) part. I'm not sure though.

Does anyone know how I can do this?
Or can you recommend some other script that I can use to do this and makes things look as nice as this one?

I'm not a web dev, so please go easy on me.
Thanks

UPDATE (based on Swati's answer and corresponding comments):

For example, if my website includes this:

<body>
    <p>
        <a href="#anchor_on_my_site">See internal</a>
    </p>
    <p>
        <a href="external_website.html#external_anchor">See external</a>
    </p>
    <div class="paragraph">
        <p>
            <a id="anchor_on_my_site"></a>
                Foo bar baz.
        </p>
    </div>
</body>

and the external website includes this:

<body>
    <div class="paragraph">
        <p>
            <a id="external_anchor"></a>
                Qux quux quuz.
        </p>
    </div>
</body>

I'd like See internal to display Foo bar baz. and See external to display Qux quux quuz.

Jure T
  • 199
  • 1
  • 8

1 Answers1

1

Inside loadPreview function you can use closest('p').clone().children().remove().end().text() to get text from p tag where a has been hover then using this put that text to show inside your frame div i.e : .find('.' + PREFIX + '-frame').text(data_to_show) .

Demo Code :

(function($) {
  var PREFIX = 'mini-preview';

  $.fn.miniPreview = function(options) {
    return this.each(function() {
      var $this = $(this);
      var miniPreview = $this.data(PREFIX);
      if (miniPreview) {
        miniPreview.destroy();
      }

      miniPreview = new MiniPreview($this, options);
      miniPreview.generate();
      $this.data(PREFIX, miniPreview);
    });
  };

  var MiniPreview = function($el, options) {
    this.$el = $el;
    this.$el.addClass(PREFIX + '-anchor');
    this.options = $.extend({}, this.defaultOptions, options);
    this.counter = MiniPreview.prototype.sharedCounter++;
  };

  MiniPreview.prototype = {
    sharedCounter: 0,

    defaultOptions: {
      width: 256,
      height: 144,
      scale: .25,
      prefetch: 'parenthover'
    },

    generate: function() {
      this.createElements();
      this.setPrefetch();
    },

    createElements: function() {
      var $wrapper = $('<div>', {
        class: PREFIX + '-wrapper'
      });
      //no need to use iframe...use simple div 
      var $frame = $('<div>', {
        class: PREFIX + '-frame'
      });
      var $cover = $('<div>', {
        class: PREFIX + '-cover'
      });
      $wrapper.appendTo(this.$el).append($frame, $cover);

      // sizing
      $wrapper.css({
        width: this.options.width + 'px',
        height: this.options.height + 'px'
      });

      // scaling
      var inversePercent = 100 / this.options.scale;
      $frame.css({
        width: inversePercent + '%',
        height: inversePercent + '%',
        transform: 'scale(' + this.options.scale + ')'
      });
      var fontSize = parseInt(this.$el.css('font-size').replace('px', ''), 10)
      var top = (this.$el.height() + fontSize) / 2;
      var left = (this.$el.width() - $wrapper.outerWidth()) / 2;
      //add more style here ...if needed to outer div
      $wrapper.css({
        top: top + 'px',
        left: left + 'px',
        'font-size': '55px',
        'color': 'blue'
      });
    },

    setPrefetch: function() {
      switch (this.options.prefetch) {
        case 'pageload':
          this.loadPreview();
          break;
        case 'parenthover':
          this.$el.parent().one(this.getNamespacedEvent('mouseenter'),
            this.loadPreview.bind(this));
          break;
        case 'none':
          this.$el.one(this.getNamespacedEvent('mouseenter'),
            this.loadPreview.bind(this));
          break;
        default:
          throw 'Prefetch setting not recognized: ' + this.options.prefetch;
          break;
      }
    },

    loadPreview: function() {
      //to get text from p tag
      var data_to_show = this.$el.closest('p').clone().children().remove().end().text().trim()
      //set new text inside div frame
      this.$el.find('.' + PREFIX + '-frame').text(data_to_show)
      //set bg color..
      this.$el.find('.' + PREFIX + '-frame').css('background-color', '#fff');


    },

    getNamespacedEvent: function(event) {
      return event + '.' + PREFIX + '_' + this.counter;
    },

    destroy: function() {
      this.$el.removeClass(PREFIX + '-anchor');
      this.$el.parent().off(this.getNamespacedEvent('mouseenter'));
      this.$el.off(this.getNamespacedEvent('mouseenter'));
      this.$el.find('.' + PREFIX + '-wrapper').remove();

    }
  };
})(jQuery);


$('a').miniPreview();
body {
  height: 100%;
  margin: 0;
  padding: 0 10% 40px;
  font-size: 2rem;
  line-height: 1.5;
  font-family: 'Roboto Slab', sans-serif;
  text-align: justify;
  color: #59513f;
  background-color: #f5ead4;
}

a {
  color: #537f7c;
}

.mini-preview-anchor {
  display: inline-block;
  position: relative;
  white-space: nowrap;
}

.mini-preview-wrapper {
  -moz-box-sizing: content-box;
  box-sizing: content-box;
  position: absolute;
  overflow: hidden;
  z-index: -1;
  opacity: 0;
  margin-top: -4px;
  border: solid 1px #000;
  box-shadow: 4px 4px 6px rgba(0, 0, 0, .3);
  transition: z-index steps(1) .3s, opacity .3s, margin-top .3s;
}

.mini-preview-anchor:hover .mini-preview-wrapper {
  z-index: 2;
  opacity: 1;
  margin-top: 6px;
  transition: opacity .3s, margin-top .3s;
}

.mini-preview-cover {
  background-color: rgba(0, 0, 0, 0);
  /* IE fix */
}

.mini-preview-frame {
  border: none;
  -webkit-transform-origin: 0 0;
  transform-origin: 0 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>

<body>
  <div class="paragraph">
    <p>
      <a id="anchor_1">See</a> This is text we are showing for first
    </p>
    <p>
      <a id="anchor_2">See</a> This is text we are showing for second
    </p>
  </div>
</body>

</html>

Update 1 :

You can differentiate between external & internal link using some class i.e : simply check if the a tag which is hover has a particular class or not depending on this change your code to preview divs.

Updated Code :

if (this.$el.hasClass("internal")) {
        //to get text from p tag
        var data_to_show = this.$el.closest('p').siblings(".paragraph").clone().text().trim()
        //set new text inside div frame
        this.$el.find('.' + PREFIX + '-frame').text(data_to_show)
        //set bg color..
        this.$el.find('.' + PREFIX + '-frame').css('background-color', '#fff');
} else {       
        console.log("for external code ..")    
}
Swati
  • 28,069
  • 4
  • 21
  • 41
  • Dear Swati! Thank you very much! It works perfectly, but I haven't been clear enough I assume. What I need is the text from the link's target, not from where the link resides. Please do tell me if I'm still not making this clear enough. Thanks. – Jure T Mar 19 '21 at 11:47
  • so which element user should hover to see text ? please can you elaborate more ? – Swati Mar 19 '21 at 12:26
  • Dear Swati! Thank you for responding. I'll update my question with a more elaborate demonstration of what I'm trying to accomplish. – Jure T Mar 19 '21 at 12:53
  • so here `external_website` should load content from url which is specify ? Let me think on this its little bit tricky here :P . – Swati Mar 19 '21 at 13:13
  • Dear Swati! Thanks a lot. You're the best. Upon mouseover of a hyperlink, the script (and most other preview scripts that I found) already shows the target website that a link points to. However, it shows a "mini browser window" of the target url. And if a link points to an anchor on the target website, it shows the part of the target website where the anchor is, again rendered as a "mini browser window". What I have trouble with is getting only the contents of the

    or

    that the anchor is part of displayed in the popup rectangle, as opposed to a fully rendered "mini website".
    – Jure T Mar 19 '21 at 15:22
  • you can check if the link over is external or internal depeding on this you can write different code for loadPreview function . – Swati Mar 20 '21 at 04:07
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/230152/discussion-between-swati-and-jure-t). – Swati Mar 20 '21 at 04:07
  • 1
    Thank you again Swati! You really went the extra length to help. Amazing! – Jure T Mar 21 '21 at 14:10