Is there an easy way to determine if an element inside a Vue component is overflowing?

I created a unique component called ResultPill which includes a tooltip feature (implemented using vuikit). The text displayed in the tooltip is determined by a getter function called tooltip, utilizing vue-property-decorator. Here are the relevant parts of the code:

<template>
    <div class="pill"
         v-vk-tooltip="{ title: tooltip, duration: 0, cls: 'some-custom-class uk-active' }"
         ref="container"
    >
        ..content here..
    </div>
</template>
<script lang="ts"&g  t;
    @Component({ props: ... })
    export default class ResultPill extends Vue {
    ...
        get tooltip (): string { ..calculating tooltip.. }
        isContainerSqueezed (): boolean {
            const container = this.$refs.container as HTMLElement | undefined;
            if(!container) return false;
            return container.scrollWidth != container.clientWidth;
        }
    ...
</script>
<style lang="stylus" scoped>
    .pill
        white-space pre
        overflow hidden
        text-overflow ellipsis
    ...
</style>

I am currently working on adding additional content to the tooltip when the component's width exceeds that of its container, triggering overflow styles. I tried checking this with $0.scrollWidth == $0.clientWidth in the console (where $0 represents the selected element), but encountered issues with this.$refs.container being undefined for many component instances. Do I need to assign unique references per component instance? Are there any other problems with my current approach? How can I determine if the element is overflowing?

In an attempt to address the potential issue of non-unique refs, I added a random id property to the class:

        containerId = 'ref' + Math.random();

and used it like so:

         :ref="containerId"
    >
    ....
            const container = this.$refs[this.containerId] as HTMLElement | undefined;

However, this did not resolve the tooltip alteration problem.

Additionally, I explored using the $el property instead of refs, but encountered similar challenges. It appears that the root cause may be related to this:

An important note about the ref registration timing: because the refs themselves are created as a result of the render function, you cannot access them on the initial render - they don’t exist yet! $refs is also non-reactive, therefore you should not attempt to use it in templates for data-binding.

(presumably the same is applicable to $el) Therefore, I must find a way to recalculate the tooltip upon mounting. I came across this question, but the provided solution does not suit my scenario.

Answer №1

As previously mentioned in one of the revisions, it is advised in the documentation not to utilize $refs for the initial rendering phase due to their undefined state at that time. Therefore, I have modified tooltip to be a property rather than a getter and perform its calculation within the mounted lifecycle hook:

export default class ResultPill extends Vue {
...
    tooltip = '';
    calcTooltip () {
        // The specific logic here is irrelevant; what matters is that this.isContainerSqueezed()
        // works accurately at this stage
        this.tooltip = !this.isContainerSqueezed() ? this.mainTooltip :
            this.label + (this.mainTooltip ? '\n\n' + this.mainTooltip : '');
    }
    get mainTooltip (): string { ..previously used calculation.. }
    ...
    mounted () {
        this.calcTooltip()
    }
}

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

Split the text using the newline character (' ') and not the double newline character (' ')

Looking to create a filter that separates all \n and combines them back as \n\n. Is it possible to only target the single \n without affecting the double \n\n? Currently, the issue arises when the input field loses focus, caus ...

Ways to switch out error message for an error landing page

I am currently displaying error text when something goes wrong, but I would like to enhance the user experience by redirecting to a well-designed error page instead. Can anyone provide guidance on how to achieve this? Below is my existing code for display ...

Displaying a timer output in an HTML div every second using PHP

I created a custom PHP countdown timer that displays the remaining time in hours, minutes, and seconds (specifically 3 hours) - named countdown.php. The timer output is displayed within a <div> tag on another page called index.html. Now, I am lookin ...

Tips on concealing modal popup when the page refreshes successfully

I implemented a progress modal popup to show progress for page reloads. This script is set to the master page and injects the progress modal popup when the form submit event is fired: <script type="text/javascript"> function ...

Developing a webpack configuration involving two distinct setups yet utilizing identical plugins

Currently, I am tackling a project based on vue.js where I need to develop two separate SPAs - one for the admin dashboard and another for the public side. My goal is to manage these projects separately but work on them simultaneously. It would be convenie ...

Extracting data from XPath results reveals information beyond just the elements themselves

Having trouble using the getElementsByXPath function in CasperJS to return a specific string from an xpath I determined. Despite my efforts, it seems like the function is only returning data for the entire webpage instead of the desired string. var casper ...

What are some effective ways to stretch specific muscles?

I am facing an issue with my select element. The default value is "please choose," but there are options like "Accommodation & Hotels" that are longer and not clearly visible on IE browsers, though they work fine in Firefox. How can I resolve this issue? S ...

Next/image is encountering an error due to an invalid Element type being generated

Trying to utilize the next/image feature to display an SVG image is causing me some trouble. Every time I attempt this, an error message pops up: Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite ...

How do you update the bind value in VueJs when using :value="text"?

My attempts at updating a string when the content is changed inside a textarea are not successful. Vue component: <template> <div> <textarea :value="text" @change="changed = true" @keyup="changed = true"&g ...

Running an Express middleware function

While watching a tutorial on the Express framework, I came across some interesting code used by the instructor for handling requests. Here is how the route is set up: router.route('/').post(authController.restrictTo('admin', 'l ...

Display Material checkbox based on a condition

I have integrated Material UI into my React application to dynamically display text and other information by using JSON data. { "included": [{ "name": "someName", "price": "0", "required": true } ...

How can I use JQuery to save values from a for loop?

After working on a grid, I encountered an issue where only the last value was being returned when trying to fetch all values into an object. Unfortunately, I am stuck and unsure of how to resolve this problem. function item_details(){ var gridDataAr ...

Unlock hidden content with a single click using jQuery's click event

I have a question that seems simple, but I can't quite get the syntax right. My issue is with a group of stacked images. When I click on an image, I want it to move to the front and display the correct description above it. Currently, clicking on the ...

unable to retrieve the city name through geographical location information

I am currently using the following code snippet to retrieve the country and city names: <?php $user_ip= getenv('REMOTE_ADDR'); $geo= unserialize(file_get_contents("http://www.geoplugin.net/php.gp?ip=$user_ip")); $city= $geo["ge ...

Issue with React component not updating content after state changes in Next.js framework

Currently, I am facing an issue with my Header component not updating its content on state change. The goal is to show the user's Profile once the state changes, but unfortunately, it does not update immediately; it only changes after a page refresh o ...

What is the best way to include a new array at the beginning of a lexicographically sorted array?

After lexicographically sorting an array, I am trying to figure out how to add values from another array "cityOfTheMoscow" first and then maintain the lexigraphical order. However, while using the code snippet below: result.unshift(...self.cityOfTheMoscow ...

Adjust camera focus towards object and utilize the lookAt() method (React three fiber)

Seeking a smooth transition for camera.position and camera.lookAt as I switch between "zoomed out" and "zoomed in" views of individual objects randomly placed. The positioning aspect is working smoothly, but lerping the lookAt() function seems to be causi ...

Chrome full screen mode can be toggled on websites after ajax data has loaded

I am currently experiencing a frustrating issue with Chrome on my webpage. The pagination feature loads content via an ajax call at: Whenever I click on the 2nd, 3rd, or subsequent tab in the pagination, the load process occurs but then suddenly jumps int ...

Is it possible to place Angular Material components using code?

Currently, I'm in the process of creating a responsive Angular application. Is there any way to adjust the height and position of the <mat-sidenav-content></mat-sidenav-content> component in Angular Material programmatically without relyi ...

Utilizing React forwardRef with a functional component

Looking at my code, I have defined an interface as follows: export interface INTERFACE1{ name?: string; label?: string; } Additionally, there is a function component implemented like this: export function FUNCTION1({ name, label }: INTERFACE1) { ...