Страницы

Поиск по вопросам

пятница, 24 мая 2019 г.

Свойство display: table-cell не срабатывает на инпутах

Нужно сделать, чтобы кнопки в ряд занимали всю ширину .row
Сейчас они смещены влево и не тянутся на всю ширину, хотя им присвоено свойство display: table-cell;
Вопрос: почему display: table-cell не работает для инпутов? И можно ли достичь желаемого результата не оборачивая input в дополнительные div?
.row{ display: table; table-layout: fixed; width: 100%; border-spacing: 1px 0; background-color: #eee; } .input{ display: table-cell; }



Ответ

Нужно переделывать на Flexbox, если количество кнопок неизвестно:
.row { height: 25px; display: flex; flex-direction: column; flex-wrap: wrap } .row input { page-break-inside: avoid; break-inside: avoid; }


Или же поставить ширину 25%, если их количество фиксированно:
.row{ display: table; table-layout: fixed; width: 100%; border-spacing: 1px 0; background-color: #eee; } .input{ width: 25%; /* Убираем влияние padding и border на конечную ширину input */ box-sizing: border-box; /* Обнуляем margin */ margin: 0; }

Нужно ли проверять SQLiteDatabase db на null?

В своем андроид-приложении ни разу не проверял db != null, при этом запросы работают. Прочитал, что надо проверять, к примеру, как в следующем коде.
SQLiteDatabase db = new ContactDbHelper( getApplicationContext()).getWritableDatabase(); if (db != null) { Toast.makeText(getApplicationContext(), "DB Contacts is created", Toast.LENGTH_LONG).show(); }else { Toast.makeText(getApplicationContext(), "Error create database!", Toast.LENGTH_LONG).show(); }
Вопрос такой, нужно ли проверять SQLiteDatabase db на null? Это просто подстраховка и если да, по каким причинам БД может не создаться, при условии, что код рабочий?


Ответ

Код открытия БД ищет БД по пути задаваемому методом Context.getDatabasePath(), легко может случиться, что какая-то сволочь однажды решит перегрузить этот метод в своем Activity и указать путь на внешний носитель - тогда вас будет ждать легкий Überraschung :)
Так что проверять надо все таки.

Можно ли в Visual Studio собирать проект на лету?

При компиляции и запуске проекта ASP.NET MVC Core часть .cs файлов блокируется студией и что б изменить код- надо "выключать сборку", изменять код, заново компилировать и запускать изменённый проект, затрачивая время.
Можно ли на лету после изменения .cs файла собрать проект и тут же увидеть в браузере обновлённые данные, не перезапуская весь IIS ?


Ответ

Можно, если использовать компьютер в качестве локального веб-сервера. Не путать с IIS Express, который открывает Visual Studio при запуске проекта.
Следует заметить что компонент IIS включен как часть установки Windows как для сервера, так и для рабочих машин. Каждая версия OS Windows предлагает свою версию IIS: Windows 8 - IIS 8, Windows 7 - IIS 7/7.5

Чтобы установить его, необходимо выполнить следующие действия:
Открыть панель управления Открыть "Программы" Открыть "Включение или отключение компонентов Windows". Выбрать Internet Information Services (Службы IIS) Убедитесь, что вы выбрали поддержку ASP.NET.

Для этого раскройте узел Службы Интернета --> Компоненты разработки приложений --> ASP.NET (Internet Information Services --> World Wide Web Services --> Application Development Features --> ASP.NET) Если вы хотите использовать поддержку IIS в Visual Studio, которая позволяет вам создавать виртуальные каталоги IIS непосредственно в диалоговом окне New Web Site, вам нужно выбрать пункт «Совместимость управления IIS 6» в разделе «Средства управления веб-сайтом» (Web Management Tools --> IIS 6 Management Compatibility).
Ok Убедитесь, что IIS активен: открыть localhost:80 в браузере. Ниже показана стандартная страница. Установить SQL Server и разрешить подключения Открыть Visual Studio с права администратора и создать виртуальный каталог для приложения: ПКМ по проекту --> Свойства --> Веб --> В разделе серверы выбрать "Локальный IIS" --> Нажать "Создать виртуальный каталог". Проект будет доступен по адресу указанному в графе URL-адрес проекта
После написания кода собираем проект Ctrl+Shift+B и перезагружаем страницу в браузере.

Для отладки
Запускаем Visual Studio с правами администратора Жмем кнопку присоединиться (вверху на панельке, зеленая) Ставим галочку на "Показать процессы, запущенные всеми пользователями" Ищем процесс с названием "w3wp.exe" Жмем "Присоединиться"

Вставить текст в border CSS HTML

Мне нужно вставить текст по центру в верхнюю и нижнюю границу, которые будут иметь фоновое изображение позади них. Это будет на каждой странице. Я могу добиться этого с помощью CSS?
Пожалуйста, посмотрите скриншот того, что я имею в виду:

Граница должна быть белого цвета, 3 пикселя в ширину, а шрифт - Basis Grotesque Medium.
Я надеюсь начать с редактирования темы WordPress.
Надеюсь, что на этот вопрос не был получен ответ в другом месте. Я пытался искать, но не мог найти то, что мне нужно.
Прежде чем идти вперед и начать строить этот сайт, не могли бы вы сказать мне, если это возможно, как я могу достигнуть этого?
Источник: Insert text in border CSS HTML


Ответ

Добавлю свои 5 копеек...
body { background-image: url(https://avatars.mds.yandex.net/get-pdb/1016956/27ec7a52-f169-49d8-b895-10a84386bb8b/s1200); background-repeat: no-repeat; } fieldset { border: 3px solid white; border-bottom: none; color: white; } fieldset+fieldset { transform: rotatex(180deg); } fieldset+fieldset>legend { transform: rotatex(180deg); } fieldset>p:last-child { margin-bottom: 0; }

Lorem

...content...

Ipsum

Долгая загрузка сайта

Сижу на хостинге, и у некоторых пользователей очень долгая загрузка сайта. Разбирались, и нашли почему такая проблема, но не нашли решения.
На сайт подключается стиль стандартным способом:

В стиле всего 79 строчек, но самую большую нагрузку в стилемов файле беру изображения:
background: url(../images/bg.jpg);
И вот каждая картинка грузит около 3-5 секунд (весом 900кб).
Не понимаем, с чем связана эта проблема, у 95% пользователей все окей, а у остальных 5% - такая вот беда...
При прямом открытии картинки по URL, эту картинку грузит все равно те же 5 секунд, а остальные - шустро (200мс в среднем).
В какую сторону стоит копать в такой ситуации?


Ответ

Я бы посоветовал вам оптимизировать весь статический контент на сайте.
Сжатие графики
В вашем случае кроме сжатия стилей и скриптов посоветую сжимать и графику. К примеру, картинки можно легко сжать без потери качества только за счет удаление exif-данных. На реальном сайте можно сократить размер картинок в среднем на 70%, что на современном сайте равняется примерно 4 МБ. Пример на gulp
var gulp = require('gulp'), imagemin = require('gulp-imagemin'), imageminJR = require('imagemin-jpeg-recompress'), imageminSvgo = require('imagemin-svgo');
// Optimizing images gulp.task('imagemin', function() { gulp.src('./img/**/*') .pipe(imagemin([ imageminJR({ method: 'ms-ssim' }), imageminSvgo({ plugins: [ {removeViewBox: false} ] }) ])) .pipe(gulp.dest('./public/img/')) });
А для браузеров, которые понимают легковесный формат webp (формат разработан Google), можно сделать еще такой вариант изображений:
var gulp = require('gulp'), webp = require('gulp-webp');
// Generate Webp gulp.task('webp', function() { gulp.src('./img/**/*') .pipe(webp()) .pipe(gulp.dest('./public/img/')) });
Оптимизация скриптов
Сперва объедините все скрипты в один файл и минифицируйте их. Это помет сократить количество HTTP-запросов и размер файлов:
var gulp = require('gulp'), concat = require('gulp-concat'), uglify = require('gulp-uglify');
// Concat JS gulp.task('js', function(){ gulp.src([ './js/jquery.js', './js/wow.js', './js/menu.js', './js/scrollspy.js', './js/main.js', './js/temp/contact.bundled.js', './js/owl.carousel.js' ]) .pipe(concat('script.js')) .pipe(uglify()) .pipe(gulp.dest('./public/js/')) });
Оптимизация стилей
Кроме обычной минификации стилей можно использовать и продвинутую - объединять дубликаты классов и @media. Пример на gulp из моего [web-starter-kit][1]:
var gulp = require('gulp'), stylus = require('gulp-stylus'),
// Минифицирует CSS, объединяет классы. Не ломает CSS, в отличие от cssnano, который, к примеру, может неправильно выставлять z-index csso = require('gulp-csso'),
// Объединяет все @media cmq = require('gulp-combine-mq'),
// Сокращает CSS-селекторы gs = require('gulp-selectors'),
// Проставляет вендорные префиксы autoprefixer = require('gulp-autoprefixer'),
livereload = require('gulp-livereload'), nib = require('nib');
// Compiling Stylus in CSS gulp.task('css', function() { gulp.src('./styl/*.styl') .pipe(stylus({ use: nib() })) .pipe(cmq()) .pipe(csso()) .pipe(autoprefixer('last 3 versions')) .pipe(gulp.dest('./public/css/')) });
А если совсем делать нечего, то можно еще и селекторы сократить:
// Minify selectors gulp.task('gs', function() { var ignores = { classes: ['active', 'menu', 'nav', 'slide', 'error', 'form-control', 'loader', 'showLoader', 'fadeLoader', 'webp', 'wow', 'owl-*', 'i-*'], ids: '*' }; gulp.src(['./public/**/*.css', './public/**/*.html']) .pipe(gs.run({}, ignores)) .pipe(gulp.dest('./public/')) });
Кстати, наверняка у вас есть классы, добавляющиеся через JS, поэтому предварительно стоит все такие классы вынести в переменную ignores
Кеширование статики на стороне пользователя
Также бы посоветовал кешировать скрипты и стили на стороне пользователя, чтобы исключить их повторную загрузку, если они не изменились:
Header set Cache-Control "max-age=2592000"
И включить gzip сжатие на сервере:
# сжатие text, html, javascript, css, xml: AddOutputFilterByType DEFLATE text/html text/plain text/xml application/xml application/xhtml+xml text/css text/javascript application/javascript application/x-javascript

Регулярное выражение для возврата первого (до пробела) слова строки

Пробовал сделать вот так:
string pattern = @"^\s+"; Regex regex = new Regex(pattern, RegexOptions.Singleline);
но когда пытаюсь выполнить
Match match = regex.Match("list command");
мне возвращает ""


Ответ

Скорее всего, вы просто перепутали большую и маленькую S
\s - это пробельный символ
\S - это любой символ кроме пробельного, нужно написать так:
^\S+
или для верности:
^\S+\s

помогите разобратьсяс админкой на laravel 5.3

Мне нужно сделать админку на laravel... Подключил sleepingowl 4! Делаю по данному видеоуроку (https://www.youtube.com/watch?v=ca4zn71n4BI), по инструкции с официального сайта совы ВСЕ данные повносил: файл composer.json:
{... "require": { ... "laravelrus/sleepingowl": "4.*@dev" } }
файл config/app.php:
'providers' => [ ... SleepingOwl\Admin\Providers\SleepingOwlServiceProvider::class, App\Providers\AppServiceProvider::class, ... ]
файл .env:
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_DATABASE=laravel5 DB_USERNAME=root DB_PASSWORD=root
Ввожу в адресную строку http://blog.laravel.com/admin (как сказано в официальных доках http://sleepingowladmin.ru/docs/configuration) выдает:
Not Found
The requested URL /admin was not found on this server. Apache/2.4.18 (Ubuntu) Server at blog.laravel.com Port 80
Логи апача говорят :
127.0.0.1 - - [21/Feb/2017:13:01:23 +0200] "GET /admin HTTP/1.1" 404 502 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:51.0) Gecko/20100101 Firefox/51.0"
Помогите настроить админку!
Ссылка на Github:
https://github.com/AlexBukreyev/blog.laravel


Ответ

Все прекрасно, просто пропишите Route:
/routes/web.php

Анимация заголовка вдоль края страницы

В учебнике написана задача:
Создайте собственную анимацию. Используйте setInterval для анимации заголовка h1, двигая его по квадрату вдоль краев страницы.
Текст двигаю вправо и вниз, а дальше никак, помогите начинающему
var leftOffset = 0; var topOffset = 0; var moveHeading = function () { $("#heading").offset({ left: leftOffset, top: topOffset }); leftOffset++; if (leftOffset > 200) { leftOffset = 200; topOffset++; if (topOffset > 200) { topOffset = 200; } } }; setInterval(moveHeading, 30) move

Привет, мир!



Ответ

Вот работающий пример
move

Привет, мир!


Переезд с mercurial на git

Здравствуйте! Есть большая проблема с переездом на git. Почему-то переезжает только одна ветка, а их полно... Использую TortoiseHg с плагином hggit. В hgrc меняю только path. Прошу помочь в этом вопросе.


Ответ

Для пингвина лучше сделать вот так:
Есть инструмент hg-fast-export
Его можно найти здесь:
git clone http://repo.or.cz/r/fast-export.git /tmp/fast-export
Нужно получить mercurial репу:
hg clone /tmp/hg-repo
Далее нужно создать файл соответствия авторов.
cd /tmp/hg-repo hg log | grep user: | sort | uniq | sed 's/user: *//' > ../authors
В /tmp/authors будет примерно следующее содержимое:
bob bob@localhost bob bob jones company com> Bob Jones Joe Smith
В примере выше, один и тот же человек (Боб) вносил изменения под пятью различными именами, лишь одно из которых правильное, а одно и вовсе не соответствует формату Git. hg-fast-export позволяет быстро исправить ситуацию, добавив ={new name and email address} к каждой строке, которую мы хотим изменить; чтобы оставить имя как есть, просто удалите нужные строки. Если же все имена выглядят хорошо, этот файл и вовсе не потребуется. В нашем примере мы хотим чтобы данные выглядели так:
bob=Bob Jones bob@localhost=Bob Jones bob jones company com>=Bob Jones bob =Bob Jones
Затем нужно создать Git репозиторий и запустить экспорт:
git init /tmp/converted cd /tmp/converted /tmp/fast-export/hg-fast-export.sh -r /tmp/hg-repo -A /tmp/authors
Флаг -r указывает на подлежащий конвертации Mercurial репозиторий, а флаг -A задаёт файл с соответствиями между авторами. Скрипт пробегается по наборам изменений Mercurial и преобразует их в скрипт для fast-import в Git. И отправляем изменение в репу гита:
git remote add origin git@my-git-server:myrepository.git git push origin --all
Для винды почти так же только немного другие команды:
cd c:\projects hg clone hg-repo git init converted git clone http://repo.or.cz/r/fast-export.git
Отредактировать c:\projects\fast-export\hg-fast-export.py. Начало этого скрипта нужно заменить на такое:
#!/usr/bin/env python
# Copyright (c) 2007, 2008 Rocco Rutte and others. # License: MIT
import sys
# import mercurial libraries from zip: sys.path.append(r'C:\Program Files (x86)\Mercurial\library.zip')
from mercurial import node from hg2git import setup_repo, fixup_user, get_branch, get_changeset from hg2git import load_cache, save_cache, get_git_sha1, set_default_branch, set_origin_name from optparse import OptionParser import re import os
Скопировать fast-export в converted игнорируя .git папку. Далее: cd converted и создайте тут файл authors.txt по аналогии из linux версии.
И hg-fast-export.sh -r c:\projects\hg-repo -A authors.txt Готово. Дальше можно заливать гит репу на сервер.

Зависает страница от большого количества

Ребят, добрый день! Нужна идея. Есть страница в которой находится такой список:

  • Заголовок
  • Заголовок
  • Заголовок
  • Заголовок
  • Заголовок
  • Заголовок
  • Заголовок
  • Заголовок
  • Заголовок
  • Заголовок
  • Заголовок

Ещё есть кусочек Jquery:
$(document).ready(function(){ $('video').hide(); }); $(".list-item").click(function() { $(this).next("video").slideToggle(1000); } );
Который позволяет кликнув по заголовку(элементу списка) развернуть находящееся под ним видео, и свернуть его, если оно уже развернуто.
Этот список будет выводиться посредством php. Но проблема в том, что когда страница открывается, то браузер очень сильно виснет. Можно ли как-то оптимизировать все это? Я думал присваивать тегу video значение атрибута src, только после клика по заголовку, но не знаю как это сделать, ведь пути к файлам будут доставаться из Бд средствами php.


Ответ

Надо изначально в php выводить видео с атрибутом display: none;

Потребление памяти PHP-генераторами

В документации говорится:
Генератор позволяет Вам писать код, использующий foreach для перебора набора данных без необходимости создания массива в памяти, что может привести к превышению вами лимита памяти, либо потребует довольно много времени для его создания. Вместо этого, Вы можете написать функцию-генератор, которая, по сути, является обычной функцией, за исключением того, что вместо возвращения единственного значения, генератор может yield столько раз, сколько необходимо для генерации значений, позволяющих перебрать исходный набор данных. Наглядным примером вышесказанного может послужить использование функции range() как генератора. Стандартная функция range() должна генерировать массив, состоящий из значений, и возвращать его, что может послужить результатом генерации огромных массивов: например, вызов range(0, 1000000), приведёт к использованию более чем 100 МБ памяти. В качестве альтернативы мы можем создать генератор xrange(), который использует память только для создания объекта Iterator и сохранения текущего состояния, что потребует не больше 1 килобайта памяти.

A generator allows you to write code that uses foreach to iterate over a set of data without needing to build an array in memory, which may cause you to exceed a memory limit, or require a considerable amount of processing time to generate. Instead, you can write a generator function, which is the same as a normal function, except that instead of returning once, a generator can yield as many times as it needs to in order to provide the values to be iterated over. A simple example of this is to reimplement the range() function as a generator. The standard range() function has to generate an array with every value in it and return it, which can result in large arrays: for example, calling range(0, 1000000) will result in well over 100 MB of memory being used. As an alternative, we can implement an xrange() generator, which will only ever need enough memory to create an Iterator object and track the current state of the generator internally, which turns out to be less than 1 kilobyte.

И приводится пример:
function xrange($start, $limit, $step = 1) { if ($start < $limit) { if ($step <= 0) { throw new LogicException('Step must be +ve'); }
for ($i = $start; $i <= $limit; $i += $step) { yield $i; } } else { if ($step >= 0) { throw new LogicException('Step must be -ve'); }
for ($i = $start; $i >= $limit; $i += $step) { yield $i; } } }
/* * Note that both range() and xrange() result in the same * output below. */
echo 'Single digit odd numbers from range(): '; foreach (range(1, 9, 2) as $number) { echo "$number "; } echo "
";
echo 'Single digit odd numbers from xrange(): '; foreach (xrange(1, 9, 2) as $number) { echo "$number "; }

Я увеличил количество генераций до 100000
range(): https://repl.it/Fy4I xrange(): https://repl.it/Fy4K
Результат мало чем отличается. Я полагал, что при использовании xrange() памяти должно быть потреблено меньше. Почему так?


Ответ

Потому, что вы забыли использовать результат
Надо так:
$a=range(0, 100000);
4474.390625
https://repl.it/Fy4I/1
Создался полный набор значений.
$a=xrange(0, 100000);
377.7890625
https://repl.it/Fy4K/1
Извлечено только одно значение.

Регулярное выражение по HTML

У меня есть такой HTML-код:


Я составил для этого кода регулярное выражение:
\\\\\<\/div\>
Но оно, почему-то, пишет, что нет совпадений. Кто знает в чём дело?


Ответ

Для манипуляций с HTML лучше пользоваться HTML-парсером. Вот пример использования PHP DomDocument для удаления определенных тегов вместе с их содержимым:
$html = <<

Start

DATA;
$dom = new DOMDocument('1.0', 'UTF-8'); // Инициализация DOMDocument $dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); // Заполнение структуры данными
$xpath = new DOMXPath($dom); // Инициализация DOMXPath нашими данными $divs = $xpath->query('//div[@id="community_header" and @class="wcommunity_header"]'); // Запрос XPath
foreach ($divs as $div) { $div->parentNode->removeChild($div); // Удаление найденных элементов }
echo $dom->saveHTML();
См. демо этого кода
Запрос XPath означает:
//div - найди все div, в которых [@id="community_header" - атрибутidравенcommunity_header` and - а также @class="wcommunity_header"] - атрибут class равен wcommunity_header

Странное поведение ограничений в обобщенном методе

Всем доброго времени суток. Может быть кто-то уже сталкивался с таким и может помочь?
public static class JSON { public static string Serialize_object_TO_JSON(this T Entity) where T:ENT { return JsonConvert.SerializeObject(Entity); }
}
Есть некий класс, который наследует ENT и передавать его в атрибуты можно. Дальше мне пришлось переделать метод так, чтоб она работал с коллекциями:
public static class JSON { public static string Serialize_object_TO_JSON(this T Entity) where T:List { return JsonConvert.SerializeObject(Entity); }
}
После чего компилятор говорит, что ему не удалось привести тип класса, который наследуется от ENT, к типу List.
P.S. Изначально задавать обобщение конечного класса я не могу, т.к. их довольно много, именно по этому попытался делать через наследование.


Ответ

Попробуйте так, если Вам это разрешает бизнес логика:
public static class JSON { public static string Serialize_object_TO_JSON(this T Entity) where T : IEnumerable { return JsonConvert.SerializeObject(Entity); } }
Дело в том что List - инвариантен. И все классы в .NET инвариантны. То есть это полное соответствие типов.
Означает, что можно использовать только изначально заданный тип. Таким образом, параметр инвариантного универсального типа не является ни ковариантным, ни контравариантным.
С другой стороны есть IEnumerable где тип-параметр T помечен как out - ковариантным.
Позволяет использовать тип с большей глубиной наследования, чем задано изначально.
Полное описание почему так
+1 за хороший пример

Рандом в крестиках ноликах

Я сделал простую версию игры крестики нолики. При нажатии на ячейку, в ней появляется крестик и вызывается функция, что бы поставить нолик рандомно.
Я добавил условие, что если ячейка не пустая, то ничего не ставить. С крестиком это срабатывает, а вот с ноликом нет. Если ячейка занята то оно ничего вообще не ставит. Как можно нормально это поправить?
$(function() { var bot = function() { var cell = Math.floor(Math.random() * (10 - 1)) + 1; if( $('.board-cell').eq(cell).text() == '' ) $('.board-cell').eq(cell).text( 'O' ); }; $('.board-cell').click(function() { if( $(this).text() == '' ){ $(this).text( 'X' ); bot(); }; }); }); .board { display: flex; flex-wrap: wrap; width: 153px; height: 153px; border-left: 1px solid black; border-top: 1px solid black; } .board-cell { width: 50px; height: 50px; border-right: 1px solid black; border-bottom: 1px solid black; cursor: pointer; }



Ответ

Можно так:
$(function() { function bot() { var $cells = $('.board-cell:empty'); var i = Math.floor(Math.random() * $cells.length); $cells.eq(i).text( 'O' ); }; $('.board-cell').click(function() { if( $(this).text() == '' ){ $(this).text( 'X' ); bot(); }; }); }); .board { display: flex; flex-wrap: wrap; width: 153px; height: 153px; border-left: 1px solid black; border-top: 1px solid black; } .board-cell { width: 50px; height: 50px; border-right: 1px solid black; border-bottom: 1px solid black; cursor: pointer; }


await Task не содержит определение Delay

using System.Threading.Tasks;
private async Task PageLoad(int TimeOut) { TaskCompletionSource PageLoaded = null; PageLoaded = new TaskCompletionSource(); int TimeElapsed = 0; _webBrowser.DocumentCompleted += (s, e) => { if (_webBrowser.ReadyState != WebBrowserReadyState.Complete) return; if (PageLoaded.Task.IsCompleted) return; PageLoaded.SetResult(true); };
while (PageLoaded.Task.Status != TaskStatus.RanToCompletion) { TimeElapsed++; if (TimeElapsed >= TimeOut * 100) PageLoaded.TrySetResult(true); await Task.Delay(10); } }
Почему VS пишет что Task не содержит определение для Dеlay? Вроде для ее работы нужна только System.Threading.Tasks или опять что-то поменялось?


Ответ

Task.Delay доступен с версии .NET Framework 4.5.
Есть аналог для .NET Framework 4 в реализации Microsoft Async
использовать так:
await TaskEx.Delay(1000);

Ошибка: play() can only be initiated by a user gesture (мобильный Chrome)

Делаем приложение через Ionic/Cordova; компилю на платформу browser; через библиотeку медиа пытаюсь запустить мелодию по событию (пришел заказ от клиента).
Столкнулся с такой проблемой: если PUSH работает нормально, то на попытку инициализировать звук когда открыто приложение через мобильный хром — ну ни как не получается. Вылетает такая ошибка:
Uncaught (in promise) DOMException: play() can only be initiated by a user gesture.
И да, я читал, что это такое и немного вот об этом и этом
Понаходил советы, что нужно вызов проигрывания цеплять на click или другой жест. Но, при всех прочих, захожу в ВК с мобильного браузера, смотрю на страницу — мне присылают сообщение, и звук идёт (не от PUSH, а от браузера)!
Вопрос: как у них это получилось? И как мне сделать такое же (хотя бы в теории)? Буду рад любым идеям. Спасибо.


Ответ

function initAudioItems(e) { if (e.originalEvent !== undefined) { var dom_item = document.getElementById('my_audio'); dom_item.muted = true; dom_item.play() .catch(function(e) { console.log(e); }); dom_item.pause(); dom_item.muted = false; $(dom_item).data('init', true); $('body').off('click', initAudioItems); } } // init audio $('body').on('click', initAudioItems);
Если пользователь хоть раз кликнет на странице - аудио беззвучно запустится и остановится. После этого вы можете запускать его по произвольному событию.
Как ни старался не смог найти как такую инициализацию повесить на пролистывание, только на клик работает.

Как сделать плавную смену css градиента при наведении

Как можно сделать плавную смену фона (градиент на градиент) при наведении hover на элемент. Сделал кнопку, дал ей все необходимые стили, включая transition для плавности эффекта наведения, но при этом смена фона происходит резко, а все остальные эффекты в виде изменения тени, как положено меняются плавно.
.btn_default { display: inline-block; min-width: 200px; font-family: $bold; font-size: 1.125em; margin-top: 10px; padding: 13px 20px; text-align: center; color: #fff; outline: none; border-radius: 30px; background: linear-gradient(0deg, rgb(158, 48, 160), rgb(213, 80, 298)); box-shadow: 0 2px 7px rgba(213, 80, 208, 0.6); transition: all 0.5s; } .btn_default:hover { color: #fff; text-decoration: none; background: linear-gradient(0deg, rgb(101, 31, 102), rgb(173, 65, 169)); box-shadow: 0 2px 10px rgba(213, 80, 208, 0.9); } Some link


Ответ

Как вариант
.btn_default { display: inline-block; min-width: 200px; font-family: $bold; font-size: 1.125em; margin-top: 10px; padding: 13px 20px; text-align: center; color: #fff; outline: none; border-radius: 30px; background: linear-gradient(0deg, rgb(158, 48, 160), rgb(213, 80, 298)); box-shadow: 0 2px 7px rgba(213, 80, 208, 0.6); position: relative; } .btn_default > span{ position: relative; z-index: 1; } .btn_default:after { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; color: #fff; text-decoration: none; background: linear-gradient(0deg, rgb(101, 31, 102), rgb(173, 65, 169)); box-shadow: 0 2px 10px rgba(213, 80, 208, 0.9); border-radius: 30px; opacity: 0; transition: opacity 0.5s; } .btn_default:hover:after { opacity: 1; } Some link