Несколько проблем здесь: 1 - вы отправляете контент HTML в вашу функцию, в то время как он ожидает элемент DOM. 2. Вы добавляете эту текстовую область в верхнюю часть страницы, чтобы браузер снова прокручивал ее до фокуса.
Решение: 1- Удалите .html()
из copyToClipboard()
и создайте переменную в начале этой функции. 2- Добавьте текстовое поле к элементу, по которому щелкнули, чтобы браузер не прокручивал его
Помните удалить скрытое поле, когда-то использованное.
Javascript code ниже
jQuery(".item").click(function () {
var success = copyToClipboard(jQuery(this));
if (success) jQuery(this).fadeOut(100).fadeIn(100);
});
function copyToClipboard(elem) {
// create hidden text element, if it doesn't already exist
var copyText = elem.html();
var targetId = "_hiddenCopyText_";
var isInput = elem.tagName === "INPUT" || elem.tagName === "TEXTAREA";
var origSelectionStart, origSelectionEnd;
if (isInput) {
// can just use the original source element for the selection and copy
target = elem;
origSelectionStart = elem.selectionStart;
origSelectionEnd = elem.selectionEnd;
} else {
// must use a temporary form element for the selection and copy
target = document.getElementById(targetId);
if (!target) {
var target = document.createElement("textarea");
/*target.style.position = "absolute";
target.style.left = "-9999px";
target.style.top = "0";
target.id = targetId;
document.body.appendChild(target);*/
target.style.opacity = 0;
elem.append(target);
}
if(typeof elem == "string") target.textContent = elem;
else target.textContent = elem.text();
}
// select the content
var currentFocus = document.activeElement;
target.focus();
target.setSelectionRange(0, target.value.length);
// copy the selection
var succeed;
try {
succeed = document.execCommand("copy");
} catch(e) {
succeed = false;
}
// restore original focus
if (currentFocus && typeof currentFocus.focus === "function") {
currentFocus.focus();
}
if (isInput) {
// restore prior selection
elem.setSelectionRange(origSelectionStart, origSelectionEnd);
} else {
// clear temporary content
target.textContent = "";
}
target.remove();
return succeed;
}
Посмотрите, если это то, что вы ищете: https://jsfiddle.net/yjvstazu
Сторона примечание : это не будет работать на iOS. Вам нужно сделать input / textarea contentEditable. Добавьте что-то подобное в ваш код:
if (navigator.userAgent.match(/ipad|ipod|iphone/i)) {
target.contentEditable = true;
target.readOnly = true;
var range = document.createRange();
range.selectNodeContents(target);
var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
target.setSelectionRange(0, 999999);
} else {
target.select();
}
Я всегда шел с опцией № 2 и просто удостоверяюсь, что никто, но у владельца есть ЛЮБОЙ вид доступа к ней. Это - самый популярный метод среди приложений PHP как Joomla, vBulletin, Галерея и многочисленные другие.
Первый метод слишком грязен мне (удобочитаемость), и третье Слишком опасно, чтобы сделать. Я никогда не думал о Методе класса, таким образом, кто-то еще может обеспечить их вход на том. Но я предполагаю, что это прекрасно, пока правильный доступ используется на использовании класса.
<час>Пример..
define('EXAMPLE1', "test1"); // scenario 1
$example2 = "test2"; // scenario 2
function DealWithUserInput($input)
{
return eval($input);
}
Теперь этот пример кода является действительно немым, но просто пример. Рассмотрите то, что могло быть возвращено функцией, в зависимости от которого сценария пользователь мог попытаться использовать в их входе.
Сценарий 2 только вызвал бы проблему при создании его глобальным в функции. Иначе это вне объема и недостижимо.
Я бы сказал, что это также немного зависит от пользовательской базы. Если конфигурации должны быть очень удобными для пользователя или у пользователя должна быть возможность изменять конфигурацию через Интернет и т. Д.
Я использую Zend Config Ini для этой и других настроек, хранящихся в БД SQL.
Я обычно использую второй метод... При обработке соединений с базой данных я обычно открываю соединение в начале запроса, затем закрываю его в конце. У меня есть функция, которая устанавливает соединение, затем удаляет имя пользователя/пароль из глобального массива (со сбросом () функция), Это препятствует тому, чтобы другие части системы получили доступ к "чувствительным" данным подключения mysql.
У меня также есть опция 2 для большинства значений конфигурации. Если бы вы собирались реализовать Класс, то я бы привязал конкретные значения к классу, на который он влияет, вместо общего класса конфигурации.
В вашем примере ваш класс предназначен для соединений с базой данных, а экземпляр будет сохранять пароль, имя_базы данных и т. Д. Это будет правильно инкапсулировать данные, а также обеспечит простой способ создания нескольких соединений, если это когда-либо понадобится. .