Как отследить, вышел ли блок за пределы окна браузера или нет?
Почему не работает следующий код, который вроде как скидывают везде где задают такие вопросы как у меня?
<template> <div class="popup" :style="{ transform: `translate(${scaleX}%, ${scaleY}%)` }" > Какое-то модальное окно при клике на предмет </div> </template> |
<template> <div class="popup" :style="{ transform: `translate(${scaleX}%, ${scaleY}%)` }" > Какое-то модальное окно при клике на предмет </div> </template>
Код ниже - это методы vue компонента:
data() { return { scaleX: 0, scaleY: 0, }; }, methods: { onResize() { console.log(this.$el); if ( this.$el && this.$el.getBoundingClientRect && typeof this.$el.getBoundingClientRect == "function" ) { const boundingRect = this.$el.getBoundingClientRect(); const { left, top, width, height } = boundingRect; console.log(boundingRect, top + height, window.innerHeight); if (left + width > window.innerWidth) this.scaleX = -100; if (top + height > window.innerHeight) this.scaleY = -100; } }, }, mounted() { window.addEventListener("resize", this.onResize); this.onResize(); }, |
data() { return { scaleX: 0, scaleY: 0, }; }, methods: { onResize() { console.log(this.$el); if ( this.$el && this.$el.getBoundingClientRect && typeof this.$el.getBoundingClientRect == "function" ) { const boundingRect = this.$el.getBoundingClientRect(); const { left, top, width, height } = boundingRect; console.log(boundingRect, top + height, window.innerHeight); if (left + width > window.innerWidth) this.scaleX = -100; if (top + height > window.innerHeight) this.scaleY = -100; } }, }, mounted() { window.addEventListener("resize", this.onResize); this.onResize(); },
Т.е. мы просто как и везде определяем, является ли координата x ( или y ) + шириа ( или высота ) больше чем ширина/высота окна браузера и если да - то просто передвигаем модалку.
Почему это не работает? Т.е. даже если вывести true или false в консоли, т.е. что возвращает условие - оно вернет false.
Дополнительно:
Я кнчн этот код в разных вариациях переписывал, но логика одна и оно не робит)
а даже не блок сверить а просто получить window.screen.width
Но проблема в том что блок начинает туда сюда скакать, т.е. он скрыт за пределами - возвращается на место стилями, потом обратно за пределы и так бесконечный цикл
или мб так даж
if(left + width < 0 || left > window.screen.width) { } |
if(left + width < 0 || left > window.screen.width) { }
?
обёртку у модалки - кидаешь в боди а тело модалки, кидаешь в этот блок обёртку и - ровняешь относительно этого же блока в котором она находится, делаешь этот блок обёртку у модалки абсолютом, и у боди скрываешь скролл, и тогда не придётся делать какие-то вычисления о том, ушёл ли блок за пределы окна просмотра и т.д
Смотри, четко видно что модалка за пределами области видимости, в консоли даже вывел координаты, ширину, высоту и т.д. Также ниже есть еще и цифры - высота и ширина браузера ( в таком порядке ).
И при этом все эти формулы, x, y, y+height, x + width не выполняют условие "больше чем ширина/высота окна"
НО ВИДНО же как модалка скрывается емае, как так то а?
а хотя в твоём случае это проверка не поможет, у тебя там вообще стоит 370+ px left, хз как ты так сверстал её
да и если на то пошло, раз ты разраб на vue, с модалкой должен на легаси разобраться чё уж...вряд ли сверхъестественная она
Модалка открывается простым кликом, который меняет модель isVisible на !isVisible. Модалка отображается по условию v-if='isVisible'. Все.
Эта модалка открывается по клику на один из многих предметов. Т.е. как инвентарь.
Код модалки вот)
<template> <div ref='popup' class="popup" :style="{ transform: `translate(${scaleX}%, ${scaleY}%)` }" > <div class="popup-main"> <div class="popup-main__header"> <div class="popup-main__header-title"> <p>{{ item.source.title }}</p> <p>{{ item.source.weight }} КГ</p> </div> <div class="popup-main__header-data"> <p>{{ $t(`inventory.rarity.${item.source.rarity}`) }}</p> <p>{{item.source.isQuestItem ? 'Квестовый' : 'Стандартный'}}</p> </div> </div> <div class="popup-main__content"> <div class="popupItem"> <div class="popupItem-image"> <img :src=" $_getImage( `images/menu/inventory/items/${item.source.imageName}` ) " alt="Image" /> </div> </div> <div class="popupDescription"> <p> {{ item.dynamicDescription || item.source.description }} </p> <div class="popupDescription-stickers"></div> </div> </div> <div class="popup-main__footer"> <div class="item-effects" v-if="item.source.effectList"> <h5 class="item-effects__title">Эффекты предмета</h5> <item-effect v-for="effect in item.source.effectList" :key="effect.id" :effect="effect" /> </div> <popup-weapon :weapon="item.source.weaponCharacteristics"/> </div> </div> </div> </template> |
<template> <div ref='popup' class="popup" :style="{ transform: `translate(${scaleX}%, ${scaleY}%)` }" > <div class="popup-main"> <div class="popup-main__header"> <div class="popup-main__header-title"> <p>{{ item.source.title }}</p> <p>{{ item.source.weight }} КГ</p> </div> <div class="popup-main__header-data"> <p>{{ $t(`inventory.rarity.${item.source.rarity}`) }}</p> <p>{{item.source.isQuestItem ? 'Квестовый' : 'Стандартный'}}</p> </div> </div> <div class="popup-main__content"> <div class="popupItem"> <div class="popupItem-image"> <img :src=" $_getImage( `images/menu/inventory/items/${item.source.imageName}` ) " alt="Image" /> </div> </div> <div class="popupDescription"> <p> {{ item.dynamicDescription || item.source.description }} </p> <div class="popupDescription-stickers"></div> </div> </div> <div class="popup-main__footer"> <div class="item-effects" v-if="item.source.effectList"> <h5 class="item-effects__title">Эффекты предмета</h5> <item-effect v-for="effect in item.source.effectList" :key="effect.id" :effect="effect" /> </div> <popup-weapon :weapon="item.source.weaponCharacteristics"/> </div> </div> </div> </template>
<style lang="scss" scoped> .menuInventoryItem { &.ordinary .popup::v-deep { &::before, &::after { background-color: rgba($color: #999999, $alpha: 1); } .popup-main__header-data > p:first-child, .popup-main__header-title > p:first-child { color: rgba($color: #999999, $alpha: 1); } } &.rare .popup::v-deep { &::before, &::after { background-color: rgba($color: #5FBCFF, $alpha: 1); } .popup-main__header-data > p:first-child, .popup-main__header-title > p:first-child { color: rgba($color: #5FBCFF, $alpha: 1); } } &.epic .popup::v-deep { &::before, &::after { background-color: rgba($color: #A47AFD, $alpha: 1); } .popup-main__header-data > p:first-child, .popup-main__header-title > p:first-child { color: rgba($color: #A47AFD, $alpha: 1); } } &.legendary .popup::v-deep { &::before, &::after { background-color: rgba($color: #E4D238, $alpha: 1); } .popup-main__header-data > p:first-child, .popup-main__header-title > p:first-child { color: rgba($color: #E4D238, $alpha: 1); } } } .popup { position: absolute; min-width: 290rem; zoom: 1.8; z-index: 15; width: 250rem; left: 50%; top: 50%; &::before { content: ''; display: block; background: rgba(128, 128, 128, 0.4); width: 95%; height: 1px; position: absolute; left:0; right: 0; margin:0 auto; top:0; z-index: 1; } &::after{ content: ''; display: block; background: rgba(128, 128, 128, 0.4); width: 95%; height: 1px; position: absolute; left:0; right: 0; margin:0 auto; bottom:0; } font-family: "Gilroy"; } .popup-main { background: rgba(0, 0, 0, 0.5); padding: 10rem; border-radius: 2rem; border-top:1px solid #fff; border-bottom: 1px solid #fff; position: relative; } .popup-main__header { display: flex; align-items: center; justify-content: space-between; margin: 5rem 0; &:first-child { margin-top: 0; } &:last-child { margin-bottom: 0; } } .popup-main__header-title { & > p { &:first-child { font-weight: 600; font-size: 16rem; color: rgba($color: #fff, $alpha: 1); line-height: 14rem; text-transform: uppercase; } &:not(:first-child) { font-size: 8rem; color: rgba($color: #A5A5A5, $alpha: 1); line-height: 11rem; } } } .popup-main__header-data { & > p { font-weight: 500; text-align: end; &:first-child { font-size: 14rem; color: rgba($color: #d272ff, $alpha: 1); line-height: 10rem; text-transform: uppercase; } &:not(:first-child) { font-size: 9rem; color: rgba($color: #A5A5A5, $alpha: 1); } } } .popup-main__content { //display: flex; padding-bottom: 8rem; /* prettier-ignore */ border: solid rgba($color: #FFFFFF, $alpha: 0.1); border-width: 1rem 0 1rem 0; margin: 5rem 0; padding: 5rem 0 0 0; &:first-child { margin-top: 0; } &:last-child { margin-bottom: 0; } & > * { margin-right: 10rem; &:last-child { margin-right: 0; } } } .popupItem { // flex-shrink: 0; // flex-grow: 0; width: 100%; border-radius: 2rem; & > p { font-weight: 500; font-size: 0.811vmin; line-height: 1.389vmin; color: white; text-align: end; } } .popupItem-image { width: 270rem; height: 70rem; display: flex; align-items: center; justify-content: center; & > img { max-width: 100%; max-height: 100%; flex-shrink: 0; flex-grow: 0; } } .popupDescription { padding: 5rem 0; & > p { text-align: center; font-weight: 500; font-size: 10rem; color: rgba($color: #A5A5A5, $alpha: 1); } } .item-effects__title{ font-size: 12rem; color:#fff; font-weight: 400; text-transform: uppercase; margin-top:10px; margin-bottom: 5px; } </style> |
<style lang="scss" scoped> .menuInventoryItem { &.ordinary .popup::v-deep { &::before, &::after { background-color: rgba($color: #999999, $alpha: 1); } .popup-main__header-data > p:first-child, .popup-main__header-title > p:first-child { color: rgba($color: #999999, $alpha: 1); } } &.rare .popup::v-deep { &::before, &::after { background-color: rgba($color: #5FBCFF, $alpha: 1); } .popup-main__header-data > p:first-child, .popup-main__header-title > p:first-child { color: rgba($color: #5FBCFF, $alpha: 1); } } &.epic .popup::v-deep { &::before, &::after { background-color: rgba($color: #A47AFD, $alpha: 1); } .popup-main__header-data > p:first-child, .popup-main__header-title > p:first-child { color: rgba($color: #A47AFD, $alpha: 1); } } &.legendary .popup::v-deep { &::before, &::after { background-color: rgba($color: #E4D238, $alpha: 1); } .popup-main__header-data > p:first-child, .popup-main__header-title > p:first-child { color: rgba($color: #E4D238, $alpha: 1); } } } .popup { position: absolute; min-width: 290rem; zoom: 1.8; z-index: 15; width: 250rem; left: 50%; top: 50%; &::before { content: ''; display: block; background: rgba(128, 128, 128, 0.4); width: 95%; height: 1px; position: absolute; left:0; right: 0; margin:0 auto; top:0; z-index: 1; } &::after{ content: ''; display: block; background: rgba(128, 128, 128, 0.4); width: 95%; height: 1px; position: absolute; left:0; right: 0; margin:0 auto; bottom:0; } font-family: "Gilroy"; } .popup-main { background: rgba(0, 0, 0, 0.5); padding: 10rem; border-radius: 2rem; border-top:1px solid #fff; border-bottom: 1px solid #fff; position: relative; } .popup-main__header { display: flex; align-items: center; justify-content: space-between; margin: 5rem 0; &:first-child { margin-top: 0; } &:last-child { margin-bottom: 0; } } .popup-main__header-title { & > p { &:first-child { font-weight: 600; font-size: 16rem; color: rgba($color: #fff, $alpha: 1); line-height: 14rem; text-transform: uppercase; } &:not(:first-child) { font-size: 8rem; color: rgba($color: #A5A5A5, $alpha: 1); line-height: 11rem; } } } .popup-main__header-data { & > p { font-weight: 500; text-align: end; &:first-child { font-size: 14rem; color: rgba($color: #d272ff, $alpha: 1); line-height: 10rem; text-transform: uppercase; } &:not(:first-child) { font-size: 9rem; color: rgba($color: #A5A5A5, $alpha: 1); } } } .popup-main__content { //display: flex; padding-bottom: 8rem; /* prettier-ignore */ border: solid rgba($color: #FFFFFF, $alpha: 0.1); border-width: 1rem 0 1rem 0; margin: 5rem 0; padding: 5rem 0 0 0; &:first-child { margin-top: 0; } &:last-child { margin-bottom: 0; } & > * { margin-right: 10rem; &:last-child { margin-right: 0; } } } .popupItem { // flex-shrink: 0; // flex-grow: 0; width: 100%; border-radius: 2rem; & > p { font-weight: 500; font-size: 0.811vmin; line-height: 1.389vmin; color: white; text-align: end; } } .popupItem-image { width: 270rem; height: 70rem; display: flex; align-items: center; justify-content: center; & > img { max-width: 100%; max-height: 100%; flex-shrink: 0; flex-grow: 0; } } .popupDescription { padding: 5rem 0; & > p { text-align: center; font-weight: 500; font-size: 10rem; color: rgba($color: #A5A5A5, $alpha: 1); } } .item-effects__title{ font-size: 12rem; color:#fff; font-weight: 400; text-transform: uppercase; margin-top:10px; margin-bottom: 5px; } </style>
Я отключил стиль zoom емае и она стала мелкой, в этом может быть причина?))) АХхпахах боже, чтоо.. Так она реально не выходит за пределы
тут так просто не разберешься, копаться надо, смотреть уже другой блок, блок относительно которого она позиционируется - но стили его и код его мне скидывать не надо, я этой шляпой заниматься не собираюсь, но ответ я дал относительно этого кода и скрина который ты скинул
действительно там есть стиль зум, мде
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос






Для отслеживания того, выходит ли блок за пределы окна браузера или нет, можно воспользоваться JavaScript. Существует несколько способов достичь этой функциональности, но одним из наиболее простых и эффективных является использование методов getBoundingClientRect() и window.innerHeight.
Пример кода на JavaScript:
// Получаем элемент, который хотим отслеживать var element = document.getElementById('myElement'); // Получаем его размеры и позицию var rect = element.getBoundingClientRect(); // Проверяем, выходит ли элемент за пределы окна браузера if(rect.top window.innerHeight) { console.log('Элемент вышел за пределы окна браузера'); } else { console.log('Элемент находится в пределах окна браузера'); }
В этом примере мы сначала получаем элемент, который хотим отслеживать, затем получаем его размеры и позицию относительно окна браузера с помощью метода getBoundingClientRect(). После этого мы проверяем, выходит ли верхняя или нижняя границы элемента за пределы высоты окна браузера (window.innerHeight). Если хотя бы одна из границ выходит за пределы, то выводим сообщение об этом.
Таким образом, данный код позволяет отслеживать, выходит ли блок за пределы окна браузера или остается видимым.