- Saat Modal dibuka, setel fokus pada <input> yang telah ditentukan di dalam Modal ini.
Tetapkan arahan dan minta $ tonton properti / pemicu sehingga tahu kapan harus memfokuskan elemen:
Name: <input type="text" focus-me="shouldBeOpen">
app.directive('focusMe', ['$timeout', '$parse', function ($timeout, $parse) {
return {
//scope: true, // optionally create a child scope
link: function (scope, element, attrs) {
var model = $parse(attrs.focusMe);
scope.$watch(model, function (value) {
console.log('value=', value);
if (value === true) {
$timeout(function () {
element[0].focus();
});
}
});
// to address @blesh's comment, set attribute value to 'false'
// on blur event:
element.bind('blur', function () {
console.log('blur');
scope.$apply(model.assign(scope, false));
});
}
};
}]);
Plunker
$ Timeout tampaknya diperlukan untuk memberikan modal waktu untuk merender.
'2.' Setiap kali <input> menjadi terlihat (misalnya dengan mengklik beberapa tombol), atur fokus padanya.
Buat arahan dasarnya seperti yang ada di atas. Tonton beberapa properti lingkup, dan ketika itu menjadi benar (atur di pawang ng-klik Anda), jalankan element[0].focus()
. Bergantung pada kasus penggunaan Anda, Anda mungkin perlu atau tidak perlu $ timeout untuk yang ini:
<button class="btn" ng-click="showForm=true; focusInput=true">show form and
focus input</button>
<div ng-show="showForm">
<input type="text" ng-model="myInput" focus-me="focusInput"> {{ myInput }}
<button class="btn" ng-click="showForm=false">hide form</button>
</div>
app.directive('focusMe', function($timeout) {
return {
link: function(scope, element, attrs) {
scope.$watch(attrs.focusMe, function(value) {
if(value === true) {
console.log('value=',value);
//$timeout(function() {
element[0].focus();
scope[attrs.focusMe] = false;
//});
}
});
}
};
});
Plunker
Pembaruan 7/2013 : Saya telah melihat beberapa orang menggunakan arahan lingkup isolat asli saya dan kemudian memiliki masalah dengan bidang input yang disematkan (yaitu, bidang input dalam modal). Arahan tanpa ruang lingkup baru (atau mungkin ruang lingkup anak baru) harus mengurangi rasa sakit. Jadi di atas saya memperbarui jawabannya untuk tidak menggunakan cakupan isolasi. Di bawah ini adalah jawaban asli:
Jawaban orisinal untuk 1., menggunakan ruang lingkup isolasi:
Name: <input type="text" focus-me="{{shouldBeOpen}}">
app.directive('focusMe', function($timeout) {
return {
scope: { trigger: '@focusMe' },
link: function(scope, element) {
scope.$watch('trigger', function(value) {
if(value === "true") {
$timeout(function() {
element[0].focus();
});
}
});
}
};
});
Plunker .
Jawaban orisinal untuk 2., menggunakan ruang lingkup isolasi:
<button class="btn" ng-click="showForm=true; focusInput=true">show form and
focus input</button>
<div ng-show="showForm">
<input type="text" focus-me="focusInput">
<button class="btn" ng-click="showForm=false">hide form</button>
</div>
app.directive('focusMe', function($timeout) {
return {
scope: { trigger: '=focusMe' },
link: function(scope, element) {
scope.$watch('trigger', function(value) {
if(value === true) {
//console.log('trigger',value);
//$timeout(function() {
element[0].focus();
scope.trigger = false;
//});
}
});
}
};
});
Plunker .
Karena kita perlu mereset properti trigger / focusInput dalam direktif, '=' digunakan untuk penyatuan data dua arah. Dalam arahan pertama, '@' sudah cukup. Perhatikan juga bahwa ketika menggunakan '@' kami membandingkan nilai pemicu ke "true" karena @ selalu menghasilkan string.
ng-model
pada bidang input, nilai model hilang ketika saya menggunakan direktif ini w / ruang lingkup isolat digunakan. Masalahnya tidak terjadi jika saya mencoba versi Josh tanpa ruang lingkup isolasi. Masih pemula, dan saya ingin memahami perbedaannya. Berikut adalah Plunker yang menunjukkannya.value != "true"
, dan itu muncul untuk mengatasi masalah saya.(EDIT: Saya telah menambahkan solusi yang diperbarui di bawah penjelasan ini)
Mark Rajcok adalah pria ... dan jawabannya adalah jawaban yang valid, tetapi
memilikicacat (Mark maaf) ...... Coba gunakan boolean untuk fokus pada input, lalu buramkan input, lalu coba gunakan untuk memfokuskan input lagi. Ini tidak akan berfungsi kecuali jika Anda mengatur ulang boolean ke false, lalu $ digest, lalu reset kembali ke true. Bahkan jika Anda menggunakan perbandingan string dalam ekspresi Anda, Anda akan dipaksa untuk mengubah string ke sesuatu yang lain, $ digest, lalu ubah kembali.(Ini telah diatasi dengan pengendali acara blur.)Jadi saya mengusulkan solusi alternatif ini:
Gunakan acara, fitur Angular yang terlupakan.
Bagaimanapun, JavaScript menyukai acara. Acara secara inheren digabungkan secara longgar, dan bahkan lebih baik, Anda menghindari menambahkan $ menonton lain ke $ digest Anda.
Jadi sekarang Anda bisa menggunakannya seperti ini:
dan kemudian di mana saja di aplikasi Anda ...
Ini luar biasa karena Anda dapat melakukan segala macam hal dengan sesuatu seperti ini. Untuk satu, Anda bisa mengikat ke acara yang sudah ada. Untuk hal lain, Anda mulai melakukan sesuatu yang cerdas dengan meminta bagian yang berbeda dari aplikasi Anda mempublikasikan acara yang dapat diikuti oleh bagian lain dari aplikasi Anda.
Bagaimanapun, jenis hal ini berteriak "event driven" kepada saya. Saya pikir sebagai pengembang Angular kami berusaha sangat keras untuk memalu pasak berbentuk $ lingkup ke lubang bentuk acara.
Apakah ini solusi terbaik? Saya tidak tahu. Ini sebuah solusi.
Solusi Terbaru
Setelah komentar @ ShimonRachlenko di bawah, saya telah mengubah metode saya untuk melakukan ini sedikit. Sekarang saya menggunakan kombinasi layanan dan arahan yang menangani acara "di belakang layar":
Selain itu, prinsipal yang sama dijelaskan di atas.
Ini demo singkat Plunk
Pemakaian
Sumber
sumber
$broadcast
dengan$timeout
jika Anda ingin ini berhasil memasuki controller. Kalau tidak solusi yang bagus.Saya telah menemukan beberapa jawaban lain yang terlalu rumit ketika semua yang Anda butuhkan adalah ini
penggunaan adalah
Kami menggunakan batas waktu untuk membiarkan hal-hal di dom render, meskipun nol, setidaknya menunggu untuk itu - dengan cara ini bekerja dalam modals dan yang lainnya juga
sumber
ng-click
: Katakanlah mengklik tombol adang-click="showInput = !showInput
pada input Anda. Kemudian, pada input Anda yang sebenarnya, tambahkanng-if="showInput"
. Beralih tombol akan membuat arahan dijalankan kembali setiap kali. Saya mengalami masalah dengan ini karena saya menggunakanng-show
yang merupakan pendekatan yang salah.HTML memiliki atribut
autofocus
.http://www.w3schools.com/tags/att_input_autofocus.asp
sumber
Anda juga dapat menggunakan fungsionalitas jqlite bawaan sudut.
angular.element('.selector').trigger('focus');
sumber
Looking up elements via selectors is not supported by jqLite!
Ini bekerja dengan baik dan cara sudut untuk memfokuskan kontrol input
Meskipun ini bukan cara sudut murni dalam melakukan tugas namun sintaksinya mengikuti gaya sudut. Jquery memainkan peran secara tidak langsung dan langsung mengakses DOM menggunakan Angular (jQLite => JQuery Light).
Jika diperlukan, kode ini dapat dengan mudah dimasukkan ke dalam arahan sudut sederhana di mana elemen dapat diakses secara langsung.
sumber
Looking up elements via selectors is not supported by jqLite!
angular.element
menjadi pembungkus$() / jQuery()
. Jadi tanpa itu ini tidak akan berhasil, dan Anda pada dasarnya hanya menggunakan jQuery (tapi perbaiki jika saya salah)Saya tidak berpikir $ timeout adalah cara yang baik untuk memfokuskan elemen pada penciptaan. Berikut adalah metode yang menggunakan fungsionalitas sudut bawaan, yang digali dari kedalaman suram dokumen sudut. Perhatikan bagaimana atribut "tautan" dapat dipecah menjadi "pra" dan "pos", untuk fungsi pra-tautan dan pasca-tautan.
Contoh Kerja: http://plnkr.co/edit/Fj59GB
Dokumen Petunjuk AngularJS Lengkap: https://docs.angularjs.org/api/ng/service/$compile
sumber
Ini solusi asli saya:
plunker
Dan HTML:
Apa fungsinya:
Ini memfokuskan input karena menjadi terlihat dengan ng-show. Tidak ada penggunaan $ watch atau $ di sini.
sumber
Saya telah menulis arahan fokus mengikat dua arah, seperti halnya model baru-baru ini.
Anda dapat menggunakan arahan fokus seperti ini:
Jika Anda membuat variabel scope someFocusVariable
true
di mana saja di controller Anda, input menjadi fokus. Dan jika Anda ingin "mengaburkan" input Anda, someFocusVariable dapat disetel ke false. Ini seperti jawaban pertama Mark Rajcok tetapi dengan ikatan dua arah.Ini adalah arahannya:
Pemakaian:
Ini biola:
http://fiddle.jshell.net/ubenzer/9FSL4/8/
sumber
Bagi mereka yang menggunakan Angular dengan plugin Bootstrap:
http://angular-ui.github.io/bootstrap/#/modal
Anda dapat mengaitkan
opened
janji dengan instance modal:sumber
$timeout
dengan50ms
sedang membutuhkan alih-alih0
.Saya merasa berguna untuk menggunakan ekspresi umum. Dengan cara ini Anda dapat melakukan hal-hal seperti memindahkan fokus secara otomatis ketika input teks valid
Atau secara otomatis fokus ketika pengguna menyelesaikan bidang panjang tetap
Dan tentu saja fokus setelah memuat
Kode untuk arahan:
sumber
Untuk tidak menghidupkan kembali zombie atau memasang arahan saya sendiri (ok itulah yang saya lakukan):
https://github.com/hiebj/ng-focus-if
http://plnkr.co/edit/MJS3zRk079Mu72o5A9l6?p=preview
sumber
Pertama, cara resmi untuk melakukan fokus adalah pada peta jalan untuk 1.1 . Sementara itu, Anda dapat menulis arahan untuk menerapkan fokus pengaturan.
Kedua, untuk menetapkan fokus pada item setelah terlihat saat ini membutuhkan solusi. Cukup tunda panggilan Anda ke fokus elemen () dengan a
$timeout
.Karena masalah kontroler-modifikasi-DOM yang sama ada untuk fokus, kabur dan pilih, saya mengusulkan memiliki
ng-target
arahan:Utas sudut di sini: http://goo.gl/ipsx4 , dan detail lainnya di-blog di sini: http://goo.gl/4rdZa
Arahan berikut akan membuat
.focus()
fungsi di dalam controller Anda seperti yang ditentukan olehng-target
atribut Anda . (Ini membuat.blur()
dan.select()
juga.) Demo: http://jsfiddle.net/bseib/WUcQX/sumber
ngFocus
tampaknya menjadi cara untuk menanganifocus
acara, bukan cara untuk mengatur fokus pada suatu elemen.Alih-alih membuat arahan Anda sendiri, dimungkinkan untuk hanya menggunakan fungsi javascript untuk mencapai fokus.
Berikut ini sebuah contoh.
Dalam file html:
Dalam file javascript, di controller misalnya, tempat Anda ingin mengaktifkan fokus:
sumber
Jika Anda hanya menginginkan fokus sederhana yang dikendalikan oleh ng-klik.
Html:
Pengarahan:
sumber
Sederhana yang bekerja dengan baik dengan modals:
Contoh
sumber
Anda bisa membuat arahan yang memaksa fokus pada elemen yang didekorasi pada postLinking:
Kemudian di html Anda:
Ini akan berfungsi untuk elemen-elemen yang di-modals dan ng-if, bukan untuk ng-show karena postLinking hanya terjadi pada pemrosesan HTML.
sumber
Mark dan Blesh memiliki jawaban yang luar biasa; Namun, Mark's memiliki kekurangan yang ditunjukkan oleh Blesh (selain rumit untuk diterapkan), dan saya merasa bahwa jawaban Blesh memiliki kesalahan semantik dalam menciptakan layanan yang secara khusus tentang mengirim permintaan fokus ke frontend ketika benar-benar semua yang ia butuhkan adalah cara untuk tunda acara sampai semua arahan mendengarkan.
Jadi di sini adalah apa yang akhirnya saya lakukan yang mencuri banyak dari jawaban Blesh tetapi menjaga semantik acara controller dan layanan "after load" terpisah.
Hal ini memungkinkan acara pengontrol dengan mudah dihubungkan untuk hal-hal selain dari hanya memfokuskan elemen tertentu dan juga memungkinkan untuk menimbulkan overhead fungsi "after load" hanya jika diperlukan, yang mungkin tidak dalam banyak kasus.
Pemakaian
Sumber
sumber
Ini juga memungkinkan untuk digunakan
ngModelController
. Bekerja dengan 1.6+ (tidak tahu dengan versi yang lebih lama).HTML
JS
-
NB: Tergantung dari konteksnya, Anda mungkin harus membungkus dengan fungsi timeout.
NB²: Saat menggunakan
controllerAs
, ini hampir sama. Cukup gantiname="myForm"
denganname="vm.myForm"
dan di JSvm.myForm.myText.$$element.focus();
,.sumber
Mungkin, solusi paling sederhana pada usia ES6.
Menambahkan arahan satu liner berikut membuat atribut 'autofokus' HTML efektif di Angular.js.
Sekarang, Anda bisa menggunakan sintaks autofokus HTML5 seperti:
sumber
.directive('autofocus', ['$timeout', ($timeout) => ({link: (_, e) => $timeout(() => e[0].focus())})])
Hanya seorang pemula di sini, tapi saya bisa membuatnya bekerja di ui.bootstrap.modal dengan arahan ini:
dan dalam metode $ modal.open saya menggunakan mengikuti untuk menunjukkan elemen di mana fokus harus diletakkan:
pada template saya punya ini:
sumber
Arahan berikut ini membantu saya. Gunakan atribut html autofokus yang sama untuk input.
sumber
Jika Anda menggunakan modalInstance dan memiliki objek, Anda dapat menggunakan "lalu" untuk melakukan tindakan setelah membuka modal. Jika Anda tidak menggunakan modalInstance, dan kode keras untuk membuka modal Anda dapat menggunakan acara tersebut. Batas waktu $ bukanlah solusi yang baik.
Anda dapat melakukannya (Bootstrap3):
Di modalInstance Anda dapat melihat perpustakaan bagaimana mengeksekusi kode setelah modal terbuka.
Jangan gunakan $ timeout seperti ini, $ timeout bisa 0, 1, 10, 30, 50, 200 atau lebih ini akan tergantung pada komputer klien, dan proses untuk membuka modal.
Jangan gunakan $ timeout, biarkan metode memberi tahu Anda kapan Anda bisa fokus;)
Saya harap ini membantu! :)
sumber
Semua jawaban sebelumnya tidak berfungsi jika elemen fokus yang diinginkan disuntikkan dalam template direktif. Direktif berikut cocok untuk elemen sederhana atau elemen yang disuntikkan direktif (saya menulisnya dalam naskah ). itu menerima pemilih untuk elemen fokus dalam. jika Anda hanya perlu memfokuskan elemen mandiri - jangan mengirim parameter pemilih ke arahan:
}
contoh penggunaan untuk elemen sederhana:
contoh penggunaan untuk elemen dalam (biasanya untuk elemen injeksi dinamis seperti direktif dengan template):
Anda dapat menggunakan pemilih jQuery apa saja alih-alih "input"
sumber
Saya mengedit arahan fokusMe Mark Rajcok agar berfungsi untuk beberapa fokus dalam satu elemen.
HTML:
di AngularJs Controller:
Petunjuk AngulaJS:
sumber
Saya ingin berkontribusi dalam diskusi ini setelah mencari solusi yang lebih baik dan tidak menemukannya, harus membuatnya.
Kriteria: 1. Solusi harus independen dari lingkup pengendali induk untuk meningkatkan kegunaan kembali. 2. Hindari penggunaan $ watch untuk memantau beberapa kondisi, ini lambat, meningkatkan ukuran loop digest dan membuat pengujian lebih sulit. 3. Hindari $ timeout atau $ scope. $ Apply () untuk memicu loop intisari. 4. Elemen input hadir dalam elemen di mana Directive digunakan terbuka.
Ini adalah solusi yang paling saya sukai:
Pengarahan:
Html:
Saya harap ini akan membantu seseorang di luar sana!
sumber
Mudah .. coba ini
html
javascript
sumber
Jika Anda ingin menetapkan fokus pada elemen tertentu, Anda dapat menggunakan pendekatan di bawah ini.
Buat layanan yang disebut
focus
.Masukkan ke dalam pengontrol dari tempat Anda ingin menelepon.
Panggil layanan ini.
sumber
Saya pikir arahan tidak perlu. Gunakan id HTML dan atribut kelas untuk memilih elemen yang diperlukan dan meminta layanan menggunakan document.getElementById atau document.querySelector untuk menerapkan fokus (atau setara dengan jQuery).
Markup adalah arahan HTML / sudut standar dengan id / kelas tambahan untuk seleksi
Pengendali siaran acara
Dalam layanan UI menggunakan querySelector - jika ada beberapa pertandingan (katakanlah karena kelas) itu hanya akan mengembalikan yang pertama
Anda mungkin ingin menggunakan $ timeout () untuk memaksakan siklus intisari
sumber
Hanya melempar kopi.
sumber